An AI agent with a long-lived API key is a liability. If the agent is compromised through prompt injection, logs its context window to disk, or has its memory files accessed by another process, your RunPod account, your database, and your cloud provider credentials are all exposed simultaneously. HashiCorp Vault solves this with short-lived dynamic credentials: instead of giving your agent a permanent API key, Vault issues a credential that expires in 1 hour, can only access the specific resources the agent needs, and leaves an audit trail of every access.
Get more guides like this in your inbox
No spam. Unsubscribe anytime.
The Problem with .env Files
The standard pattern for giving an AI agent API access is an .env file containing a long-lived API key. This has three failure modes: the key is valid indefinitely (if it leaks, the attacker has permanent access), the key typically has broad permissions (a RunPod API key that can create pods can also delete them), and there is no audit trail. Vault addresses all three: credentials are short-lived, scoped to minimum permissions, and every access is logged.
Set Up Vault with AppRole Auth
AppRole is the recommended authentication method for machine-to-machine access. It uses a Role ID (like a username) and a Secret ID (like a password) to authenticate:
vault auth enable approle
cat > agent-policy.hcl << 'EOF'
path "secret/data/runpod" { capabilities = ["read"] }
path "secret/data/brave-search" { capabilities = ["read"] }
path "*" { capabilities = ["deny"] }
EOF
vault policy write ai-agent agent-policy.hcl
vault write auth/approle/role/ai-agent \
token_policies="ai-agent" \
token_ttl=1h \
secret_id_ttl=10m \
secret_id_num_uses=1Agent Authentication in Python
In your AI agent code, authenticate to Vault at startup and fetch credentials dynamically. Never hardcode credentials or read them from environment variables:
import hvac, os
client = hvac.Client(url=os.environ["VAULT_ADDR"])
response = client.auth.approle.login(
role_id=os.environ["VAULT_ROLE_ID"],
secret_id=os.environ["VAULT_SECRET_ID"], # Single-use, expires in 10 min
)
print(f"Token TTL: {response['auth']['lease_duration']}s")
# Fetch credentials at runtime
secret = client.secrets.kv.v2.read_secret_version(
path="runpod", mount_point="secret"
)
runpod_key = secret["data"]["data"]["api_key"]Infisical: The Open-Source Alternative
If HashiCorp's BSL license is a concern, Infisical is a fully open-source (MIT license) alternative with a nearly identical feature set. Infisical has a cleaner web UI, native Kubernetes integration, and a free cloud tier. For a self-hosted private AI setup where secrets never leave your infrastructure, the self-hosted version (Docker Compose or Kubernetes) is the recommended option.