Using Secrets in Agents

Agents never see secret values. They reference secrets by name using the handle syntax, and the daemon substitutes the plaintext at dispatch time.

Handle Syntax

{{secret:<name>}}

Use handles anywhere in tool call JSON arguments:

{
  "url": "https://api.openai.com/v1/chat/completions",
  "headers": {
    "Authorization": "Bearer {{secret:openai-key}}"
  }
}
{
  "url": "https://api.example.com/data?key={{secret:api-key}}"
}

The daemon:

  1. Parses the tool input JSON
  2. Finds all {{secret:<name>}} occurrences
  3. Checks the agent has secret.use:<name> capability
  4. Finds an active pre-approval policy matching (name, tool, host)
  5. Substitutes the plaintext inline in the tool input (only for the handler, never logged)
  6. Calls the tool handler with the substituted input
  7. Scrubs the tool output for any secret values before returning to the agent

Manifest Declaration

Declare which secrets an agent may use:

spec:
  capabilities:
    - secret.use:openai-key
    - secret.use:db-*            # glob: any secret starting with "db-"

SDK Usage

The Agent SDK does not need special handling for secrets; just pass the handle as a string in your tool input:

#![allow(unused)]
fn main() {
let result = agent.invoke_tool("web.fetch", json!({
    "url": "https://api.openai.com/v1/models",
    "headers": {
        "Authorization": "Bearer {{secret:openai-key}}"
    }
})).await?;
}

If the secret is not registered, the capability is missing, or no policy matches, the call returns a ToolFailed error describing why.

Output Scrubbing

After the tool handler returns, agentd scans the result for any registered secret values. If found, they are replaced with [REDACTED:<name>]:

{"body": "Error: invalid token [REDACTED:openai-key]"}

This prevents accidental leakage into the agent's LLM context.

sandbox.exec and Secrets

The sandbox.exec tool supports injecting secrets as environment variables in the sandboxed process:

{
  "runtime": "sh",
  "code": "curl -H \"Authorization: Bearer $OPENAI_KEY\" https://api.openai.com/v1/models",
  "secrets": {
    "OPENAI_KEY": "{{secret:openai-key}}"
  }
}

The environment variable is set for the child process only. It does not appear in tool logs.