> ## Documentation Index
> Fetch the complete documentation index at: https://vetta.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Credential vault

> Secrets injected at the network boundary — the agent never sees raw values.

<Info>**Available now.** The vault API and CLI are live, with write-only at-rest encryption. Injection is live on the [MCP connector](/docs/capabilities/tools#mcp-connector) path; `env_var` substitution on general sandbox egress is coming soon and the kind is refused until then.</Info>

The vault lets you register a credential once and reference it by ID, so you don't run your own secret store or transmit tokens on every call. Its defining property: **the agent never sees the raw secret**. Values are injected at the network boundary, so nothing sensitive enters the model's context, the transcript, or your logs.

## Setting a credential

<CodeGroup>
  ```bash CLI theme={"system"}
  # one vault per identity; credentials are sealed into it by vault id
  vetta vault create --name ava-secrets --identity ava

  # env-var kind: read from stdin, never echoed; bound to the host it may be sent to
  vetta vault set --vault vlt_... --env PAYMENTS_API_KEY --host api.payments.example.com

  # MCP static bearer, keyed by server URL
  vetta vault set --vault vlt_... --mcp-bearer https://mcp.example.com/mcp

  # MCP OAuth with refresh
  vetta vault set --vault vlt_... --mcp-oauth https://chat.example.com/mcp
  vetta vault credentials --vault vlt_...   # metadata only; no value is ever returned
  vetta vault rm --vault vlt_... --credential PAYMENTS_API_KEY
  ```

  ```typescript TypeScript theme={"system"}
  await vetta.vaults.credentials.create(vault.id, {
    displayName: "Task tracker API key",
    auth: { type: "static_bearer", mcpServerUrl: "https://mcp.example.com/mcp", token: "tok_..." },
  });
  ```
</CodeGroup>

## How network-boundary injection works

```
env_var  (bound to host = api.payments.example.com):
  sandbox env  PAYMENTS_API_KEY = "vetta_ref_a1b2..."   (placeholder, never the real key)
        │
        ▼  agent runs `curl https://api.payments.example.com ... -H "Authorization: Bearer $PAYMENTS_API_KEY"`
  egress proxy  IF request host == bound host  →  swaps vetta_ref_a1b2... → real secret  ──▶  upstream API
                ELSE (any other host)          →  placeholder is sent as-is; the real secret never leaves

mcp_oauth / static_bearer:
  MCP connector (server-side)  injects the token when the agent connects to mcp_server_url
```

The sandbox process, the model, the transcript, and logs only ever see the placeholder. The substitution happens outside the sandbox, at egress — and **only when the request is bound for the credential's destination host**. If a tricked or prompt-injected agent tries to `curl` the placeholder to `attacker.example.com`, the proxy sends the inert placeholder, not the secret. A credential can never be exfiltrated to a host it wasn't scoped to.

## At rest

Credentials are protected with envelope encryption: a per-write data key wraps the value with AES-256-GCM, and the data key itself is wrapped by a key held in a managed key service, bound to the org and identity. A vault maps to an [identity](/docs/identity/overview) and is referenced per session.

## Credential kinds

<ParamField path="env_var" type="credential">
  For CLIs, SDKs, and direct API calls that authenticate through an environment variable. Stored in the sandbox only as an **opaque placeholder**; the real value is substituted at **egress**, and **only for the bound destination `host`**. A request to any other host receives the inert placeholder, so the secret cannot be exfiltrated to an unintended endpoint.
</ParamField>

<ParamField path="mcp_oauth" type="credential">
  For MCP servers that use OAuth 2.0, keyed by `mcp_server_url`. Injected server-side when the agent connects; refreshed automatically when a `refresh` block is supplied.
</ParamField>

<ParamField path="static_bearer" type="credential">
  For MCP servers that accept a fixed bearer token (API key or PAT), keyed by `mcp_server_url`. No refresh needed.
</ParamField>

Secret fields (`token`, `access_token`, `refresh_token`, `client_secret`, `secret_value`) are **write-only** and never returned by the API. Reads return metadata only.

<Card title="Back to identity" icon="id-badge" href="/docs/identity/overview">
  How personas tie it all together.
</Card>
