DEV Community

Jurgen PWR
Jurgen PWR

Posted on

AI Agent Security: How to Build Agents That Don't Leak Your API Keys

A practical guide to credential management, secrets handling, and supply chain defense for AI agent builders.


Why This Matters Right Now

The AI agent ecosystem is exploding. Every week there's a new framework, a new tool, a new way to let LLMs take actions in the real world. But there's a dirty secret no one talks about openly:

Most AI agents are security disasters waiting to happen.

The Bitwarden CLI compromise (April 2026) is just the latest example. A popular tool, trusted by thousands, got backdoored through a supply chain attack. Agent Vault — an open-source credential proxy — appeared as a direct response.

These aren't isolated incidents. They're symptoms of a gold rush ignoring security fundamentals.

If you're building AI agents, you need to understand:

  1. How to store secrets without hardcoding them
  2. How to give agents only the access they need (principle of least privilege)
  3. How to detect when your dependencies are compromised
  4. How to rotate credentials when things go wrong

This guide covers all four.


The Threat Model

Before diving into solutions, let's be clear about what you're defending against.

Threat Vector 1: Hardcoded Secrets

# DON'T DO THIS — ever
openai_api_key = "sk-prod-1234567890abcdef"
Enter fullscreen mode Exit fullscreen mode

Anyone with repo access — collaborators, accidentally-public repos, ex-employees — now has your production key. GitHub scans for these automatically. So do attackers.

Threat Vector 2: Over-Privileged Agents

Your agent doesn't need full admin access to your AWS account just to read S3 buckets. But most agent configs grant admin because it's easier.

When that agent gets compromised — and it will — the attacker has the keys to your entire infrastructure.

Threat Vector 3: Dependency Supply Chain

You pip install a library. That library updates. The update is compromised. Now your agent is a backdoor into your infrastructure.

This isn't theoretical. It happened to npm. It happened to PyPI. It happened to RubyGems. And in April 2026 — it happened to the Bitwarden CLI, one of the most trusted password manager CLIs in the ecosystem.

Threat Vector 4: Credential Persistence

Agents run long tasks. Credentials expire mid-run. The agent panics and — in a worst-case implementation — logs raw auth headers to a file "for debugging."


Solution 1: Never Store Secrets in Code

Option A: Environment Variables (Start Here)

# .env file — add to .gitignore immediately
OPENAI_API_KEY=sk-prod-xxxxx
ANTHROPIC_API_KEY=sk-ant-api-xxxxx
AWS_ACCESS_KEY_ID=xxxxx
AWS_SECRET_ACCESS_KEY=xxxxx
Enter fullscreen mode Exit fullscreen mode
import os
from dotenv import load_dotenv

load_dotenv()

api_key = os.environ.get("OPENAI_API_KEY")
if not api_key:
    raise ValueError("OPENAI_API_KEY not set — refusing to start")
Enter fullscreen mode Exit fullscreen mode

Never hardcode. Never log. Never pass in URLs.

Option B: HashiCorp Vault (Production)

# Fetch secret at runtime, not at deploy time
vault kv get -field=api_key secret/ai-agents/production
Enter fullscreen mode Exit fullscreen mode

Your agent gets credentials on startup from Vault. Rotate without redeploying.

Option C: Cloud-Native Secrets Managers

Cloud Service SDK
AWS Secrets Manager / Parameter Store boto3
GCP Secret Manager google-cloud-secret-manager
Azure Key Vault azure-keyvault-secrets
# AWS example — fetch at runtime
import boto3

def get_secret(secret_name):
    client = boto3.client("secretsmanager", region_name="eu-central-1")
    response = client.get_secret_value(SecretId=secret_name)
    return response["SecretString"]

api_key = get_secret("prod/ai-agent/openai-key")
Enter fullscreen mode Exit fullscreen mode

Solution 2: Principle of Least Privilege

Your AI agent should have exactly the permissions it needs — no more.

AWS IAM: Scope to the Bucket

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-specific-agent-bucket/*"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Not s3:*. Not *. Only what the agent actually needs.

GitHub Token Scopes

Agent Task Required Scopes
Read issues only issues:read
Comment on PRs pull_requests:write
Create releases contents:write + actions:write
Read repo metadata metadata:read

Create a fine-grained token scoped to the specific repo. Not a classic token with full repo access.

Rotating Credentials

Build rotation into your agent's startup sequence:

def startup_with_rotation():
    current_key = fetch_from_secrets_manager("openai-key")

    # Verify key works before proceeding
    if not verify_key(current_key):
        # Key may have been rotated already — fetch latest
        current_key = refresh_from_secrets_manager("openai-key")
        if not verify_key(current_key):
            raise RuntimeError("All credentials invalid — stopping agent")

    return current_key
Enter fullscreen mode Exit fullscreen mode

Solution 3: Supply Chain Defense

Pin Dependencies with Hash Verification

# WRONG — auto-updates pull in compromised versions
requests>=2.28.0

# RIGHT — exact version + hash verification
requests==2.31.0     --hash=sha256:58cd2187423d85b68bbe7b0f6f5a3e4f4d7ee7d7e1b1e0b1f9a9e5b4c3d2e1f0
Enter fullscreen mode Exit fullscreen mode

Generate hashes automatically:

pip-compile --generate-hashes requirements.in -o requirements.txt
pip install -r requirements.txt --require-hashes
Enter fullscreen mode Exit fullscreen mode

Now if any package is tampered with, installation fails loudly.

Automate Security Audits

# Python — runs in CI, fails build on known vulnerabilities
pip install pip-audit
pip-audit

# Node.js
npm audit --audit-level=high

# Container images (check what's inside your Docker image)
brew install syft
syft packages python:3.11-slim -o table
Enter fullscreen mode Exit fullscreen mode

Add this to your CI/CD pipeline. Every PR. Every deploy.

Subscribe to Alerts


Solution 4: The Agent Vault Pattern

Agent Vault (by Infisical) represents a new architectural pattern emerging directly from incidents like the Bitwarden compromise.

The idea: never give your agent direct access to secrets. Instead, the agent talks to a local proxy.

Traditional:
agent ──────────────────────────► Cloud Secrets Manager
         (direct, persistent creds)

Agent Vault pattern:
agent → Agent Vault (local proxy) → Cloud Secrets Manager
              │
              ├── audit log (every credential access)
              ├── rate limiting (prevent bulk exfil)
              ├── scope enforcement (agent can't request secrets outside its scope)
              └── instant revocation (kill switch without redeploying agent)
Enter fullscreen mode Exit fullscreen mode

When you kill the proxy, the agent loses access immediately. No waiting for token expiry. No hunting down where credentials are cached.

Setup is straightforward:

# Install Agent Vault
pip install agent-vault

# Start the proxy (runs locally on a port your agent can reach)
agent-vault serve --config agent-vault.yaml

# Your agent now talks to localhost instead of directly to Vault/AWS
SECRETS_PROXY_URL=http://localhost:8200
Enter fullscreen mode Exit fullscreen mode

This pattern is worth adopting if you're building anything production-facing.


Deployment Checklist

Before shipping any AI agent to production, run through this:

Secrets & Credentials

  • [ ] Zero hardcoded secrets in code or config files
  • [ ] .env files added to .gitignore before first commit
  • [ ] Secrets loaded from env vars or secrets manager at runtime
  • [ ] Credential rotation documented and tested at least once

Permissions

  • [ ] Agent uses scoped IAM role / fine-grained token
  • [ ] No admin-level access anywhere unless explicitly required
  • [ ] Token scopes reviewed and minimized

Dependencies

  • [ ] All dependencies pinned to exact versions
  • [ ] Hash verification enabled (--require-hashes)
  • [ ] pip-audit or npm audit running in CI
  • [ ] Alert subscription active for used packages

Runtime

  • [ ] Agent Vault or equivalent proxy in place (or on roadmap)
  • [ ] Access logs being collected
  • [ ] Credential expiry handled gracefully in code
  • [ ] Incident response plan exists (who do you call when a key leaks?)

TL;DR

Threat Fix
Hardcoded secrets Env vars → Vault → Cloud secrets manager
Over-privileged agents Scoped IAM + fine-grained tokens
Supply chain Pin + hash + audit in CI
Credential drift Agent Vault proxy + rotation logic

The AI agent gold rush isn't slowing down. The security incidents aren't either. Build this in from the start — retrofitting security onto a running agent in production is significantly harder.


Found this useful? Follow for more practical AI agent guides.

Top comments (0)