Skip to main content
The credential vault lets a sandbox use a secret (API key, token, database password) without the secret value ever entering the VM. The value lives server-side in OpenBao and is injected at the egress proxy on outbound requests to the destinations you scope it to. Inside the VM, the env var holds only the placeholder string declaw:vault-managed. This is the stronger sibling of Environment Secrets. With env secrets, the value is present in the VM (just masked in audit logs and excluded from get_info()) — any process inside the sandbox can read it from its environment. With the vault, the value is never delivered to the VM at all: a compromised agent that dumps /proc, reads the environment, or exfiltrates the process table sees only the placeholder. The credential is resolved and applied at the proxy layer between the VM and the upstream service. Secrets are stored and referenced by name — there is no team or environment to set up. The value is written to the vault backend (OpenBao) and is never returned by any API after creation.

Using a vault secret in a sandbox

Pass a map of env var name → secret name at sandbox create time.
A vault ref resolves by secret namedemo-token looks up the secret named demo-token. The --vault-ref CLI flag is repeatable.
Two requirements for injection to actually happen. A vault ref always hides the value (the VM gets the placeholder), but injection only fires when both of these hold:
  1. The scope’s domain_regex must use the ~ regex prefix. An unprefixed entry is an exact hostname match, so a regex literal like ^postman-echo\.com$ would never equal the real host and nothing would be injected. Write ~^postman-echo\.com$.
  2. The target host must be in the sandbox’s network allow_out. Injection happens at the L7 egress proxy. A host that is not in the network policy bypasses the proxy entirely, so there is nothing to inject into.
Miss either one and the value stays hidden but no credential is attached to the outbound request.

What the agent sees

The env var inside the VM holds the placeholder — never the real value:
An outbound request to a scoped host carries the injected credential (here, bearer injection sets the Authorization header). The agent issues a plain request; the proxy attaches the header before forwarding:
A request to a host not covered by a scope carries nothing — no credential is leaked to unintended destinations:
The credential never existed anywhere inside the VM. It was fetched worker-side from OpenBao and applied at the proxy. Rotating the secret value takes effect on the next outbound request — no sandbox restart required.

Storing a secret

A secret stores a value plus one or more scopes that tell the egress proxy which destination host the value is for and how to inject it. There are two ways to supply the scopes. The value is write-only: it is written to OpenBao and is never returned by any API after creation — not by create, list, or get.
The vault is a cloud-mode feature and requires an authenticated API key. All operations are scoped to your account.

(a) From a provider preset

Name a built-in provider with provider= and the preset supplies the domain regex, injection type, and any required static headers — you only paste the value. The secret name defaults to the provider key when omitted. Browse the catalog with list_presets / declaw vault presets.

(b) With explicit scopes

For a custom destination, provide the scopes yourself. domain_regex uses the vault’s ~ prefix to mark a case-insensitive regex match against the request host. The proxy anchors every scope automatically (wrapping it as ^(?:…)$), so a pattern like api.example.com matches that host only and never an attacker-suffixed look-alike (api.example.com.evil.com) — you may still write explicit ^…$ anchors, but you no longer have to. injection_type defaults to bearer; an optional rotation_interval_days enables a rotation policy.

List, rotate, and delete secrets

list returns metadata only (id, name, scopes, rotation status) — never the value. rotate replaces the stored value while leaving the scopes unchanged. Running sandboxes pick up the rotated value on their next outbound request (a short-lived TTL cache at the proxy) — no sandbox restart is required. delete removes both the metadata and the stored value.
A secret with rotation_interval_days > 0 is flagged rotation_due in list output once that many days pass since it was last rotated (or created). This is an advisory signal — rotation is not automatic; call rotate to clear it.

Update a secret’s scopes

update_scopes replaces a secret’s injection scopes in place — point it at a new destination or change the injection format — without re-supplying the value. It’s the in-place alternative to delete-and-recreate; running sandboxes pick up the new scopes on their next outbound request.

Injection types

A secret’s scope declares how the proxy presents it to the allowed destination. HTTP types inject into the TLS-intercepted request; socket types complete an authentication handshake transparently so the agent connects with no password.

Scope fields

A scope is one per-destination injection rule on a secret. The proxy matches a request’s host against domain_regex and injects the value per injection_type. All of the static fields below are applied at the egress proxy after the security scan, so they never appear in the request the agent issued — they let one scope express a provider’s full contract (e.g. Anthropic’s required anthropic-version header) without a new injection mechanism. A single secret may carry multiple scopes — one secret can be injected differently for different destination hosts.

Provider presets

Declaw ships a built-in catalog of ~39 first-party provider templates (OpenAI, Anthropic, Gemini, Bedrock, Cohere, Mistral, Hugging Face, Pinecone, LangSmith, ElevenLabs, Tavily, and more) so you can store a credential by naming the provider and pasting the value — no hand-written domain regex or header (see Storing a secret). The preset expands server-side into the correct scopes at create time; the worker only ever sees the resulting injection specs. Browse the live catalog:

BYO secret-store connectors

A secret can hold a connector descriptor instead of a literal value — a pointer to your existing secret store. At injection time the worker fetches the real value from that store (cached, per the revocation TTL), so an upstream rotation is picked up automatically on the next cache miss. Implemented connectors: aws_sm · aws_ssm · gcp_sm · azure_kv · vault / openbao · infisical · doppler · k8s · 1password (Connect) · conjur · akeyless The descriptor names the provider and the path to the value; the literal credential never lives in declaw.
Secret values live in OpenBao, never in declaw’s Postgres. The control plane stores only metadata — the secret’s id, name, scopes, and rotation status. The value is written to the vault backend and is fetched worker-side and injected at the proxy. It never enters the control-plane database and is never returned by the API after creation.
Trust boundary and the cert-pinned limitation. Vault HTTP injection rides declaw’s TLS interception at the egress proxy — the same edge proxy used for PII and injection scanning (see Network Policies). The proxy terminates TLS, attaches the credential, and re-originates to the upstream. This means an upstream that certificate-pins (rejects the proxy’s CA) cannot have a credential injected, because the proxy can’t sit in the TLS path. For socket brokers, the agent↔proxy leg is always cleartext within the sandbox’s own network namespace (where the proxy is the only gateway); the proxy↔upstream leg can opt into TLS (set tls: true in the secret value) — smtp upgrades via STARTTLS, redis and mongodb negotiate TLS at connect time, and postgres and mysql upgrade in-protocol — so a database that mandates TLS on the wire is brokered too.