Skip to main content

Overview

AgentVault holds the credentials your governed tools need (an upstream API key, a bearer token) so that agents never hold them. An operator stores a credential once and binds it to a governed tool. Agents can never create, read, rotate or bind a credential. A credential is a single opaque string secret. It is write-only: no response, ledger row or log line ever contains it, or its base64.

Credential references and the local store

A credential is a reference: provider names where the secret lives and ref locates it there. The only provider available today is local. With local, the secret is kept in the Agent Sentinel database as an envelope-encrypted payload:
  • Each secret is encrypted with its own random AES-256-GCM data key.
  • The data key is wrapped by a versioned master key, identified by key_id.
  • The payload is bound to its organization and credential id, so a ciphertext copied into another row fails to open.
If the credential store is unavailable, every route returns 503 agentvault_local_store_disabled or 503 agentvault_key_unavailable, and nothing is stored or changed.
Vault connectors are not available yet. External secret managers (HashiCorp Vault, cloud secret managers) are planned as additional providers. Until then, local is the only provider.

Who can call these routes

  • User sessions only. Every route refuses any API key, bound to an agent or not, with 403 user_session_required.
  • Reads (GET) require membership of your active organization.
  • Writes require the OWNER or ADMIN role. A MEMBER gets 403 org_admin_required.
  • A credential or governed tool of another organization is a 404. A credential can only be bound to a tool of its own organization.

Endpoints

All routes are under /api/v1/agentvault/credentials.

Create a credential

  • name matches ^[A-Za-z0-9_.-]{1,128}$ and is unique in the organization (409 credential_name_exists).
  • secret is a non-empty string of at most 8 KiB, UTF-8 encoded. A validation error never echoes it.
  • scopes is a list of at most 32 strings of at most 64 characters each.
The response carries id, organization_id, name, provider, ref, scopes, key_id, created_by_user_id, created_at, rotated_at and revoked_at. It never carries the secret or any envelope field (wrapped_data_key, wrap_nonce, data_nonce, ciphertext).

Revoke a credential

Revocation is permanent and idempotent. A revoked credential cannot be bound (409 credential_revoked) and is never re-wrapped.

Bind a credential to a governed tool

The secret is injected into exactly one header:
  • type must be "header".
  • header matches ^[A-Za-z0-9-]{1,64}$ and is not, in any letter case, Host, Content-Length, Transfer-Encoding, Cookie, Connection or X-Sentinel-Decision-Token.
  • prefix is optional: at most 32 printable ASCII characters, so it has no CR or LF. An explicit null is rejected; omit the key for no prefix.
  • Any other key is rejected with 422.
A tool has at most one credential. Binding a tool that is already bound replaces its binding. DELETE /{id}/bindings/{tool_id} clears the binding, but only if the tool is bound to that credential. Otherwise it returns 404 credential_binding_not_found.

Key rotation

Each credential records the key_id of the master key that wraps its data key. Agent Sentinel manages the master keys. When a new master key is available, an owner or admin moves the organization’s credentials onto it:
Rotation re-wraps only the data key. The ciphertext is unchanged and the secret itself is never decrypted. All of your organization’s non-revoked credentials move in one transaction: if any fails, none move. An unknown or malformed to_key_id returns 503 agentvault_key_unavailable before anything changes. A to_key_id that is empty, longer than 64 characters or contains control characters returns 422.

Audit trail

Every write appends exactly one chained, signed ledger row, in the same transaction as the change. Its outputs.type is credential_created, credential_revoked, credential_rotated, credential_bound or credential_unbound. outputs carries the credential id(s), the tool id for bindings, and the count for a rotation. The row’s actor is the user who made the change. Each operator action is recorded under its own completed run. If a signing key is configured and the row cannot be signed, the route returns 500 audit_signing_failed and the change is rolled back. A credential change is never stored without its audit row.

Leases and injection

Binding a credential does not hand it to anyone. A credential is leased and its secret injected into the bound header only after the gateway returns an ALLOW decision for that tool call. The secret is added to the outbound request by the platform and is never returned to the agent. Lease minting and injection ship in a later release; this release covers storage, rotation and bindings.

Error codes