An AI agent should never receive a raw secret merely so it can pass that secret to a tool. Give the runtime an opaque credential handle, resolve a short-lived audience-specific credential at the tool boundary, inject it into the outbound request outside model-visible data, and redact it before logs, traces, memory, errors, or results are created.
OWASP recommends centralized storage, short lifetimes, least privilege, rotation, revocation, and auditing across a secret's lifecycle (OWASP Secrets Management Cheat Sheet). Agent systems add several high-volume leak surfaces: prompt transcripts, tool arguments, retrieval indexes, durable memory, model-provider logs, observability exports, browser screenshots, and delegated-agent messages.
Inventory secrets and their paths
Include more than API keys:
- OAuth access and refresh tokens;
- database passwords and connection strings;
- SSH and signing keys;
- webhook secrets;
- session cookies;
- cloud workload credentials;
- client certificates and private keys; and
- one-time approval or password-reset links.
For each secret, record owner, issuer, consumers, audience, allowed operations, source, delivery path, storage, lifetime, rotation, revocation, and recovery contact. Then draw every place plaintext exists, including process memory and crash dumps.
Classify data that is not formally a credential but acts like one. A pre-authenticated URL or predictable Task handle may authorize access and deserves equivalent handling.
Use a credential-broker pattern
model proposes: read_customer_account(customer_17)
│
▼
agent policy checks principal, tenant, tool, resource
│
▼
runtime passes credential handle cred:accounts-read/acme
│
▼
tool broker resolves short-lived accounts-api token
│
▼
HTTP client adds Authorization header
│
▼
tool returns redacted domain data, never the token
The model sees the tool name and business arguments. It does not see the handle if the SDK can keep runtime metadata separate; it never sees the resolved credential.
type CredentialRequest = Readonly<{
workloadId: string;
humanSubject?: string;
tenantId: string;
taskId: string;
audience: string;
scopes: readonly string[];
purpose: string;
maxLifetimeSeconds: number;
}>;
This is application pseudocode. The broker verifies workload identity and policy rather than trusting these fields from the model or client. It returns the credential through a protected process boundary or performs the upstream request itself.
Prefer workload identity and dynamic credentials over shared static secrets. A dedicated agent workload should not inherit a developer's entire local environment or cloud profile.
Keep secrets out of prompts and tool schemas
Do not define tools such as:
call_api(url, api_key, body)
Use:
get_account_status(account_id)
The server selects the audience, credential profile, endpoint, method, and allowed response fields. Tool input and output schemas should have no credential fields. Reject unexpected authorization headers and URL user-info.
System prompts are not secure vaults. Models may reproduce context, providers may retain or inspect requests under configured policies, and application traces often capture prompts. A prompt instruction saying “never reveal this token” does not reduce the credential's authority.
Do not store secrets in agent memory or vector search. If retrieved content contains a secret, quarantine the document, redact before embedding, and begin incident response because the embedding or index may already be a derived exposure.
Reduce lifetime and blast radius
Use one credential per audience and purpose with the smallest scopes and shortest practical lifetime. Separate read, preview, and commit. Bind credentials to workload identity or proof-of-possession where supported.
OAuth Security BCP recommends privilege-restricted access tokens and sender-constrained tokens to reduce replay (RFC 9700). DPoP defines one application-level sender-constraint mechanism but is not authorization by itself (RFC 9449).
Avoid one “agent service token” shared by all tenants. Per-tenant or per-task credentials improve containment and attribution. If a downstream only supports a static API key, hide it behind a narrow broker and enforce tenant and operation policy there.
Redact before serialization
Redaction must happen before a value crosses into general telemetry:
const SENSITIVE_KEYS = new Set([
"authorization",
"cookie",
"set-cookie",
"apiKey",
"accessToken",
"refreshToken",
"clientSecret",
]);
function redactObject(value: unknown): unknown {
// Walk bounded structured data, replace sensitive fields, and reject cycles.
// This comment is a design requirement, not a complete implementation.
return boundedRedaction(value, SENSITIVE_KEYS);
}
Key-name filtering alone is insufficient. Scan for known token formats and registered secret values, but do not let scanning become an oracle that exposes whether a guessed secret exists. Cap recursion, bytes, and processing time.
Apply redaction to prompts, tool arguments and results, HTTP headers and bodies, exceptions, traces, metrics labels, screenshots, replay fixtures, support bundles, and dead-letter queues. Never place high-cardinality tokens in metric labels.
Logs can contain sensitive personal and technical data and must be protected from unauthorized read, tampering, and deletion (OWASP Logging Cheat Sheet). Restrict access and audit access to the logs themselves.
Rotate without breaking active agent work
Rotation has four phases:
- issue a new credential or key;
- make consumers accept or use the new value;
- verify successful use and stop issuing the old value;
- revoke and delete the old value after the overlap policy.
For short-lived dynamic credentials, rotation often means rotating issuer keys and allowing current tokens to expire. Test key discovery cache behavior. For static upstream keys, support dual values during a bounded cutover if the provider permits it.
Do not copy secrets into task state to survive rotation. Persist the credential profile or grant ID, then resolve a current valid credential when the next tool call occurs. A task waiting for approval should not retain a commit credential it does not yet need.
Design failure and break-glass behavior
If the secrets service is unavailable, fail closed for writes and sensitive reads. Do not fall back to an environment-wide administrator key. Queue resumable work without serializing the secret and tell the user the capability is temporarily unavailable.
Document a break-glass process outside the agent path: named human authorization, time-limited access, independent alerting, and retrospective review. The agent must not decide that an outage justifies break-glass access.
Backups of the secrets system require encryption, reduced access, tested restore, and separate recovery credentials. OWASP explicitly recommends testing backup, restore, and emergency processes.
Respond to exposure as compromise
If a credential enters a prompt, result, log, commit, screenshot, or memory:
- revoke it immediately where possible;
- replace it with a new narrowly scoped credential;
- disable affected tools if revocation is delayed;
- locate every copy and derived store;
- preserve an incident timeline without reproducing plaintext;
- remove or cryptographically erase exposed copies under retention policy;
- inspect actions performed during the exposure window; and
- fix the path that serialized the secret.
Redaction after the fact does not make a still-valid credential safe.
Tests that catch real leaks
- Seed canary credentials and assert none appear in model requests or responses.
- Throw upstream errors containing authorization headers and inspect all telemetry.
- Verify tool results cannot return secret fields through nested objects.
- Rotate while a durable task is paused and confirm it resolves a new credential.
- Revoke a credential and detect attempted reuse.
- Test tenant isolation in credential handles and broker policy.
- Confirm crash dumps, debug endpoints, and support bundles are restricted and redacted.
- Verify a malicious tool argument cannot select another credential profile or audience.
Release checklist
- Inventory every credential and plaintext path.
- Prefer workload identity and dynamic audience-specific tokens.
- Resolve credentials at the tool boundary outside model context.
- Remove credential fields from tool schemas and reject arbitrary headers.
- Redact before logs, traces, errors, memory, and replay serialization.
- Scope by tenant, task, audience, operation, and lifetime.
- Test rotation, revocation, issuer-key changes, and broker outages.
- Fail closed instead of using an administrator fallback.
- Keep break-glass authority outside the agent.
- Treat any prompt or log exposure as a credential incident.