Airtable: Redact PII in Record Reads
Scans the responses of the Airtable record-read tools — the calls that return row fields values — and rewrites high-confidence PII shapes to a fixed…
Scans the responses of the Airtable record-read tools — the calls that return row fields values — and rewrites high-confidence PII shapes to a fixed…
Airtable bases routinely hold CRM contacts, applicant-tracking pipelines, customer/financial trackers, and — on HIPAA-eligible Enterprise plans — health-ops…
An Airtable OAuth grant (or Personal Access Token) with the workspacesAndBases:read scope spans the entire workspace — every base the connected identity can…
Maintains a per-tenant allowlist of audited Airtable tool-name suffixes and denies any call whose tool name does not end with an allowlisted entry.
Denies every destructive Airtable tool call unless the caller's IdP token carries the placeholder group airtable-admins.
Reusable DTwo policies for Airtable MCP servers — the official remote server that the Claude connector fronts (https://mcp.airtable.com/mcp, OAuth 2.0), plus the dominant community/local implementations (domdomegg/airtable-mcp-server, rashidazarang/airtable-mcp). The MCP surface is read/discovery tools (list and search records, schema and base discovery, interface pages), data-write tools (create/update records, attachment upload), schema/structure tools (create base/table/field, create/publish interface), and — on the community domdomegg server — a batch delete_records. Its risk profile is dominated by bulk PII egress and irreversible writes: a single list_records or search_records call can drain an entire table of CRM contacts, applicant-tracking rows, or (on HIPAA-eligible Enterprise) health-ops data, and filterByFormula enables targeted extraction. The official remote server has no record- or table-delete tool, but the community servers do, and update_records overwrites are the effective destructive path everywhere. Tool naming diverges sharply between servers (verbose *_for_table suffixes on the official server, terse create_record/delete_records on community ones), so these policies match on the suffix to stay portable across both spellings.
| Policy | Direction | Purpose | Framework bundles |
|---|---|---|---|
| default-deny-unknown-tools | ingress | Allowlist audited Airtable tool names; deny (and alert on) any unrecognized, renamed, or newly-added upstream tool. | soc2, gdpr-ccpa |
| fence-base-allowlist | ingress | Deny record calls whose baseId argument is not in the approved allowlist, confining the agent to sanctioned bases even when the OAuth grant spans the workspace. |
soc2, hipaa, pci-dss, gdpr-ccpa |
| freeze-record-deletion | ingress | Deny destructive record/page delete tools so records survive agent error or prompt injection; points users to the web UI for deletions. | soc2, hipaa, gdpr-ccpa, sox |
| cap-bulk-record-reads | ingress | Clamp maxRecords down to ≤50 on bulk record-list tools (injecting it when absent or invalid) and strip filterByFormula for callers outside the analyst group. |
soc2, hipaa, gdpr-ccpa |
| redact-pii-egress | egress | Redact SSN, email, and phone patterns from record-read responses for callers outside a data-privileged group. | soc2, hipaa, gdpr-ccpa |
DTwo prefixes tool names with the MCP server name configured on the gateway, so a server registered as airtable surfaces tools like airtable-list_records_for_table or airtable-delete_records. Airtable's servers also diverge on the tool names themselves: the official remote server uses verbose suffixed names (list_records_for_table, create_records_for_table, update_records_for_table), while domdomegg uses terse ones (list_records, create_record, delete_records). The policies here match on the suffix (e.g. *record*, *delete*) so they cover both spellings, but you should confirm the exact tool names your gateway sends with the dump-input debug technique before deploying. The rashidazarang/airtable-mcp server (42 advertised tools, including webhook management) has unverified individual tool names — treat any per-tool policy against it as requiring live introspection first, as noted in each policy's Known limitations.
The identity-gated policies (cap-bulk-record-reads formula-strip exemption, redact-pii-egress) read input.subject.claims.groups with placeholder group names (e.g. analyst, data-privileged). Replace these with your own IdP group names at import time. Missing claims fail closed for grants (no group → not exempt / redaction still applies).
To add an Airtable policy:
apps/airtable/<policy-slug>/ with policy.md and a tests.yaml test file.apps: ["airtable"] in the policy frontmatter, plus any industry / bundle slugs that apply.pnpm manifest from the repo root.See CONTRIBUTING.md for the full process.