AgentsCredential vaults

Credential vaults

⚠️
Preview — this feature is being built; the design below is the spec.

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

MethodPathPurpose
POST/v1/vaultsCreate a vault.
GET/v1/vaultsList 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 fieldDescription
name1 to 64 characters: letters, digits, - and _. This is how agents and configs refer to it.
hintThe last four characters, so you can tell which value is stored. Omitted for values shorter than 16 characters.
allowed_destinationsHost 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_atWhen a tool last used it.

Store a secret

PUT /v1/vaults/{vault_id}/secrets/{name}

FieldRequiredNotes
valueYesThe secret, up to 16 KB.
allowed_destinationsNoHost 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:

WhereHow
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.

StatustypecodeWhen
400invalid_requestinvalid_secret_nameName has disallowed characters.
400invalid_requestsecret_too_largeValue over 16 KB.
403permissionrole_requiredWrite attempted with a key whose creator is not an Administrator or Owner.
404not_foundvault_not_found, secret_not_foundNo such vault or secret.
409invalid_requestvault_in_useDelete 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

LimitValue
Vaults per workspace100
Secrets per vault100
Value size16 KB

Vaults are free.

Build notes for the platform team

  • Reuse the existing credentials encryption helpers and vault module; add a workspace_id and the allowed_destinations check in the outbound path.
  • The redaction pass on tool output runs before output is stored in traces, not only before the model call.
Was this page helpful?