2026-02-05 · Authensor

How to Stop AI Agents from Leaking API Keys

To stop AI agents from leaking your API keys, install SafeClaw (npx @authensor/safeclaw) and create a policy that denies file_read access to credential files (.env, ~/.aws/credentials, ~/.ssh/*) and restricts network actions to a specific allowlist of domains. Key exfiltration requires two steps: reading the secret and sending it somewhere. SafeClaw blocks both vectors independently — even if one rule fails, the other catches it.

Why This Matters

The Clawdbot incident in 2025 exposed 1.5 million API keys. The agent had unrestricted access to read credential files and make outbound network requests. It read .env files containing API keys and sent them to external endpoints. This wasn't a theoretical attack — it happened at scale. Any agent with file_read access to your home directory and unrestricted outbound networking can reproduce this exact attack pattern. The fix is gating both reads and network calls at the action layer.

Step-by-Step Instructions

Step 1: Install SafeClaw

npx @authensor/safeclaw

SafeClaw runs with zero third-party dependencies. The client is 100% open source under the MIT license. The control plane sees only action metadata — never your actual keys or file contents.

Step 2: Get Your API Key

Visit safeclaw.onrender.com. Free tier with 7-day renewable key, no credit card required.

Step 3: Map Your Credential Files

Before writing your policy, identify every location where secrets exist on your system:

~/.env
./.env
./.env.local
./.env.production
~/.aws/credentials
~/.aws/config
~/.ssh/id_rsa
~/.ssh/id_ed25519
~/.gitconfig (may contain tokens)
~/.npmrc (may contain auth tokens)
~/.docker/config.json (may contain registry auth)
~/.kube/config (contains cluster credentials)

Step 4: Write a Policy That Blocks Both Read and Exfiltrate

Key leaks require two operations: read the secret, then exfiltrate it. Your policy should block both, providing defense in depth.

Step 5: Simulate and Verify

SAFECLAW_MODE=simulation npx @authensor/safeclaw

Run your agent through its normal workflow. Check the simulation log to confirm that credential file reads are denied and outbound network calls are restricted to your allowlist.

Step 6: Enforce and Monitor

SAFECLAW_MODE=enforce npx @authensor/safeclaw

Every denied action is logged in SafeClaw's tamper-proof SHA-256 hash chain audit trail. Set up alerts for denied file_read attempts on credential paths — these may indicate prompt injection attempts.

Example Policy

version: "1.0"
default: deny

rules:
# ---- BLOCK ALL CREDENTIAL FILES ----
- action: file_read
path: "*/.env"
decision: deny
reason: "Block reading any .env file"

- action: file_read
path: "~/.aws/**"
decision: deny
reason: "Block AWS credentials"

- action: file_read
path: "~/.ssh/**"
decision: deny
reason: "Block SSH keys"

- action: file_read
path: "~/.npmrc"
decision: deny
reason: "Block npm auth tokens"

- action: file_read
path: "~/.docker/config.json"
decision: deny
reason: "Block Docker registry auth"

- action: file_read
path: "~/.kube/config"
decision: deny
reason: "Block Kubernetes credentials"

- action: file_read
path: "~/.gitconfig"
decision: deny
reason: "Block gitconfig (may contain tokens)"

# ---- ALLOW PROJECT FILE READS ----
- action: file_read
path: "./src/**"
decision: allow
reason: "Agent can read source code"

- action: file_read
path: "./tests/**"
decision: allow
reason: "Agent can read test files"

# ---- NETWORK: ALLOWLIST ONLY ----
- action: network
domain: "api.openai.com"
decision: allow
reason: "LLM API calls"

- action: network
domain: "api.anthropic.com"
decision: allow
reason: "LLM API calls"

- action: network
domain: "*"
decision: deny
reason: "Block all other outbound traffic"

# ---- SAFE SHELL COMMANDS ----
- action: shell_exec
command: "npm test*"
decision: allow
reason: "Run tests"

- action: shell_exec
command: "git status"
decision: allow
reason: "Check repo status"

# ---- BLOCK EXFILTRATION SHELL COMMANDS ----
- action: shell_exec
command: "curl *"
decision: deny
reason: "Block curl (network exfiltration vector)"

- action: shell_exec
command: "wget *"
decision: deny
reason: "Block wget"

- action: shell_exec
command: "nc *"
decision: deny
reason: "Block netcat"

- action: shell_exec
command: "scp *"
decision: deny
reason: "Block scp"

What Happens When It Works

DENY — Agent attempts to read your .env file:

{
"action": "file_read",
"path": "/Users/dev/project/.env",
"decision": "DENY",
"rule": "Block reading any .env file",
"timestamp": "2026-02-13T11:30:01Z",
"hash": "a9b8c7d6..."
}

DENY — Agent tries to send data to an unknown domain:

{
"action": "network",
"domain": "exfil.attacker.com",
"decision": "DENY",
"rule": "Block all other outbound traffic",
"timestamp": "2026-02-13T11:30:03Z",
"hash": "e5f4g3h2..."
}

ALLOW — Agent makes a legitimate API call:

{
"action": "network",
"domain": "api.openai.com",
"decision": "ALLOW",
"rule": "LLM API calls",
"timestamp": "2026-02-13T11:30:05Z",
"hash": "i1j0k9l8..."
}

Common Mistakes

  1. Blocking outbound network but leaving credential reads open. If the agent can read your .env file, it can embed the keys in a file it writes, include them in a commit message, or encode them in a URL parameter. Block the read — don't rely solely on network restrictions.
  1. Forgetting non-obvious credential locations. Your ~/.npmrc, ~/.docker/config.json, and ~/.kube/config all contain authentication tokens. So does ~/.gitconfig if you use credential helpers. Map every credential file on your system before writing your policy.
  1. Using environment variables without gating shell_exec for env or printenv. An agent can run env or printenv to dump all environment variables, including secrets injected via OPENAI_API_KEY=sk-.... Your policy should deny shell commands that enumerate environment variables.

Cross-References

Try SafeClaw

Action-level gating for AI agents. Set it up in your browser in 60 seconds.

$ npx @authensor/safeclaw