Read the diff, not the summary
Before approving a file edit, read the actual diff, not the agent’s one-line description of it. The summary is what the agent intended; the diff is what it will write.
Data privacy for AI-assisted development rests on a four-tier classification — public, internal, confidential, restricted — that says what may reach a model provider, enforced by each tool’s retention setting, pre-flight secret scanning, synthetic data instead of production copies, least-privilege MCP credentials, and environment isolation that keeps agents off production entirely.
A developer on your team pastes a database query result into their AI tool to debug a performance issue. The result contains customer email addresses, billing addresses, and partial card numbers, and the provider’s logs now hold PII from your production database. Three lines into another session, someone has pasted a full DATABASE_URL — host, user, and password — to ask why prod keeps timing out. A third person is about to point a community MCP server at production with admin credentials.
Every one of those moves feels harmless in the moment, and every one of them is the scenario that kills enterprise AI adoption before it starts. AI assistants are safe on proprietary code if you configure them deliberately: classify what can leave, turn on the right retention setting, never let a secret reach the model, and give every MCP server the least privilege it needs.
GRANTNot all data carries the same risk when sent to AI tools. Classify it once, and every later decision — which files to ignore, which prompts to block, which database the agent may touch — follows from the tier.
| Tier | Description | AI Tool Policy | Examples |
|---|---|---|---|
| Public | Open-source code, public docs | Unrestricted | OSS libraries, public APIs, documentation |
| Internal | Proprietary code, internal docs | Allowed with privacy mode | Business logic, internal tools, architecture docs |
| Confidential | Trade secrets, unreleased features | Allowed with strict controls | Algorithms, competitive features, pricing logic |
| Restricted | PII, credentials, financial data | Never send to AI tools | Customer data, API keys, payment info, health records |
The Internal tier is doing quiet work in that table: it is allowed with privacy mode, which means the tier system only holds if you know what your tool’s privacy mode actually guarantees.
“Privacy Mode” is not universal — each vendor has its own control and its own guarantee. Know which one applies to you before you paste a single proprietary line.
Cursor has an explicit Privacy Mode toggle (Cursor Settings). With it on, your code is not stored by Cursor and not used for training — a zero-data-retention (ZDR) guarantee. Privacy Mode is on by default for Enterprise teams, and admins can enforce it team-wide so individuals cannot turn it off. Indexing still computes embeddings, but under Privacy Mode plaintext code is not retained server-side after the request.
For commercial usage — Team, Enterprise, and API — Anthropic does not train models on your code or prompts by default. Free, Pro, and Max accounts may be used for training only if you opt in, and are consumer plans governed by the consumer terms rather than the right tier for enterprise data handling. Default retention is 30 days; zero data retention is available with appropriately configured API keys, meaning transcripts are not retained server-side. If you are on a personal plan for work, check the data-usage setting and move to commercial terms for proprietary code.
Codex inherits ChatGPT Enterprise guarantees: no training on enterprise data, and zero data retention for the CLI and IDE, with residency and retention following your ChatGPT Enterprise policies. On personal ChatGPT plans, review your data controls (chat history and “improve the model” settings) before using Codex on a private repo.
A classification nobody can see is a classification nobody applies. Each tool has a file that gets loaded before the agent does anything, and a mechanism that enforces the hard edges rather than suggesting them.
Use .cursor/rules to state the data-handling policy:
DATA HANDLING POLICY:Privacy Mode MUST be enabled at all times (Settings → Privacy).
NEVER include in prompts or context:- Contents of .env, .env.*, or any secrets files- Customer data, even for debugging (use anonymized samples)- Production database query results- API keys, tokens, certificates, or private keys- Internal URLs that contain authentication tokens
ALWAYS use instead:- .env.example with placeholder values- Faker.js-generated test data that matches production schemas- Redacted log entries: replace emails with user_XXX@example.com- Mock credentials: sk_test_XXXXXXXXXXXXRules are guidance. The enforcement is .cursorignore, which keeps the files out of the index entirely:
.env***/secrets/****/credentials/****/*.pem**/*.keyconfig/production.*database/seeds/production/**Claude Code respects .gitignore and lets you exclude sensitive files with Read(...) deny rules in .claude/settings.json. Deny rules are evaluated first and the file is never read into context:
{ "permissions": { "deny": [ "Read(./.env)", "Read(./.env.*)", "Read(./secrets/**)", "Read(./credentials/**)", "Read(./**/*.pem)", "Read(./**/*.key)", "Read(./config/production.*)" ] }}Deny rules cover files. For everything a developer types, add a UserPromptSubmit hook that scans each prompt before it is sent:
{ "hooks": { "UserPromptSubmit": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node scripts/privacy-check.js" }] }] }}The hook script reads the event JSON from stdin and scans for patterns like email addresses, credit card numbers, and API key formats, blocking the prompt (exit code 2) before the request leaves the developer’s machine. The next section has the prompt that writes that script.
Codex cloud tasks run in sandboxed environments. Encode privacy controls in AGENTS.md, the file Codex reads before every task:
PRIVACY CONTROLS:- Do not read .env or any secrets files- When debugging with sample data, generate synthetic data using Faker- All database connection strings must use environment variable references- Never output actual credentials, tokens, or PII in generated code or comments- If production data is needed for context, describe the schema shape insteadCodex’s network sandbox prevents production database connections from cloud task environments by default, which makes the sandbox the enforcement layer and AGENTS.md the guidance layer.
The rule is unchanged from ordinary security hygiene, but the surface is wider: API keys, tokens, passwords, and database connection strings must never appear in a prompt. Reference process.env.DATABASE_URL, not the literal value. The most reliable enforcement is automation, not willpower — wire gitleaks into a pre-commit hook so a leaked credential is caught before it is ever committed or pasted.
Two prompts cover the two moments. The first is the per-diff check a human runs before committing; the second builds the scanner your UserPromptSubmit hook calls on every single interaction, which is why it has to be fast and pattern-driven rather than a model call.
When developers need production-like data for debugging, the answer is not a redacted export — it is synthetic data that matches the schema and the edge cases. Teach the agent to generate it from the shape of the table rather than its contents.
Anonymization only holds if production data is not sitting in the environment the agent can reach in the first place.
Development environments never contain production data
Use synthetic data generation or anonymized production snapshots. Never copy production databases to development.
AI tools connect to development and staging only
Database MCP servers, if used, connect only to development databases. Production database access requires separate tooling with full audit trails.
CI/CD pipelines use service accounts
AI-assisted CI workflows (headless Claude Code, Codex automation) use service accounts with minimal permissions, not developer credentials.
Regular access reviews
Monthly review of what data AI tools can access. Remove unnecessary access proactively.
The Model Context Protocol lets your agent connect to external tools — a database, GitHub, a browser. Every MCP server is executable software with whatever permissions you hand it, so an over-privileged or unvetted server is a real attack surface. Two rules cover most of the risk.
First, vet the server before you install it. Prefer official, scoped packages (for example @modelcontextprotocol/server-github, @modelcontextprotocol/server-postgres) over an unknown community fork. Have the agent summarize what a server actually does before you wire it up:
Second, connect it with least-privilege credentials. For a Postgres MCP server, never hand it your app or admin role. Create a read-only role scoped to exactly what the agent needs:
CREATE ROLE ai_readonly LOGIN PASSWORD 'rotate-me';GRANT CONNECT ON DATABASE app TO ai_readonly;GRANT USAGE ON SCHEMA public TO ai_readonly;GRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_readonly;-- new tables inherit read-only access automaticallyALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ai_readonly;Then point the MCP server’s connection string at ai_readonly — identical config across Cursor, Claude Code, and Codex, since all three read the same mcpServers block. Now a hallucinated DROP TABLE is rejected by the database, not by hope. See Database MCP for full setup and MCP Security for the threat model.
Treat every block the agent writes as a pull request from a brand-new contributor: it may be functionally correct and still ship an injection bug or a missing authorization check. Do not skim the diff — make a second pass with the model wearing a security hat, then verify the findings yourself.
Read the diff, not the summary
Before approving a file edit, read the actual diff, not the agent’s one-line description of it. The summary is what the agent intended; the diff is what it will write.
Gate destructive commands
Never auto-approve terminal commands that delete, deploy, or mutate data. Run agents in a restricted mode (Cursor’s per-action approval, Claude Code’s permission prompts, or Codex with an explicit sandbox and approval_policy=on-request). In Codex, the sandbox enforces access boundaries while the approval policy separately controls escalation prompts.
This is the human-in-the-loop discipline that separates production work from demos — see Human in the Loop for the full review workflow.
If your organization processes data from EU residents, your AI tool usage must comply with GDPR:
Privacy controls only work if developers understand and follow them. A short, memorable card beats a policy document nobody opens.
Then keep it honest with a quarterly review that verifies four things: tool configuration (privacy modes enabled, ignore files current), usage patterns (prompts containing suspicious patterns such as email addresses or key formats), vendor compliance (DPAs current, retention policies unchanged), and training freshness (new developers onboarded to the policy within their first week).
args — load them from the environment.UPDATE because the role you gave the MCP server could write. The read-only GRANT above is the fix; create a separate, deliberately-invoked write role only when you actually need mutations..env or key file got embedded because it was not ignored. Add it to .cursorignore and .gitignore, then rotate any credential that was indexed — an embedded secret is a leaked secret.