What Happens When You Send Code to an AI
When you paste code into Claude, Copilot, or Cursor, here is what actually happens:
- -Your code leaves your machine as an HTTPS request to an external API
- -The API processes it on infrastructure outside your control
- -The provider stores the interaction per their data retention policy
- -The response is returned and the session ends
In most cases this is completely fine. For a lot of code it is even desirable: LLM providers need data to improve their models, and if you are working on a hobby project, that tradeoff is reasonable.
The problem arises when the code you are pasting contains things that belong inside your network.
What Is Actually at Risk
API Keys and Credentials
The most obvious risk. If your code has a hardcoded API key, even in a comment, even in a .env file you opened in the same context window, that key can appear in a prompt.
# Bad: This entire file context could be sent
STRIPE_SECRET_KEY = "<your-live-stripe-key>" # production key
DB_CONNECTION_STRING = os.environ["DB_CONNECTION_STRING"] # never hardcode connection strings
def charge_customer(amount: float) -> dict:
# developer asks: "why isn't this working?"
...
AI providers' systems are secure, but you are still transmitting a live production key to a third party. The key appears in request logs. It could be retained for model training. It creates audit trail issues for SOC 2 and similar frameworks.
Proprietary Business Logic
Less obvious but often more damaging. Your pricing algorithm, fraud detection logic, recommendation engine, or risk scoring model represents years of investment. Sending it to an external AI means it leaves your network.
// This function represents real business IP
function calculateRiskScore(
user: User,
transaction: Transaction,
historicalPatterns: Pattern[]
): number {
// proprietary algorithm
const behaviorScore = analyzeUserBehavior(user, historicalPatterns);
const velocityRisk = checkTransactionVelocity(transaction);
const networkRisk = assessNetworkGraph(user);
return weightedRisk(behaviorScore, velocityRisk, networkRisk);
}
The function name, the parameter structure, the sub-function names: these are all identifiers that describe your system architecture to anyone who sees the prompt.
PII in Test Data
Developers often work with real production data in test environments "just to check something." Real names, email addresses, SSNs, and account numbers end up in AI prompts regularly. This is a HIPAA and GDPR liability on top of a security concern.
Three Rules Before Using AI on Production Code
Rule 1: Keep active credentials out of every paste
Use placeholder values or environment variable references when asking AI for help with code that accesses secrets.
# Instead of showing this:
api_key = "<your-live-stripe-key>"
# Show this:
api_key = os.environ["STRIPE_API_KEY"] # or "STRIPE_KEY_HERE"
Rule 2: Sanitize proprietary identifiers in sensitive contexts
Before sending code that contains business-critical function or class names, consider whether the names themselves reveal your architecture. In high-stakes cases, rename to generics before pasting.
# Original:
fraud_detection_score = calculate_meridian_risk_score(transaction)
# Sanitized for AI question:
result_score = calculate_score(transaction)
Rule 3: Use a local proxy for ongoing work
For teams doing significant AI-assisted development, a proxy like Pretense handles this automatically. You keep your workflow, and the proxy swaps sensitive identifiers and secrets for stand-ins before they leave your network. Identifiers come back byte-exact in the answer; secrets stay as stand-ins by design.
# One-time setup
curl -fsSL https://pretense.ai/install.sh | sh
pretense init
pretense start
# Set in your shell profile
export ANTHROPIC_BASE_URL=http://localhost:9339
export OPENAI_BASE_URL=http://localhost:9339/openai
After that, your normal workflow routes through the proxy and behaves exactly as before.
What Providers Actually Do With Your Data
Anthropic (Claude): API usage is excluded from training by default. You can opt into training data contribution. Data is retained per their privacy policy. Holds a SOC 2 Type II report.
OpenAI (GPT/Copilot): API usage data is excluded from training by default. Copilot Individual uses prompts for product improvement; Copilot Business and Enterprise keep prompts out of it. Holds a SOC 2 Type II report.
Google (Gemini): API usage data retention varies by product and plan. Check the specific product's data processing terms.
The word "default" matters here. In all cases, the safe path is to send only data you can afford to share, regardless of provider policy.
The Practical Test
Before sending any code block to an AI, ask: "Would I be comfortable if a smart competitor could read this?"
If the answer is uncertain, either sanitize it manually using the rules above, or use a proxy that handles it automatically.
How I run Pretense on my own code
I build Pretense with Claude Code, and my sessions run through it. Here is the setup I give a new engineer, in order.
- -Run the agent through the proxy. Type
pretense run claudewhere you would typeclaude. It starts a local proxy on port 9339, points Claude Code at it and stops the proxy when the session ends. Detected secrets and PII leave the laptop as stand-in tokens. - -Put hooks on every repo.
pretense installadds a pre-commit and a pre-push hook. A key that never lands in git is a key an agent never reads. - -Scan before an agent reads the repo.
pretense scan path .lists what it finds. In CI,pretense scan ciexits 0 when clean, 2 on findings and 3 when it examined nothing. Treat 3 as a failure. - -Preview the swap.
pretense review .shows what would be mutated.pretense mutate <file> --previewprints one file mutated and leaves the file on disk as it was. - -Round-trip a file you need to share.
pretense mutate <file> --map <map>swaps the secrets in place.pretense reverse <file> --map <map>turns it back into the original, byte for byte, from the encrypted map on your machine. We run that round trip on real files before every CLI release and compare sha256 hashes.
One thing I learned the hard way: inside a session the agent sees stand-ins, so a file the agent writes can hold a stand-in where you expected a real value. Grep what the agent wrote before you ship it.
What Pretense will not do is put a secret back into the model's answer. Code identifiers come back byte-exact. Secrets and PII stay as stand-ins in the response. That is deliberate: a prompt-injected model can echo a token into a link, and reversing it there would hand over the real key.
What this means if you lead an engineering team
The outcome: your team keeps asking AI assistants about real systems, configs and connection strings, and detected secrets leave each laptop as stand-ins.
- -No new workflow. Engineers type
pretense run claudein place ofclaude. Other AI CLIs run the same way, for examplepretense run gemini. - -Guard the repo as well as the prompt.
pretense installadds pre-commit and pre-push hooks.pretense scan ciin the pipeline fails on findings (exit 2) and on an empty scan (exit 3). - -Answers stay usable. Identifiers inside fenced code blocks go out as stand-ins and come back byte-exact, so the code the model writes still uses your names.
- -Measure before you mandate. Run it on your own repo for a week.
pretense auditshows what it swapped and when.
Try it on your own repo: create a free account, then run npm i -g @pretense/cli and pretense run claude. If you need a security review first, talk to me.