Credential vaults
Agents often need credentials: a token for your CRM’s MCP server, a database password for a script, an API key for an internal service. A vault holds those secrets so agents can use them without ever seeing them. The model only ever sees a secret’s name; Syntic substitutes the value at the moment a tool, MCP server or environment needs it.
Secret values are write-only. You can set and replace them, but no endpoint, Console page or log ever returns them.
When to use a vault
- An agent definition lists an MCP server that needs a bearer token.
- Code in an environment must call a service that needs an API key.
- Different customers’ agents need different credentials for the same tool: one vault per customer, same agent definition.
Never put credentials in agent instructions, tool descriptions, metadata or environment env_vars; those are readable through the API and may reach the model.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/vaults | Create a vault. |
GET | /v1/vaults | List vaults. |
GET | /v1/vaults/{vault_id} | Read a vault and its secrets’ names (never values). |
PATCH | /v1/vaults/{vault_id} | Rename or change the description. |
DELETE | /v1/vaults/{vault_id} | Delete a vault and all its secrets. |
PUT | /v1/vaults/{vault_id}/secrets/{name} | Create or replace a secret. |
DELETE | /v1/vaults/{vault_id}/secrets/{name} | Delete a secret. |
Base URL https://app.syntic.ai/v1 (the paths above already include /v1). Authenticate with a private key and send syntic-beta: agents-2026-11-01. Creating vaults and writing secrets requires a key whose creator is an Administrator or Owner. Any key in the workspace may list vaults and read secret names, so agents can be configured by developers without exposing values.
The vault object
{
"id": "vlt_01JC2B4D6F8H0K2M4P6R",
"type": "vault",
"name": "acme-prod",
"description": "Production credentials for the Acme integration.",
"secrets": [
{
"name": "crm-token",
"hint": "…9f2a",
"allowed_destinations": ["mcp.example.com"],
"created_at": "2026-11-03T09:00:00Z",
"updated_at": "2026-11-05T09:00:00Z",
"last_used_at": "2026-11-05T10:00:03Z"
}
],
"created_at": "2026-11-03T09:00:00Z"
}| Secret field | Description |
|---|---|
name | 1 to 64 characters: letters, digits, - and _. This is how agents and configs refer to it. |
hint | The last four characters, so you can tell which value is stored. Omitted for values shorter than 16 characters. |
allowed_destinations | Host names the secret may be sent to. A tool or MCP call to any other host that would use this secret is refused. Empty means no restriction (not recommended). |
last_used_at | When a tool last used it. |
Store a secret
PUT /v1/vaults/{vault_id}/secrets/{name}
| Field | Required | Notes |
|---|---|---|
value | Yes | The secret, up to 16 KB. |
allowed_destinations | No | Host names, with *. wildcards. |
Response 200 OK with the secret’s metadata (no value).
curl -sS -X PUT https://app.syntic.ai/v1/vaults/vlt_01JC2B4D6F8H0K2M4P6R/secrets/crm-token \
-H "Authorization: Bearer $SYNTIC_ADMIN_SCOPE_KEY" \
-H "Content-Type: application/json" \
-H "syntic-beta: agents-2026-11-01" \
-d "{\"value\": \"$CRM_TOKEN\", \"allowed_destinations\": [\"mcp.example.com\"]}"In these examples SYNTIC_ADMIN_SCOPE_KEY is an ordinary private sk_live_ key created by an Administrator or Owner. It is not an Admin API key; those manage the organization and cannot call workspace resources.
Referring to secrets
Add the vault to the agent’s vault_ids, then refer to secrets by name:
| Where | How |
|---|---|
| MCP server on an agent | "vault_secret": "crm-token". Sent as Authorization: Bearer <value> to that server only. |
| Environment variable in an environment | "vault_secrets": [{ "vault_id": "vlt_...", "name": "CRM_TOKEN" }]. Injected when the container starts. |
| Built-in HTTP tools | "auth": { "vault_secret": "crm-token", "header": "X-Api-Key" } on the tool entry. |
If two attached vaults hold the same name, the vault listed first in vault_ids wins.
How values are protected
- Values are encrypted with a per-organization key before storage and decrypted only inside the component that sends them on. With customer-managed keys, that key lives in your cloud KMS.
- Values are never placed in the model’s context, traces, session events, logs or error messages. If a tool’s output happens to contain a stored secret value, it is replaced with
[secret:crm-token]before the model sees it. - Every create, replace, delete and use writes an audit event:
vault.secret_written,vault.secret_deleted,vault.secret_used(with the destination host, sampled to one per secret per minute).
Errors
Errors use the error envelope.
| Status | type | code | When |
|---|---|---|---|
| 400 | invalid_request | invalid_secret_name | Name has disallowed characters. |
| 400 | invalid_request | secret_too_large | Value over 16 KB. |
| 403 | permission | role_required | Write attempted with a key whose creator is not an Administrator or Owner. |
| 404 | not_found | vault_not_found, secret_not_found | No such vault or secret. |
| 409 | invalid_request | vault_in_use | Delete while an agent or environment references the vault. |
At run time, a refused destination shows up as a failed tool step with the error secret_destination_not_allowed; the agent sees only that the call failed.
Limits
| Limit | Value |
|---|---|
| Vaults per workspace | 100 |
| Secrets per vault | 100 |
| Value size | 16 KB |
Vaults are free.
Build notes for the platform team
- Reuse the existing credentials encryption helpers and vault module; add a
workspace_idand theallowed_destinationscheck in the outbound path. - The redaction pass on tool output runs before output is stored in traces, not only before the model call.