Skip to main content
clay-policy-guardrails Implement credit spending limits, data privacy enforcement, and input validation guardrails for Clay pipelines.
Use when enforcing spending caps, blocking PII enrichment,
or adding pre-enrichment validation rules.
Trigger with phrases like "clay policy", "clay guardrails", "clay spending limit",
"clay data privacy rules", "clay validation", "clay controls".
Aller à l'installation Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill clay-policy-guardrailsLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Plus depuis ce dépôt Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
Métiers associés SOC
Basé sur la classification professionnelle SOC
name clay-policy-guardrails description Implement credit spending limits, data privacy enforcement, and input validation guardrails for Clay pipelines.
Use when enforcing spending caps, blocking PII enrichment,
or adding pre-enrichment validation rules.
Trigger with phrases like "clay policy", "clay guardrails", "clay spending limit",
"clay data privacy rules", "clay validation", "clay controls".
allowed-tools Read, Write, Edit, Bash(node:*) version 1.14.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","clay","clay-policy"] compatibility Designed for Claude Code, also compatible with Codex and OpenClaw
Clay Policy Guardrails
Overview
Policy enforcement and guardrails for Clay data enrichment pipelines. Clay processes personal and business data at scale, requiring strict controls around credit spending, data privacy compliance, input validation, and export restrictions.
Prerequisites
Clay integration in production or pre-production
Understanding of GDPR/CCPA requirements
Credit budget defined by management
Data classification policy for your organization
Instructions
Step 1: Credit Spending Guardrails
interface CreditPolicy {
dailyLimit : number ;
perTableLimit : number ;
perBatchLimit : number ;
alertThresholdPct : number ;
hardStopEnabled : boolean ;
}
const CREDIT_POLICIES : Record <string , CreditPolicy > = {
conservative : {
dailyLimit : 200 ,
perTableLimit : 500 ,
perBatchLimit : 100 ,
alertThresholdPct : 70 ,
hardStopEnabled : true ,
},
standard : {
dailyLimit : 500 ,
perTableLimit : 2000 ,
perBatchLimit : 500 ,
alertThresholdPct : 80 ,
hardStopEnabled : true ,
},
: {
: ,
: ,
: ,
: ,
: ,
},
};
{
dailyUsed = ;
tableUsage = < , >();
( ) {}
( : , : , : ): {
: ;
?: ;
} {
estimated = rowCount * creditsPerRow;
(estimated > . . ) {
{
: ,
: ,
};
}
( . + estimated > . . ) {
( . . ) {
{
: ,
: ,
};
}
. ( );
}
tableTotal = ( . . (tableId) || ) + estimated;
(tableTotal > . . ) {
{
: ,
: ,
};
}
dailyPct = (( . + estimated) / . . ) * ;
(dailyPct > . . ) {
. ( );
}
{ : };
}
( ) {
. += credits;
. . (tableId, ( . . (tableId) || ) + credits);
}
}
aggressive
dailyLimit
2000
perTableLimit
10000
perBatchLimit
2000
alertThresholdPct
90
hardStopEnabled
false
class
CreditPolicyEnforcer
private
0
private
new
Map
string
number
constructor
private policy : CreditPolicy
checkBatch
tableId
string
rowCount
number
creditsPerRow
number
allowed
boolean
reason
string
const
if
this
policy
perBatchLimit
return
allowed
false
reason
`Batch (${estimated} credits) exceeds per-batch limit (${this .policy.perBatchLimit} ). Split into smaller batches.`
if
this
dailyUsed
this
policy
dailyLimit
if
this
policy
hardStopEnabled
return
allowed
false
reason
`Would exceed daily limit: ${this .dailyUsed} + ${estimated} > ${this .policy.dailyLimit} `
console
warn
`WARNING: Exceeding daily limit (${this .dailyUsed + estimated} /${this .policy.dailyLimit} )`
const
this
tableUsage
get
0
if
this
policy
perTableLimit
return
allowed
false
reason
`Table ${tableId} would exceed limit: ${tableTotal} > ${this .policy.perTableLimit} `
const
this
dailyUsed
this
policy
dailyLimit
100
if
this
policy
alertThresholdPct
console
warn
`Credit alert: ${dailyPct.toFixed(0 )} % of daily limit used`
return
allowed
true
recordUsage
tableId : string , credits : number
this
dailyUsed
this
tableUsage
set
this
tableUsage
get
0
Step 2: Data Privacy Guardrails
const BLOCKED_ENRICHMENT_FIELDS = new Set ([
'ssn' , 'social_security' , 'tax_id' ,
'date_of_birth' , 'dob' , 'birthday' ,
'home_address' , 'home_phone' ,
'personal_phone' , 'personal_mobile' ,
'bank_account' , 'credit_card' ,
'medical_history' , 'health_records' ,
'salary' , 'compensation' ,
'political_affiliation' , 'religion' ,
'ethnic_origin' , 'sexual_orientation' ,
]);
const CONSENT_REQUIRED_FIELDS = new Set ([
'personal_email' , 'phone_number' , 'mobile_phone' ,
]);
interface PrivacyCheckResult {
allowed : boolean ;
violations : string [];
warnings : string [];
}
function checkPrivacy (
fieldsToEnrich : string [],
hasExplicitConsent : boolean = false ,
): PrivacyCheckResult {
const violations : string [] = [];
const warnings : string [] = [];
for (const field of fieldsToEnrich) {
const normalized = field.toLowerCase ().replace (/[\s-]/g , '_' );
if (BLOCKED_ENRICHMENT_FIELDS .has (normalized)) {
violations.push (`BLOCKED: "${field} " is a restricted field (never enrich)` );
}
if (CONSENT_REQUIRED_FIELDS .has (normalized) && !hasExplicitConsent) {
warnings.push (`CONSENT: "${field} " requires explicit consent to enrich` );
}
}
return {
allowed : violations.length === 0 ,
violations,
warnings,
};
}
Step 3: Input Validation Guardrails
const PERSONAL_EMAIL_DOMAINS = new Set ([
'gmail.com' , 'yahoo.com' , 'hotmail.com' , 'outlook.com' , 'icloud.com' ,
'aol.com' , 'protonmail.com' , 'mail.com' , 'yandex.com' , 'gmx.com' ,
]);
const DISPOSABLE_EMAIL_DOMAINS = new Set ([
'tempmail.com' , 'guerrillamail.com' , 'throwaway.email' , 'yopmail.com' ,
'mailinator.com' , '10minutemail.com' , 'trashmail.com' ,
]);
interface ValidationResult {
valid : Record <string , unknown >[];
rejected : { row : Record <string , unknown >; reason : string }[];
stats : {
total : number ;
valid : number ;
invalidDomain : number ;
personalDomain : number ;
disposableDomain : number ;
missingRequiredField : number ;
duplicates : number ;
};
}
function validateBatch (
rows : Record <string , unknown >[],
requiredFields : string [] = ['domain' ],
): ValidationResult {
const seen = new Set <string >();
const stats = {
total : rows.length , valid : 0 , invalidDomain : 0 ,
personalDomain : 0 , disposableDomain : 0 , missingRequiredField : 0 , duplicates : 0 ,
};
const valid : Record <string , unknown >[] = [];
const rejected : { row : Record <string , unknown >; reason : string }[] = [];
for (const row of rows) {
const missing = requiredFields.filter (f => !row[f]);
if (missing.length > 0 ) {
rejected.push ({ row, reason : `Missing required: ${missing.join(', ' )} ` });
stats.missingRequiredField ++;
continue ;
}
const domain = String (row.domain || '' ).toLowerCase ().trim ();
if (!domain.includes ('.' ) || domain.length < 4 ) {
rejected.push ({ row, reason : `Invalid domain: "${domain} "` });
stats.invalidDomain ++;
continue ;
}
if (PERSONAL_EMAIL_DOMAINS .has (domain)) {
rejected.push ({ row, reason : `Personal email domain: ${domain} ` });
stats.personalDomain ++;
continue ;
}
if (DISPOSABLE_EMAIL_DOMAINS .has (domain)) {
rejected.push ({ row, reason : `Disposable email domain: ${domain} ` });
stats.disposableDomain ++;
continue ;
}
const key = `${domain} :${String (row.first_name || '' ).toLowerCase()} :${String (row.last_name || '' ).toLowerCase()} ` ;
if (seen.has (key)) {
stats.duplicates ++;
continue ;
}
seen.add (key);
valid.push ({ ...row, domain });
stats.valid ++;
}
return { valid, rejected, stats };
}
Step 4: Export Restrictions
type ExportDestination = 'crm' | 'outreach' | 'analytics' | 'csv' ;
const EXPORT_RULES : Record <ExportDestination , {
allowedFields : string [];
blockedFields : string [];
requiresApproval : boolean ;
}> = {
crm : {
allowedFields : ['email' , 'first_name' , 'last_name' , 'company_name' , 'job_title' , 'icp_score' ],
blockedFields : ['personal_email' , 'home_address' ],
requiresApproval : false ,
},
outreach : {
allowedFields : ['email' , 'first_name' , 'company_name' , 'personalized_opener' ],
blockedFields : ['phone_number' , 'linkedin_url' , 'personal_email' ],
requiresApproval : false ,
},
analytics : {
allowedFields : ['company_name' , 'industry' , 'employee_count' , 'icp_score' ],
blockedFields : ['email' , 'first_name' , 'last_name' , 'phone_number' ],
requiresApproval : false ,
},
csv : {
allowedFields : ['*' ],
blockedFields : ['personal_email' , 'home_address' , 'ssn' ],
requiresApproval : true ,
},
};
function filterForExport (
rows : Record <string , unknown >[],
destination : ExportDestination ,
): Record <string , unknown >[] {
const rules = EXPORT_RULES [destination];
return rows.map (row => {
const filtered : Record <string , unknown > = {};
for (const [key, value] of Object .entries (row)) {
if (rules.blockedFields .includes (key)) continue ;
if (rules.allowedFields [0 ] !== '*' && !rules.allowedFields .includes (key)) continue ;
filtered[key] = value;
}
return filtered;
});
}
Error Handling Issue Cause Solution Credit overrun No spending limits enforced Implement credit policy enforcer PII enrichment violation No privacy checks Add blocked field validation Wasted credits on bad data No input validation Pre-validate all batches Unauthorized data export No export restrictions Implement per-destination field filtering
Resources
Next Steps For architecture patterns at scale, see clay-architecture-variants.