Secrets
Store, rotate, and grant tenant-level secret values that agents reference at tool-call time with {{secret.KEY}} placeholders
Secrets are encrypted, tenant-scoped values — API keys, tokens, passwords — that your agents reference indirectly through {{secret.KEY}} placeholders instead of pasting the raw value into a tool configuration.
The plaintext is encrypted at rest the moment you save it, is never returned by any read endpoint (only metadata flows out), and is decrypted only at the instant a tool call needs it — and only for agents you have explicitly granted. Manage them from the Secrets page in the dashboard.
Secret vs. integration credential — An integration credential (on a tenant integration config) authenticates a whole connected service like Slack or Jira. A secret is a standalone value you reference yourself inside a tool parameter — use it when a tool needs a key that isn't owned by one of the built-in integrations.
Creating a secret
A secret has a stable key, a value, an optional description, and a sensitivity tier.
| Field | Notes |
|---|---|
| Key | Reference name, unique per tenant (e.g. STRIPE_API_KEY). This is what you put inside {{secret.…}}. Keys are immutable — you can't rename a key, because agent definitions reference it by name and a rename would silently break them. |
| Value | The plaintext. Encrypted at rest immediately; the first revision is created and published atomically. |
| Sensitivity | Defaults to STANDARD. See Sensitivity tiers. |
| Description | Optional. Shown to operators and, for allowlisted secrets, surfaced to the model so it can pick the right credential (see Per-step allowlist). |
Referencing a secret: the {{secret.KEY}} placeholder
Put {{secret.KEY}} anywhere a tool parameter accepts a value — for example a header Authorization: Bearer {{secret.STRIPE_API_KEY}}. At execution time the resolver swaps the placeholder for the decrypted value just before the call is dispatched; the plaintext never enters the agent definition, the conversation, or the logs.
Where resolution works
Secret resolution runs across every tool kind:
| Tool kind | Resolves {{secret.KEY}} in |
|---|---|
| API tools | URL, headers, query, and body templates, plus the integration config they bind to |
| Code / SQL / NoSQL / messaging tools | Tool parameters |
| File-password tools | Tool parameters |
| MCP tools | Parameters passed to the MCP executor |
| Predefined tools | Tool parameters |
Revisions: rotate, publish, and roll back
Every secret keeps an append-only revision history. The value you see in use is the published revision.
- Rotate / publish a new value to create a new revision and make it the published one. The previous revisions stay in history.
- Roll back to point the published pointer at an earlier revision — useful if a rotation broke something.
Because the key is stable across revisions, rotating or rolling back never requires touching the agents that reference it.
Granting secrets to agents
A secret is not readable by every agent in the tenant. The resolver consults a per-agent grant list before it will substitute a secret into any tool call:
- Grant an agent to allow it to reference the secret.
- Revoke to remove that permission. After a revoke,
{{secret.KEY}}in that agent's tools stops resolving.
Browse a secret's grants to answer "who can decrypt this?" at a glance.
Per-step allowlist
On top of the per-agent grant, an individual agent step can carry a tighter allowlist, so a chatty step only reaches the credentials it actually needs. The resolver enforces grant ∩ allowlist:
null(no allowlist on the step) — falls back to grant-only behavior (legacy steps).- a set of keys — only those keys resolve, and only if the agent is also granted them.
- empty — denies every secret for that step.
When a step has a non-empty allowlist, the legal placeholders are surfaced to the model through an <available_secrets> system footer that lists each allowed {{secret.KEY}} and its description, so the model can choose the right one.
Sensitivity tiers
Each secret carries a sensitivity tier that drives the per-operation audit policy. Tiers are ordered by stringency; a credential subject to multiple regimes is tagged its strictest applicable label.
| Tier | For |
|---|---|
STANDARD | OAuth refresh tokens, generic API keys, webhook secrets (default) |
PII | Access to personally identifiable information (CRM rows, mailbox, calendar) |
PHI | Access to protected health information (HIPAA scope) |
FINANCIAL | Ability to initiate funds movement (payment processors, exchange APIs) |
REGULATED | Government / defense / critical-infrastructure scopes (FedRAMP, CMMC, ITAR-adjacent) |
STANDARD uses best-effort audit logging; PHI, FINANCIAL, and REGULATED use fail-closed audit writes. You can upgrade a secret's tier at any time, but downgrades are rejected so audit policy is never silently relaxed on a key that already saw stricter handling.
Managing secrets via the API
All routes are tenant-scoped under /v1/tenants/{tenant}/secrets. Read endpoints return metadata only — never the plaintext.
| Method & path | Purpose |
|---|---|
GET /secrets | List every non-deleted secret |
POST /secrets | Create a secret (publishes the first revision) |
GET /secrets/{secret} | Get one secret's metadata |
PATCH /secrets/{secret} | Update description or sensitivity |
DELETE /secrets/{secret} | Soft-delete |
POST /secrets/{secret}:publish | Rotate to a new value (new revision) |
POST /secrets/{secret}:rollback | Roll the published pointer to a prior revision |
GET /secrets/{secret}/revisions | List revision history |
GET /secrets/{secret}/revisions/{revision} | Get one revision's metadata |
GET /secrets/{secret}/grants | List agents granted access |
PUT /secrets/{secret}/grants/{grant} | Grant an agent access |
DELETE /secrets/{secret}/grants/{grant} | Revoke an agent's access |
Secrets are encrypted with a per-tenant data-encryption key. See Security for how credential encryption and the audit trail work.