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

# Agent Vault

> Store agent-owned credentials and use them by name in a browser or workspace.

The vault stores credentials an agent needs for its own work, such as a website
login or an API token for a service without a connector. A person supplies a
secret through a one-time drop link or an operator adds it in the dashboard. The
agent then refers to it by name when using its browser or workspace.
The vault API and agent management tools return metadata, never stored values.

Vault entries belong to an **agent**, not an individual conversation. The agent
can use an entry across its conversations when its available tools permit it.
Infrastructure credentials, such as model keys and connector logins, remain in
their separate settings and are not exposed through the vault.

## Add a secret as an operator

The vault requires PostgreSQL and `MESH_AGENT_MASTER_KEY`. From the agent's page,
open **Vault → Manage vault** and choose **Add secret**.

1. Give the entry a name the agent can refer to, such as `SENTRY_TOKEN`.
2. Add a short description explaining its intended use. Names and descriptions
   are visible to the model, so keep the secret value out of both.
3. Paste the value into the secret field and save.
4. Tell the agent which entry to use, without pasting the value into chat.

Names must start with a letter and contain only letters, digits, or underscores,
up to 64 characters. Descriptions are limited to 500 characters and values to
32 KiB. Both the operator save and drop-link submission trim surrounding
whitespace. Saving the same name replaces the value; the vault does not keep value history.

The page shows the source, saved time, and last-use time. It cannot reveal a saved
value. Remove an entry on that page or ask the agent to forget it; deletion is
permanent and does not revoke the credential at its external provider.

## Provide a secret through a drop link

When an agent needs a missing credential, it can call `vault_request` with a name
and description, then share a one-time URL in the conversation. Open the link,
check which agent and entry it names, paste the value, and choose **Hand it over**.
You do not need a Formation account or sign-in. The value goes straight into the vault;
it is not added to the conversation as a message. Formation queues a run so the agent
can confirm receipt in the same thread. If it is already working there, that
confirmation waits until the conversation is idle.

Drop links require `PUBLIC_URL` as well as the vault's database and master key.
`vault_request` is offered only in a turn with a durable conversation and anchor
message. It returns `url` and `expires_at`, and refuses a name already in the
vault unless the agent sets `replace: true`. The agent should check `vault_list`
before requesting a value.

Each link accepts a value once, for **15 minutes**. After that, **Send me a new
link** remains available until **72 hours after that link was issued**, subject
to a limit of **five renewals per request**. The agent posts the replacement in
the original conversation; the expired page does not display it. Each replacement
gets fresh expiry times. Opening or previewing a link does not consume it.

An expired page can request another replacement if delivery failed, within those
limits. Repeated requests while its renewal is pending or running have no extra
effect. Once any link in the request is used, its other links stop working. Used
or revoked links, expired links with no renewals left, and links older than
72 hours show the same invalid-link page; ask the agent for a new request in the
conversation.

Treat the URL as a credential: anyone holding it can submit a value for that
entry, although they cannot read a stored value. Operators can inspect outstanding
requests under **Open drop links** on the Vault page and revoke individual links.
The list shows metadata and expiry times, never the token.

## How an agent uses a secret

The agent can manage entries with:

| Tool | Behavior |
| - | - |
| `vault_list` | List names, descriptions, source, timestamps, and last use. |
| `vault_request` | Request a value through a one-time drop link; see the requirements above. |
| `vault_forget` | Permanently delete the named entry. |

There is no tool that returns a plaintext value. The agent passes an entry name
to one of these supported use sites:

| Use site | Agent request | Where the value is used |
| - | - | - |
| Browser | `browser_act` with `action: "fill_secret"`, a fresh element `ref`, and `secret: "SENTRY_TOKEN"` | Formation opens the value and types it into the selected input. |
| Workspace | `workspace_exec` with `secrets: ["SENTRY_TOKEN"]` | The command receives `MESH_SECRET_SENTRY_TOKEN` in its environment. |

The corresponding browser or workspace capability must already be available to
the agent. The vault does not enable either one. Workspace calls may request up
to 16 entries, using their exact stored names; environment variable suffixes are
uppercased. Formation refuses a command if two requested names map to the same
environment variable, such as `token` and `TOKEN`; request only one of them.

For example, a command can read `MESH_SECRET_SENTRY_TOKEN` from its environment
instead of embedding a token in a command argument. Formation redacts exact delivered
values from workspace output and withdraws the per-command entries from its grant
file when the command returns. Rotation takes effect on the next use; forgetting
or replacing an entry does not tear down a running sandbox.

## What the vault protects

Values are encrypted at rest in their own table. Formation derives a vault-specific
key from the installation master key using HKDF-SHA256, then uses authenticated
encryption bound to the agent and entry name. Vault rows have no plaintext-derived
hint. Public drop lookups use a hash of the token. Renewal workers also keep an
encrypted token so a retry can recover the same URL and expiry. Key rotation and
verification cover both vault entries and these renewal tokens; follow
[secrets and recovery](/secrets-and-recovery.md) for backup and key handling.

Using an entry by reference avoids putting its value directly into the tool's
model-visible arguments and stored tool result. It is still delivered to the
browser page or command that needs it. A website can expose what is typed, and a
command can transform or send an environment value. Exact-value redaction is not
a security boundary against code with access to the secret. Only provide
credentials appropriate for the work and tools entrusted to that agent.

Browser observations can show visible input values or website content after a
fill. Avoid treating the vault as a guarantee that a website cannot reflect a
secret into an observation. Operator reads of the vault itself never return it.

## Current boundaries

Plaintext reveal, TOTP generation, and secret injection into arbitrary MCP tool
arguments are unavailable. Earlier design notes described these as possible
extensions; they are not setup steps or supported tools.

## Operator API

These routes require access to the agent; writes also require write permission.
All responses use `Cache-Control: no-store`.

| Method and route | Result |
| - | - |
| `GET /api/agents/{slug}/vault` | Entry metadata in an `entries` array. |
| `PUT /api/agents/{slug}/vault/{name}` | Add or replace `{ "value": "…", "description": "…" }`; return metadata. |
| `DELETE /api/agents/{slug}/vault/{name}` | Permanently remove an entry; return 204. |
| `GET /api/agents/{slug}/vault/drops` | Outstanding drop metadata in a `drops` array. |
| `DELETE /api/agents/{slug}/vault/drops/{id}` | Revoke a link; return 204. |

The public drop endpoints use the link token as authorization and need no operator
session. See the [operator API reference](/operator-api.md#agent-vault) for their
contracts, validation, and error responses. The implementation is in
`internal/vault`, `internal/admin/vault.go`, `internal/admin/vault_drops.go`,
`internal/webbrowser`, and `tools/workspace`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.