Skip to main content

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 a vault.<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

Set access_mode to control how much Bifrost interacts with your vault:
ModeWhat Bifrost does
read_only (default)Resolves vault.<path> references. Never writes to or deletes from the backend.
read_and_writeAlso auto-stores plaintext values you save via the dashboard or API, and deletes owned secrets when you remove an entity.
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 a vault_store block inside your existing config_store in config.json.

AWS fields

FieldRequiredDescription
regionNoAWS region (e.g. us-east-1). Falls back to AWS_DEFAULT_REGION or instance metadata if unset.
access_key_idNoRequired when not using IAM roles. Must be set with secret_access_key.
secret_access_keyNoMust be set with access_key_id.
session_tokenNoFor STS-issued temporary credentials.
role_arnNoIAM role to assume via STS.
kms_key_idNoKMS key for encrypting new secrets (read_and_write only).
Minimum IAM policy for read_only:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "secretsmanager:GetSecretValue",
      "Resource": "arn:aws:secretsmanager:us-east-1:*:secret:bifrost/*"
    },
    {
      "Effect": "Allow",
      "Action": "secretsmanager:ListSecrets",
      "Resource": "*"
    }
  ]
}
Add secretsmanager:CreateSecret, secretsmanager:PutSecretValue, and secretsmanager:DeleteSecret for read_and_write.

Using vault references

Any secret field in Bifrost that supports env.<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. Provider key field showing vault reference badge For example, a provider key in config.json:
{
  "providers": {
    "openai": {
      "keys": [
        {
          "models": ["gpt-4o", "gpt-4o-mini"],
          "value": "vault.bifrost/providers/openai/key"
        }
      ]
    }
  }
}

Fragment references

If your secret manager holds a JSON object with multiple keys, use vault.<path>#<key> to extract a single field. For example, if prod/shared-keys contains:
{
  "openai_api_key": "sk-...",
  "anthropic_api_key": "sk-ant-..."
}
You can reference each key independently:
vault.prod/shared-keys#openai_api_key
vault.prod/shared-keys#anthropic_api_key
Both resolve to their respective values with a single backend fetch for the shared secret.
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.

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, call POST /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 are correct. 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 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