Overview

What the Agent Vault is, how the per-user agent model works, its MCP-primary + REST-fallback architecture, and the security tradeoffs it makes.

The Agent Vault lets AI coding agents — Claude Code, Cursor, Codex, VS Code, or any custom agent that can make an authenticated HTTP call — resolve your SecretStash secrets at call time, instead of you copying raw values into a local .env file or an agent's config.

Instead of a shared project token, every agent you connect gets its own identity, its own credential, and its own scope of authorized environments. The agent asks for a secret by name when it actually needs it; SecretStash decrypts it and hands back the plaintext value for that one call.

The per-user, per-agent model

  • Every agent belongs to a user, within that user's current organization. There is no shared "project" credential — each agent you connect (a Claude Code session, a Cursor install, a CI bot, a script) is its own row with its own name, type, and status.
  • Each agent authenticates with its own API key — a personal access token scoped with a single agent:{uuid} ability. It cannot be used for anything else: not to sign in, not to call any other SecretStash API endpoint, not to act as any other agent.
  • Each agent is authorized against a specific, explicit set of environments. An agent connected to your staging environment cannot resolve a production secret, even if both belong to the same application.
  • Revoking an agent immediately deletes its token. There's nothing to rotate elsewhere — the credential simply stops working.

This means the blast radius of a leaked agent credential is exactly one agent's authorized environments, not your whole account.

MCP-primary, REST-fallback architecture

The Agent Vault exposes the same capability — resolve a secret by name — on two surfaces:

  • MCP server (primary): /api/v1/mcp/agent-vault. This is the native integration path for MCP-aware tools like Claude Code, Cursor, Codex, and VS Code. The agent calls a tool (resolve_secret), and the model decides when it needs a credential, without you ever pasting one into a prompt or a config file.
  • REST API (fallback): /api/v1/agents/{agent}/secrets/.... A plain authenticated HTTP endpoint for any agent, script, or runtime that isn't MCP-aware — a CI job, a custom automation, a language without a mature MCP client yet.

Both surfaces authenticate with the same Bearer token and enforce the same authorization rules, so there's one mental model regardless of which one a given agent uses. See MCP Integration and REST API for the details of each.

The security tradeoff

Earlier designs for agent secret access considered a local forwarding proxy: point HTTPS_PROXY at SecretStash, and have it substitute placeholders into outgoing requests before they leave your machine. That approach was dropped — a proxy can't intercept and rewrite HTTPS traffic without a local man-in-the-middle setup, which defeats the goal of "no local install."

The Agent Vault instead controls access at the point of resolution:

  • SecretStash decides which secrets an agent is allowed to resolve (its authorized environments) and audits every resolution it performs.
  • SecretStash does not control where the agent sends the secret afterward, once the plaintext value is returned from a tool call or API response. The agent transiently sees the plaintext — this is unavoidable for any design that doesn't intercept the agent's outbound HTTPS traffic.
  • Secrets are never stored by SecretStash outside of their encrypted form, and are never persisted by the agent on your behalf — an agent that behaves correctly resolves a value, uses it for one call, and discards it.
  • Access is scoped and revocable per agent at any time, and every resolution is recorded for later review.

This is the same tradeoff most managed secrets platforms make in practice: scoped, audited access to the credential — not control over the credential's destination once released.

Placeholder convention

Because a well-behaved agent should never need to see a secret until the moment it uses it, write configuration, code comments, and system prompts using a placeholder rather than a real value:

__SECRETSTASH_[APPNAME]_[ENV]_[KEYNAME]__

For example: __SECRETSTASH_GITHUB_PROD_TOKEN__. Tell your agent (in its instructions or system prompt) that these placeholders are opaque — it should resolve the underlying value through the vault only when it's actually about to make the authenticated call, and it should never write the resolved plaintext back into a file, a log, or a commit. If a raw secret ever shows up in output that should have carried a placeholder, treat it as a bug in that config or prompt, not as an inconvenience to work around.

Next steps