An AI agent's API token is a skeleton key. It grants write access to your AI provider account, billing, and potentially every tool the agent is authorized to call: databases, email, code repositories, third-party APIs. When one leaks, the damage window is measured in minutes, not hours.
This playbook gives you the exact steps to execute in the first 24 hours. Copy it into your incident response wiki before you need it.
Before You Start: What You're Dealing With
A leaked AI agent token is different from a leaked database password in one important way: the blast radius includes your provider's cost center. A compromised token can rack up thousands of dollars in API charges in under an hour while exfiltrating data from every tool the agent has access to.
Common leak vectors for AI agent tokens:
- Committed to a public or private git repo (most common)
- Stored in plaintext in a
.envfile that got included in a Docker image or deployment artifact - Logged by a debugging statement that ended up in application logs
- Exposed via a misconfigured environment variable in a CI/CD pipeline
- Stolen from a developer's local machine via malware
In short: Revoke the token before you investigate. Export usage logs before wiping anything. Check every downstream tool the agent could reach. If personal data was accessible, the GDPR 72-hour notification clock starts at the moment you became aware.
For more on preventing these vectors at the architecture level, see the TypeScript AI agent security playbook.
Phase 0: First 15 Minutes: Detect and Contain
Trigger: How You Find Out
You'll typically discover the leak via one of:
- GitHub secret scanning alert (GitHub scans all pushes for known token patterns)
- Unexpected billing spike from your AI provider
- Unusual usage in your provider's dashboard
- A security scanner (truffleHog, gitleaks, detect-secrets)
- An alert from a downstream system the agent uses
Step 0.1: Revoke Immediately
Do not investigate first. Revoke first.
OpenAI:
# Via dashboard: platform.openai.com/api-keys → select key → Delete
# Via API (requires a separate admin key):
curl https://api.openai.com/v1/organization/api_keys/KEY_ID \
-X DELETE \
-H "Authorization: Bearer $OPENAI_ADMIN_KEY"
Anthropic:
# Via dashboard: console.anthropic.com/settings/keys → Disable or Delete
# No API endpoint for key deletion; use the console
Google AI (Gemini/Vertex):
# Via gcloud:
gcloud services api-keys delete API_KEY_ID --project=YOUR_PROJECT
Generic (any provider with key management API):
# Most providers: find the key ID in your dashboard and call the delete endpoint
# Store your admin/management key separately from your agent's operational key
Step 0.2: Preserve Evidence Before You Wipe Anything
Before rotating or deleting logs, export them. You need these for the post-incident review and for any regulatory notification.
# Export provider usage logs (OpenAI example):
curl https://api.openai.com/v1/organization/usage \
-H "Authorization: Bearer $OPENAI_ADMIN_KEY" \
-G \
--data-urlencode "start_time=$(date -d '48 hours ago' +%s)" \
--data-urlencode "end_time=$(date +%s)" \
> /tmp/openai-usage-$(date +%Y%m%d-%H%M%S).json
# Export any application logs from the agent process
# Docker:
docker logs your-agent-container > /tmp/agent-logs-$(date +%Y%m%d-%H%M%S).txt 2>&1
# Systemd:
journalctl -u your-agent-service --since "48 hours ago" > /tmp/agent-systemd-$(date +%Y%m%d-%H%M%S).txt
Step 0.3: Identify the Leak Source
# Scan your current repo for the leaked token pattern:
git log --all --oneline | head -100 # see scope of history to check
grep -r "sk-" . # OpenAI key pattern
grep -r "sk-ant-" . # Anthropic key pattern
grep -rE "AIzaSy[0-9A-Za-z_-]{33}" . # Google AI pattern
# Check git history for the token value:
git log -p --all -S "YOUR_TOKEN_PREFIX_HERE" | head -200
# Run truffleHog on your repo (install: pip install trufflehog):
trufflehog git file://. --only-verified
Phase 1: First Hour: Scope and Rotate
Step 1.1: Determine the Token's Permission Scope
A token's damage is bounded by its permissions. Check what the compromised token was allowed to do:
# OpenAI: check if token had org-level access vs project-level
curl https://api.openai.com/v1/me \
-H "Authorization: Bearer $POTENTIALLY_LEAKED_TOKEN"
# WARNING: only do this if the token is not yet revoked and you need to confirm scope
# Revoke first if you already have another way to check scope
Document the answers to:
- Did the token have read access to conversation history?
- Did the token have write access to fine-tuning datasets or assistants?
- Did the token have billing visibility?
- Did the agent use this token to call downstream tools (databases, email APIs, Slack)?
Step 1.2: Check What the Token Actually Did
# OpenAI: get per-model usage breakdown for the suspected compromise window
curl "https://api.openai.com/v1/organization/usage/completions" \
-H "Authorization: Bearer $OPENAI_ADMIN_KEY" \
-G \
--data-urlencode "start_time=$(date -d '48 hours ago' +%s)" \
--data-urlencode "end_time=$(date +%s)" \
| python3 -c "
import json, sys
data = json.load(sys.stdin)
for bucket in data.get('data', []):
print(f\"{bucket['start_time']}: {bucket['results']} requests\")
"
# Look for:
# - Requests from IPs not matching your infrastructure
# - Requests at times your agent normally isn't running
# - Model names you don't use (an attacker may switch to a cheaper model to avoid detection)
# - Unusually large prompts (data exfiltration attempts often send large context windows)
Step 1.3: Issue a New Token with Minimum Permissions
Create the replacement token before you need it running again. This time, scope it down:
# Principle of least privilege for AI agent tokens:
# - Scope to one project, not the whole organization
# - If your provider supports it, restrict to specific models
# - Set spending limits at the project level, not just the org level
# - Use separate tokens for different agents (never share one token across multiple agents)
Store the new token correctly:
# Never in code. Use a secrets manager:
# AWS Secrets Manager:
aws secretsmanager create-secret \
--name "prod/ai-agent/openai-token" \
--secret-string "sk-..."
# Retrieve at runtime (not at build time):
export OPENAI_API_KEY=$(aws secretsmanager get-secret-value \
--secret-id prod/ai-agent/openai-token \
--query SecretString \
--output text)
# Or use a .env file that is in .gitignore and never committed
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
For a deeper treatment of MCP server token handling, see MCP server security.
Phase 2: First 24 Hours: Assess Damage and Notify
Step 2.1: Check Downstream Tool Access
AI agents often call tools beyond the AI provider. If the leaked token was used in an agentic loop with tool access, check each connected system:
# Example: check if an agent with database write access was abused
# Query your database audit log for the agent's service account:
psql -U admin -c "
SELECT event_time, client_ip, user_name, statement_text
FROM audit_log
WHERE user_name = 'ai_agent_user'
AND event_time > NOW() - INTERVAL '48 hours'
ORDER BY event_time;
"
# For email/Slack integrations: check sent items and outgoing webhooks
# For GitHub integrations: check the repo's audit log at
# Settings > Security > Audit log
Step 2.2: Determine If Personal Data Was Exposed
This is the GDPR/privacy trigger decision. Answer three questions:
- Could the leaked token read conversations that included personal data (names, emails, health info)?
- Could an attacker use the token to call tools that access personal data (CRM, database, email)?
- Is there evidence in the usage logs that an attacker actually did make such calls?
If the answer to 1 or 2 is yes, treat it as a personal data breach. You don't need to prove exploitation; unauthorized access to a system that could expose personal data is sufficient in most jurisdictions.
For the full GDPR data handling requirements for AI systems, see AI and data privacy for small teams.
Step 2.3: Notify (If Required)
GDPR (Article 33): If the incident meets the threshold of a personal data breach, you have 72 hours from discovery to notify your lead supervisory authority. The clock started when you first became aware, not when you confirmed it.
Your notification needs:
- Nature of the breach (leaked API token with X scope)
- Categories of data potentially affected
- Approximate number of data subjects affected (estimate if unknown)
- Likely consequences
- Measures taken or proposed
Affected users: If personal data of specific individuals was likely accessed, Article 34 may require individual notification too, unless the data was encrypted or the risk to individuals is low.
Internally: Notify legal, your DPO if you have one, and any enterprise customers whose data the agent might have processed. Don't delay internal notification while you're still assessing scope.
Phase 3: Post-Incident Review
Run this within 5 business days of containment.
Root Cause Analysis Checklist
- Where exactly was the token stored when it leaked?
- How long was the token exposed before discovery?
- What is the evidence that an attacker used the token (vs. it was discovered before exploitation)?
- What was the total unauthorized spend, if any?
- Did our alerting catch this, or did we find out externally?
Prevention Fixes
For each root cause identified, implement a corresponding control:
| Root cause | Fix |
|---|---|
| Token committed to git | Add pre-commit hook with gitleaks or detect-secrets |
| Token in Docker image | Move to runtime secrets, audit Dockerfile ENV instructions |
| Token in CI/CD logs | Mask the variable in your CI config; rotate all tokens that appeared in logs |
| No usage anomaly alerts | Set billing alerts and rate-limit notifications with your provider |
| Single token used by multiple agents | Separate tokens per agent, scoped to minimum model and project |
| Token had org-level access | Use project-scoped tokens, not admin tokens, for operational agents |
For a complete checklist of what to verify when evaluating AI tools your team uses, see vetting AI tools.
Copy-Paste Incident Checklist
Use this as your live tracking doc during an incident. Copy into a shared doc or incident channel.
Phase 0 (First 15 min)
- Token revoked in provider dashboard
- Billing alerts set to catch ongoing charges
- Usage logs exported (48-hour window before discovery)
- Application logs exported
- Leak source identified (git commit? .env? CI logs?)
- Incident channel opened, response team notified
Phase 1 (First hour)
- Token permission scope documented (what could it access?)
- Usage logs reviewed for anomalous IPs, times, models
- Evidence of exploitation: yes / no / unknown
- New token issued with reduced scope
- New token stored in secrets manager (not code)
- Agent redeployed with new token and verified working
Phase 2 (First 24 hours)
- Downstream tool access reviewed (DB, email, GitHub, Slack)
- Personal data exposure assessment complete: yes / no / unknown
- GDPR 72-hour clock: started at [TIME], deadline is [TIME+72h]
- DPA notification filed (if required)
- Internal stakeholders notified (legal, DPO, enterprise customers)
- External comms drafted (if required)
Phase 3 (Within 5 days)
- Root cause documented
- Prevention controls implemented
- All remaining tokens audited for same vulnerability pattern
- Incident report filed internally
- Lessons-learned session scheduled
Quick Reference: Token Revocation URLs
| Provider | Revocation URL |
|---|---|
| OpenAI | platform.openai.com/api-keys |
| Anthropic | console.anthropic.com/settings/keys |
| Google AI Studio | aistudio.google.com → API keys |
| Google Cloud (Vertex) | console.cloud.google.com → APIs & Services → Credentials |
| Cohere | dashboard.cohere.com/api-keys |
| Mistral | console.mistral.ai/api-keys |
| Hugging Face | huggingface.co/settings/tokens |
Bookmark this table. When an incident happens, you won't want to search for these URLs.
