Overview
By default, Bifrost stores provider API keys, virtual key values, and other credentials in its config database. Secret Management lets you keep those values in your own secret manager - Bifrost stores a reference and resolves the real value at runtime. Once connected, any secret field in Bifrost (provider keys, virtual key values, MCP auth headers, etc.) accepts avault.<path> reference alongside the existing env.<VAR> and plaintext options.
Secret Management is an Enterprise-only feature and requires a PostgreSQL config store.
Access modes
Setaccess_mode to control how much Bifrost interacts with your vault:
Start with
read_only if you want to manage secrets yourself. Use read_and_write if you want Bifrost to handle it - useful when migrating existing plaintext keys, since Bifrost pushes the value to the vault on the next save.
Setup
Pick your backend and add avault_store block inside your existing config_store in config.json. Credential fields in this block accept a plain value or an env.<VAR> reference, but not a vault.<path> reference, since they are read before the vault is connected.
- AWS Secrets Manager
- GCP Secret Manager
- HashiCorp Vault
- Azure Key Vault
- IAM role (recommended)
- Static credentials
- Role assumption
Attach an IAM role to your EC2 instance, ECS task, or EKS pod. No credentials needed in config - the SDK inherits the role automatically. For EKS with IRSA, annotate your service account with the role ARN and leave credentials unset.
AWS fields
Minimum IAM policy for
read_only:secretsmanager:CreateSecret, secretsmanager:PutSecretValue, and secretsmanager:DeleteSecret for read_and_write.Using vault references
Any secret field in Bifrost that supportsenv.<VAR> also supports vault.<path>. This covers provider keys, virtual key values, MCP auth headers, plugin credentials, observability tokens, and more. Type the reference directly in the dashboard or set it in config.json.

config.json:
Fragment references
If your secret manager holds a JSON object with multiple keys, usevault.<path>#<key> to extract a single field.
For example, if prod/shared-keys contains:
Fragment references are never auto-deleted by Bifrost in
read_and_write mode, because the secret is externally managed and may be shared with other services.Azure Key Vault secret names
Key Vault secret names only allow letters, digits, and-, and are case-insensitive. Bifrost maps a reference path to a secret name like this:
- A path that is already a valid name is used as-is.
vault.openai-api-keyreads the secret namedopenai-api-key. Use this form to reference secrets you created yourself. - Any other path is encoded.
/becomes-s,_becomes-u,.becomes-d,-becomes-h, and an uppercase letter becomes-cfollowed by the lowercase letter. For example,vault.bifrost/providers/openai/keyreads the secretbifrost-sproviders-sopenai-skey.
read_and_write mode always use the encoded form, because their paths look like <prefix>/<table>/<id>/.... Encoded names never collide with each other. A secret you create yourself can only clash with one if you give it an encoded-looking name such as bifrost-s..., so avoid that pattern. An encoded name longer than 127 characters is rejected.
Fragment references work the same way: vault.shared-keys#openai_api_key reads the JSON secret shared-keys and returns its openai_api_key field.
Key Vault always soft-deletes. When Bifrost removes a secret it owns, the secret stays recoverable for the vault’s retention period and its name stays reserved. If Bifrost later writes to the same name, it recovers the deleted secret first and then writes the new value, which is why
read_and_write needs the Recover permission.Rotating secrets
Update the value in your secret manager - no Bifrost restart needed. Bifrost checks for updated secrets every hour in the background and picks up the new value automatically. To apply a rotation immediately, callPOST /api/vault/flush-cache. The endpoint requires a management bearer token and, in a clustered deployment, broadcasts the flush to all peers automatically.
Full details in the API reference.
Troubleshooting
Bifrost fails to start with “vault: ping failed” The backend is unreachable or credentials are invalid. Check network connectivity, verify the IAM role / token has read permissions on the configured prefix, and confirm the region / address / project ID / vault URL are correct. Bifrost fails to start with “vault: hashicorp kubernetes login” The Kubernetes login was rejected or the token file could not be read. Confirm the role inkubernetes_role exists under the right mount (vault read auth/kubernetes/role/<name>), that bound_service_account_names and bound_service_account_namespaces match the pod’s service account, and that the token file exists at kubernetes_token_path.
Bifrost fails to start with “vault: azure ping: DefaultAzureCredential: failed to acquire a token”
No credential in the chain could get a token. With Workload Identity, check that the pod carries the azure.workload.identity/use: "true" label (kubectl get pod <pod> -o yaml should show AZURE_FEDERATED_TOKEN_FILE), that the service account annotation holds the identity’s client ID, and that the federated credential’s subject is exactly system:serviceaccount:<namespace>:<service-account>. Also make sure AZURE_CLIENT_SECRET is not set in the pod (see the warning in the Azure tab).
Bifrost fails to start with “vault: azure ping” and a 403
The identity authenticated but cannot list secrets. Check that it has Key Vault Secrets User (or the List access policy) on the vault and that the vault’s network rules allow Bifrost’s egress.
Azure reference resolves to “secret not found”
The reference path was encoded to a different name than you expected. Reference your own secrets by their exact Key Vault name (vault.<secret-name>), with no /, _, or . in the path. See Azure Key Vault secret names.
Secret field is empty after save
The reference was saved but the backend returned nothing. Verify the secret exists at that exact path and the credentials have GetSecretValue / secretAccessor / read / Key Vault Get permission on it.
New values aren’t being pushed to the vault
access_mode must be read_and_write. The default read_only mode never writes to the backend.
Old value still in use after rotation
Flush the cache via POST /api/vault/flush-cache. If the issue persists, confirm the new version is active in the backend and not still pending.
“vault: not enabled” from the flush-cache endpoint
vault_store.enabled is false or the block is missing from config.json. Fix the config and restart.
Next steps
- Audit Logs - use vault-backed keys for HMAC audit log signing
- Clustering - cache flushes broadcast to all cluster peers automatically
- AWS deployment guide - set up IRSA for keyless Secrets Manager access
- GCP deployment guide - set up Workload Identity for keyless Secret Manager access
- Azure deployment guide - set up AKS Workload Identity for keyless Key Vault access

