Clay Subroutine Allowlist
Lets the agent run Clay's built-in enrichment functions (Work Email, Person Job Title, Enrich Company, Tech Stack and the rest) and blocks every other Clay…
On this page
What it does
Lets the agent run Clay's built-in enrichment functions (Work Email, Person Job Title, Enrich Company, Tech Stack and the rest) and blocks every other Clay function.
Clay's run-subroutine tools run any function in the workspace, not just
enrichment. A workspace can hold custom functions that push data out — add
contacts to a Salesforce campaign, update a HubSpot record, send a webhook.
Those writes come from Clay, so the CRM policies on the gateway never see
them. This policy closes that path: only functions on the allowlist run.
- Search and data-point tools pass.
search-*,query-objects,add-company-data-points,add-contact-data-points,get-task*and the rest are untouched. - Subroutine calls are checked.
run-subroutine,run-subroutine-directandrun-subroutine-no-mappingare allowed only whensubroutine_idis on the allowlist. A missing or unknown ID is denied.
Compliance alignment
- SOC 2 CC6.1; CC6.3 — least privilege: the agent gets enrichment, not arbitrary workspace automation.
- SOC 2 CC8.1 — change management: CRM changes can't be made through a side channel that bypasses the CRM's own controls.
- ISO 27001 A.5.15 — access control: enforces which Clay functions the agent channel can invoke.
Why ingress
A custom function's side effects (CRM writes, outbound webhooks) happen
inside Clay once it runs. The function is fully identified by
subroutine_id in the request, so denying at ingress stops it before it
starts.
How it matches
A tool is in scope when its (lowercased) name starts with clay and
contains run-subroutine or run_subroutine. For those calls,
payload.args.subroutine_id must be one of the IDs in _allowed_ids.
The default list holds the 19 built-in enrichment functions as Clay
returned them from list-subroutines on 2026-10-03: Company Industry,
Company Domain, Company Address, Company Employee Count, Company Latest
Funding, Company News, Company Revenue (Exact), Enrich Company, Company Job
Openings, Person Full Name, Enrich Person, Find People at Company, Mobile
Phone Number, Enrich Person and Find Contact Details, Person Location,
Website Traffic, Website Technology Stack, Person Job Title, Work Email.
Check the IDs against your workspace before deploying. Call
list-subroutines through the gateway and compare. If your IDs differ,
replace the list; until you do, the policy fails closed and blocks those
functions with a clear reason, rather than letting anything through.
Examples
Allowed (Work Email on given inputs)
{
"input": {
"action": "tool_pre_invoke",
"resource": { "name": "clay-run-subroutine-direct", "type": "tool" },
"payload": {
"args": {
"subroutine_id": "t_0tm6n9mtip5BqhnMv5d",
"inputs": [ { "Full Name": "Jane Doe", "Company Domain": "acme.com" } ]
}
}
}
}
allow = true, no reason.
Denied (custom function)
{
"input": {
"action": "tool_pre_invoke",
"resource": { "name": "clay-run-subroutine", "type": "tool" },
"payload": {
"args": {
"subroutine_id": "t_custom_push_to_sfdc",
"taskId": "mcp-task-123",
"inputs": { "Salesforce Campaign ID": "7018b00000ABCDEF" }
}
}
}
}
allow = false, reason = "Blocked: only Clay's built-in enrichment functions can run through this gateway. Custom Clay functions can push data into other systems, so ask your admin to add this one to the allowlist if you need it.".
Composition
Pairs with the CRM write posture in the same bundle. The CRM policies control what the agent can change in Salesforce or HubSpot directly; this one stops the agent from changing it indirectly through Clay. Volume and credit spend are a separate concern — cap them with a separate policy.
Known limitations
- IDs are workspace data. The default list comes from one Clay
workspace. Confirm yours with
list-subroutines. - Contact details are allowed. Mobile Phone Number, Work Email and Enrich Person and Find Contact Details return personal contact data. Remove their IDs if the agent shouldn't fetch them, or mask the values with an egress redaction policy.
- Prefix scope. Only tools whose name starts with
clayare in scope. Change the prefix if your gateway registers the server under another name. - No identity-based exemptions. To let RevOps admins run custom
functions, add an exception gated on
input.subject.claims.
Compliance note. This policy supports alignment with the cited framework controls on the MCP path only. No policy or bundle makes an organization compliant with any framework; web-UI, native-API, and in-app access are outside the gateway's reach by design. Validate against your own compliance program before relying on it.
Policy source (Rego)
package clay.ingress.subroutine_allowlist
import future.keywords.if
import future.keywords.in
# Allow broadly; deny only Clay subroutine runs that aren't on the list.
default allow := true
# Clay's built-in enrichment functions. Confirm against `list-subroutines`
# in your workspace and replace if the IDs differ.
_allowed_ids := {
"t_0tm6n9dEsVBMcS7oBvc", # Company Industry
"t_0tm6n9dFNTJjpVjZaYT", # Company Domain
"t_0tm6n9dG96YSDVGRXfM", # Company Address
"t_0tm6n9dVqh5MuXB9EXk", # Company Employee Count
"t_0tm6n9hMMAfCCgSJwgV", # Company Latest Funding
"t_0tm6n9hpQ5EmoAreRds", # Company News
"t_0tm6n9hWiPpnUCkZMax", # Company Revenue (Exact)
"t_0tm6n9hxVZpR4Cy6eYh", # Enrich Company
"t_0tm6n9hirHaxjjwgksd", # Company Job Openings
"t_0tm6n9iAu7KzcRycseU", # Person Full Name
"t_0tm6n9i5AtDR7HatCyJ", # Enrich Person
"t_0tm6n9iWQEKDYvceygd", # Find People at Company
"t_0tm6n9imvUTzmEhq997", # Mobile Phone Number
"t_0tm6n9ifsSooEgeeMCh", # Enrich Person and Find Contact Details
"t_0tm6n9miExJo3rhcgMf", # Person Location
"t_0tm6n9mo9Xk2gRm8r6W", # Website Traffic
"t_0tm6n9mKSfSitNJRCbw", # Website Technology Stack
"t_0tm6n9mkCFSdffP4HwB", # Person Job Title
"t_0tm6n9mtip5BqhnMv5d", # Work Email
}
_tool := lower(input.resource.name)
_is_subroutine_call if {
startswith(_tool, "clay")
regex.match(`run[-_]subroutine`, _tool)
}
_subroutine_id := object.get(object.get(input.payload, "args", {}), "subroutine_id", "")
_is_allowed_subroutine if {
is_string(_subroutine_id)
_subroutine_id in _allowed_ids
}
allow := false if {
_is_subroutine_call
not _is_allowed_subroutine
}
reason := "Blocked: only Clay's built-in enrichment functions can run through this gateway. Custom Clay functions can push data into other systems, so ask your admin to add this one to the allowlist if you need it." if {
_is_subroutine_call
not _is_allowed_subroutine
} Canonical source: policy.md on GitHub · raw · raw on this site (.md)