Skip to main content
Agent Vault agents follow a standard HTTP protocol to interact with the server. Agents handle this automatically (the instructions are embedded in every invite response). This page is a reference for understanding what happens under the hood.
Agents must never extract, log, or display credential values. They reference credentials by key name only.

Bearer token

Every request an agent makes to Agent Vault requires a bearer token. How the agent gets one depends on how it connects:
MethodHow the agent gets a token
agent-vault vault runAgent Vault sets AGENT_VAULT_SESSION_TOKEN on the child process automatically
Agent inviteAgent calls POST {invite_url} and receives an agent token
Both methods deliver the same core connection details:
VariableDescription
AGENT_VAULT_ADDRBase URL of the Agent Vault server (e.g. http://127.0.0.1:14321)
AGENT_VAULT_SESSION_TOKENBearer token for all Agent Vault requests

Session types

There are two session types:
  • Vault-scoped sessions — created by agent-vault vault run. The vault is embedded in the session. No extra headers needed.
  • Instance-level agent tokens — created via agent invites. The agent must include an X-Vault header on every vault-scoped request to select which vault to use.

The X-Vault header

Instance-level agent tokens must include X-Vault: {vault_name} on all vault-scoped requests (discover, proxy, proposals, credentials):
GET {AGENT_VAULT_ADDR}/discover
Authorization: Bearer {AGENT_VAULT_SESSION_TOKEN}
X-Vault: my-vault
Agents created via agent-vault vault run do not need this header — the vault is embedded in the session token.

Instance-level agent tokens

Agents invited via agent-vault agent invite receive instance-level agent tokens that can access multiple vaults. The agent token can be configured with no expiry (works indefinitely) or a specific TTL. If the token expires, the operator can issue a new one via rotation. See Agents overview for the full lifecycle.

Discover services

Before proxying anything, the agent calls /discover to learn which hosts have credentials configured in the vault.
GET {AGENT_VAULT_ADDR}/discover
Authorization: Bearer {AGENT_VAULT_SESSION_TOKEN}
X-Vault: my-vault
The X-Vault header is required for instance-level agent tokens. Vault-scoped sessions (from vault run) can omit it.
Response
{
  "vault": "my-vault",
  "proxy_url": "http://127.0.0.1:14321/proxy",
  "services": [
    { "host": "api.stripe.com", "description": "Stripe API" },
    { "host": "*.github.com", "description": "GitHub API" }
  ],
  "available_credentials": ["GITHUB_TOKEN", "STRIPE_KEY"]
}
  • services lists the hosts the agent can proxy through Agent Vault (defined by the vault’s services). Requests to any other host go direct.
  • available_credentials lists credential key names in the vault (values are never exposed). Agents use these to avoid creating duplicate slots in proposals.

Proxy requests

For hosts returned by /discover, the agent routes requests through the Agent Vault proxy:
{AGENT_VAULT_ADDR}/proxy/{target_host}/{path}[?query]
Authorization: Bearer {AGENT_VAULT_SESSION_TOKEN}
Agent Vault strips the agent’s auth header, attaches the real credentials from the vault’s services, and forwards the request over HTTPS.
GET http://127.0.0.1:14321/proxy/api.stripe.com/v1/charges?limit=10
Authorization: Bearer {AGENT_VAULT_SESSION_TOKEN}

Propose changes

When an agent needs access to a service that is not in the vault’s services, it creates a proposal. Each proposal bundles services (host access) and credential slots (credentials the human provides at approval time).
POST {AGENT_VAULT_ADDR}/v1/proposals
Authorization: Bearer {AGENT_VAULT_SESSION_TOKEN}
Content-Type: application/json

{
  "services": [
    {
      "action": "set",
      "host": "api.stripe.com",
      "description": "Stripe API",
      "auth": { "type": "bearer", "token": "STRIPE_KEY" }
    }
  ],
  "credentials": [
    {
      "action": "set",
      "key": "STRIPE_KEY",
      "description": "Stripe API key",
      "obtain": "https://dashboard.stripe.com/apikeys",
      "obtain_instructions": "Developers > API Keys > Reveal test key"
    }
  ],
  "message": "Need Stripe API key for billing feature",
  "user_message": "I need access to your Stripe account to build the checkout page."
}
The response includes an approval_url that the agent presents to the user:
Response (201)
{
  "id": 1,
  "status": "pending",
  "vault": "default",
  "approval_url": "http://localhost:14321/approve/1?token=av_appr_...",
  "message": "Proposal created. Approve here: http://localhost:14321/approve/1?token=av_appr_..."
}
The agent then polls GET /v1/proposals/{id} until the status changes from pending (every 3s for the first 30s, then every 10s). Once applied, the agent retries its original request.
Every credential key referenced in a service’s auth config must resolve to either a credential slot in the same proposal or an existing credential in available_credentials. Otherwise the request returns 400.
See Proposals for the full proposal lifecycle, including storing credentials back and removing access.

Error handling

StatusMeaningWhat the agent does
401Invalid or expired tokenRe-check AGENT_VAULT_SESSION_TOKEN. Contact operator for a new token or rotation.
403Host not allowedCreate a proposal to request access. The response includes a proposal_hint.
429Too many pending proposalsWait for existing proposals to be reviewed.
502Missing credential or upstream errorTell the user a credential may need to be added.

Security constraints

  • Never extract, log, or display credential values
  • Never hardcode tokens. Always read from AGENT_VAULT_SESSION_TOKEN.
  • Only proxy hosts returned by /discover. For unlisted hosts, create a proposal.
  • If a credential_not_found error occurs, inform the user which key is missing.