---
title: Vaults
description: Storing the credentials the broker uses on an agent's behalf.
sidebar:
  order: 3
---

When an agent calls a tool on an MCP server, something has to authenticate that call. That credential lives in a vault. The broker reads it and attaches it; the model never sees it, and neither does the session log.

## Creating a vault

```ts
const vault = await subako.vaults.create({ display_name: "Support tools" });
```

A vault is a container. What matters is what goes in it.

```ts
await subako.vaults.update(vault.id, { display_name: "Support tools (prod)" });
await subako.vaults.delete(vault.id);
const vaults = await subako.vaults.list();
```

## Adding a credential

```ts
await subako.vaults.addCredential(vault.id, {
	display_name: "Tickets MCP",
	protocol: "mcp",
	target: "https://mcp.example.com/tickets",
	payload: { auth_scheme: "static_bearer", token: process.env["TICKETS_TOKEN"]! },
});
```

| Prop | Type | Default | Description |
| - | - | - | - |
| `protocol` | `"mcp"` | - | What the credential authenticates. The server owns this vocabulary, so more may appear without an SDK release. |
| `target` | `string` | - | What the broker matches a tool call against. For `mcp`, the server's exact URL. |
| `display_name` | `string` | - | For people reading the list, not for matching. |
| `payload` | `CredentialPayloadBody` | - | The secret itself. Two shapes, below. |

**`target` has to match the `url` in the agent's MCP grant exactly.** That is how the broker finds the credential for a call. A mismatch is not an error you get at publish time — it is a tool call that fails at runtime, which is a slower thing to debug.

## The two payload shapes

```ts
// A token you hold
{ auth_scheme: "static_bearer", token: "..." }

// OAuth, where the broker can refresh
{ auth_scheme: "oauth", access_token: "...", expires_at: "2026-10-01T00:00:00Z", refresh: { ... } }
```

`static_bearer` is sent as it stands. `oauth` lets the broker refresh the token when it lapses, so a long session does not die with the credential.

## Listing and removing

```ts
const credentials = await subako.vaults.listCredentials(vault.id, { limit: 50 });
await subako.vaults.deleteCredential(vault.id, credentialId);
```

The listing describes the credentials. It does not return the secrets — those went in and do not come back out.

## Giving a session access

A vault is not attached to an agent. It is named when the session is created, so the same agent can run against different credentials:

```ts
const created = await subako.sessions.create({
	agent_id: agentId,
	vault_ids: [vault.id],
});
```

That is what lets one agent serve several customers, or the same agent run against staging and production without republishing.
