How to Prevent API Keys from Leaking into AI Prompts
API keys in prompts, retrieved documents, and chat history are a common leakage path. Learn detection, redaction, and architectural controls.
Preventing API keys from leaking into AI prompts requires scanning every text path that assembles model context—user messages, chat history, retrieved documents, tool outputs, and pasted code—for credential-shaped strings, blocking or stripping matches before the HTTP request leaves your infrastructure, and rotating any key that may have been exposed. API keys in prompts are especially dangerous because model providers, log aggregators, and annotation vendors may retain request bodies longer than you expect, turning a one-time paste into a durable secret exposure.
Why API keys end up in prompts
Developers and end users introduce keys into LLM context through predictable paths:
- Debugging — "Here's my failing curl command:
Authorization: Bearer sk-test_..." - Code paste — Source files containing
process.env.STRIPE_SECRET_KEYassignments with accidental literal values - Retrieved docs — Internal wikis with example configurations checked into Confluence
- Agent tool loops — A search tool returns a GitHub gist containing a
.envsnippet - Error messages — Stack traces echoing configured headers from outbound HTTP clients
LLMs do not "know" secrets are sensitive unless your pipeline enforces that boundary. The model may even suggest pasting a key to "help debug faster."
For broader leakage context, read LLM Data Leakage: Causes, Examples and Prevention. For all secret types—not just API keys—see Secrets Detection for LLM Applications.
Detection: what to scan for
IdenticAPI's PII & Secrets Detection flags patterns including:
| Pattern type | Synthetic example | Category |
|---|---|---|
| Stripe-style key | sk-test_abcdefghijklmnopqrstuvwxyz123456 | stripe_key |
| AWS access key | AKIA0000000000000000 | aws_access_key |
| GitHub PAT | ghp_abcdefghijklmnopqrstuvwxyz1234567890AB | github_token |
| OpenAI-style key | sk-abcdefghijklmnopqrstuvwwxT3BlbkFJabcdefghijklmnopqrst | openai_key |
| Bearer header | Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.test | bearer_token |
| Key-value pair | api_key=sk-test_notrealvalue1234567890 | credential_pair |
When any secret category matches, the API returns verdict: "unsafe" and risk: "high".
POST /api/v1/security/pii-secrets
{
"text": "Use key sk-test_abcdefghijklmnopqrstuvwxyz123456 for billing.",
"redact": false
}
Do not use real keys in tests. Use clearly synthetic prefixes like sk-test_ and documented test vectors.
Response handling policy
Recommended policy for secrets in user-facing LLM apps:
- Block the LLM request immediately when
verdictisunsafe - Show a clear user message: "Remove API keys and secrets before submitting"
- Log
request_id, timestamp, and categories—never the raw secret - Alert security if repeated attempts suggest deliberate exfiltration testing
- Rotate credentials if a production key may have reached a third-party log
Redaction alone is insufficient for secrets. Replacing a key with [API_KEY] still confirms a secret existed and does not undo transmission if the raw prompt already logged.
Architectural controls
Never embed keys in prompts
Load secrets from environment variables or a secrets manager at runtime. System prompts should reference capabilities, not credentials:
Bad: "Use Stripe key sk-test_abc123..."
Good: "Call the billing tool; credentials are injected server-side."
Server-side tool execution
When an agent needs an external API, your backend attaches keys to outbound requests. The model sees only tool results shaped to exclude secrets.
Pre-flight scanner in the request path
Incoming message → secrets scan → if unsafe: 400 + guidance
→ if safe/suspicious: continue to PII redaction → LLM
Place the scanner in your API route, not the browser, so keys cannot bypass client-side checks.
CI and repository scanning
Prevent keys from entering RAG corpora at the source. Git pre-commit hooks and CI secret scanners complement runtime LLM guards—they address different lifecycle stages.
Example: blocked request flow
User input (synthetic):
Why does this fail? curl -H "Authorization: Bearer ghp_abcdefghijklmnopqrstuvwxyz1234567890AB" ...
API scan result:
{
"verdict": "unsafe",
"findings": [
{
"category": "github_token",
"reason": "Detected github token (secret)",
"confidence": 0.95
}
]
}
Application response:
{
"error": "secrets_detected",
"message": "Remove tokens and API keys from your message before submitting."
}
No LLM call occurs. If this was a real token, open a rotation ticket regardless of block success.
Private keys and certificates
PEM private keys are high-severity findings:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7SyntheticExample
-----END PRIVATE KEY-----
Treat these like API keys: block, rotate, audit. Details in How to Detect Private Keys and Tokens in Text.
Developer workflow guardrails
- Add a "paste code" UI that runs local or server-side secret scan before send
- Strip
.envfiles from upload allowlists in document chat features - Train support staff not to ask customers for passwords or full card numbers in chat
- Review prompt templates in pull requests with the same rigor as application code
Use the PII Checker to validate detection on synthetic samples. Full API reference: docs.
Limitations
Pattern-based secret detection:
- Misses heavily obfuscated or encrypted secrets
- May match dummy values in documentation that look like real keys
- Cannot tell if a detected string is active, revoked, or a honeypot
- Does not replace vault-based secret storage discipline
Assume detection will be imperfect; combine scanning with least-privilege keys, short TTLs, and rapid rotation.
Related reading
- How to Detect Credentials in User Input
- PII and Secrets Leakage Checklist
- PII Detection in Node.js — wire scanning into your API layer
- Building a Privacy Filter Before Your LLM API Call
Frequently asked questions
Why do API keys end up in AI prompts?
Users and developers paste curl commands, configuration snippets, stack traces, and internal wiki content into chat interfaces while debugging. LLM UIs feel private, so credential paste is common.
What should happen when a secret is detected in user input?
Block the LLM request, show a message that does not echo the secret, log request_id and finding categories only, and rotate the credential if a production key may have been exposed.
Is redact true enough for API keys?
No. Secrets should trigger a block on unsafe verdicts. Redaction is appropriate for PII in many cases but not sufficient for credential exposure.
How do I keep keys out of system prompts?
Reference capabilities instead of credentials, load secrets from environment variables or a vault at runtime, and review prompt templates in pull requests the same way you review application code.
Which IdenticAPI categories indicate API keys?
Categories include stripe_key, aws_access_key, github_token, openai_key, google_api_key, slack_token, api_key, bearer_token, credential_pair, and private_key. All map to an unsafe verdict.
Related reading
- Secrets Detection for LLM Applications
Detect private keys, bearer tokens, cloud credentials, and high-entropy secrets in LLM inputs and outputs before they ca…
- How to Detect Private Keys and Tokens in Text
Identify private key blocks, bearer tokens, and cloud API key formats in text before they reach logs, models, or third-p…
- LLM Data Leakage: Causes, Examples and Prevention
LLM data leakage happens when sensitive information enters prompts, context, logs, or model output. Understand common ca…