Secret Management is an enterprise-only feature and requires the enterprise Bifrost image and a PostgreSQL config store.
vault_store under config_store in config.json.
Once connected, any secret field in config.json accepts a vault.<path> reference in place of a plaintext value or env.* reference. See Secret Management for the full list of supported fields, access modes, and secret rotation.
Configuration
- AWS Secrets Manager
- GCP Secret Manager
- HashiCorp Vault
- Azure Key Vault
- IAM role (recommended)
- Static credentials
- Role assumption
Attach an IAM role to your instance, ECS task, or EKS pod. No credentials needed in config - the AWS SDK inherits the role automatically.For EKS with IRSA, annotate your service account with the role ARN and leave credentials unset.
{
"config_store": {
...
"vault_store": {
"enabled": true,
"type": "aws-secrets-manager",
"prefix": "bifrost",
"access_mode": "read_only",
"aws": {
"region": "us-east-1"
}
}
}
}
{
"config_store": {
"vault_store": {
"enabled": true,
"type": "aws-secrets-manager",
"prefix": "bifrost",
"access_mode": "read_only",
"aws": {
"region": "us-east-1",
"access_key_id": "env.AWS_ACCESS_KEY_ID",
"secret_access_key": "env.AWS_SECRET_ACCESS_KEY"
}
}
}
}
access_key_id and secret_access_key must be set together.Assume a cross-account or restricted IAM role on top of any existing credential source.
{
"config_store": {
"vault_store": {
"enabled": true,
"type": "aws-secrets-manager",
"prefix": "bifrost",
"access_mode": "read_only",
"aws": {
"region": "us-east-1",
"role_arn": "arn:aws:iam::123456789012:role/BifrostSecretsReader"
}
}
}
}
AWS fields
| Field | Required | Description |
|---|---|---|
region | No | AWS region (e.g. us-east-1). Falls back to AWS_DEFAULT_REGION or instance metadata if unset. |
access_key_id | No | Required when not using IAM roles. Must be set with secret_access_key. |
secret_access_key | No | Must be set with access_key_id. |
session_token | No | For STS-issued temporary credentials. |
role_arn | No | IAM role to assume via STS. |
kms_key_id | No | KMS key for encrypting new secrets (read_and_write only). |
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": "*"
}
]
}
secretsmanager:CreateSecret, secretsmanager:PutSecretValue, and secretsmanager:DeleteSecret for read_and_write.- Workload Identity (recommended)
- Service account key
Bind a GCP service account to your GKE pod or Compute Engine instance and omit credentials - Application Default Credentials are used automatically.
{
"config_store": {
"vault_store": {
"enabled": true,
"type": "gcp-secret-manager",
"prefix": "bifrost",
"access_mode": "read_only",
"gcp": {
"project_id": "my-gcp-project"
}
}
}
}
{
"config_store": {
"vault_store": {
"enabled": true,
"type": "gcp-secret-manager",
"prefix": "bifrost",
"access_mode": "read_only",
"gcp": {
"project_id": "my-gcp-project",
"credentials_json": "env.GCP_CREDENTIALS_JSON"
}
}
}
}
credentials_json accepts a JSON string (the full key file contents) or a file path on disk.GCP fields
| Field | Required | Description |
|---|---|---|
project_id | Yes | GCP project containing your secrets. |
credentials_json | No | Service account key JSON string or file path. If omitted, Application Default Credentials are used. |
roles/secretmanager.secretAccessor for read_only. For read_and_write, also grant roles/secretmanager.secretCreator, roles/secretmanager.secretVersionAdder, and roles/secretmanager.secretDeleter.Bifrost uses the KV v2 secrets engine. Auth is resolved in order: explicit
Minimum Vault policy for Add
token → AppRole → Kubernetes auth → ambient VAULT_TOKEN env var.- Token
- AppRole
- Kubernetes
- Ambient token
{
"config_store": {
"vault_store": {
"enabled": true,
"type": "hashicorp-vault",
"prefix": "bifrost",
"access_mode": "read_only",
"hashicorp": {
"address": "https://vault.internal:8200",
"token": "env.VAULT_TOKEN"
}
}
}
}
{
"config_store": {
"vault_store": {
"enabled": true,
"type": "hashicorp-vault",
"prefix": "bifrost",
"access_mode": "read_only",
"hashicorp": {
"address": "https://vault.internal:8200",
"mount_path": "secret",
"role_id": "env.VAULT_ROLE_ID",
"secret_id": "env.VAULT_SECRET_ID"
}
}
}
}
Log in with the pod’s service account token through Vault’s Kubernetes auth method. See Secret Management for the Vault-side role setup.
kubernetes_role is the Vault role bound to Bifrost’s service account and namespace.{
"config_store": {
"vault_store": {
"enabled": true,
"type": "hashicorp-vault",
"prefix": "bifrost",
"access_mode": "read_only",
"hashicorp": {
"address": "https://vault.internal:8200",
"kubernetes_role": "bifrost",
"kubernetes_mount_path": "kubernetes"
}
}
}
}
If
VAULT_TOKEN is set in the environment and no token, AppRole, or Kubernetes role is configured, Bifrost inherits it automatically. Useful with Vault Agent injection.{
"config_store": {
"vault_store": {
"enabled": true,
"type": "hashicorp-vault",
"prefix": "bifrost",
"access_mode": "read_only",
"hashicorp": {
"address": "https://vault.internal:8200"
}
}
}
}
HashiCorp fields
| Field | Required | Description |
|---|---|---|
address | No | Vault server URL. Reads VAULT_ADDR env var if unset. |
token | No | Vault token. |
namespace | No | Vault namespace (HCP Vault / Vault Enterprise). |
mount_path | No | KV v2 mount path. Defaults to secret. |
role_id | No | AppRole role ID. Must be set together with secret_id. |
secret_id | No | AppRole secret ID. Must be set together with role_id. |
kubernetes_role | No | Vault role for Kubernetes auth. Setting it enables login with the pod’s service account token. |
kubernetes_mount_path | No | Mount path of the Kubernetes auth method, without the auth/ prefix. Defaults to kubernetes. |
kubernetes_token_path | No | Path to the service account token file. Defaults to /var/run/secrets/kubernetes.io/serviceaccount/token. |
read_only:path "secret/data/bifrost/*" {
capabilities = ["read"]
}
path "secret/metadata/bifrost/*" {
capabilities = ["list"]
}
create, update, and delete on both paths for read_and_write.With
Required role: Key Vault Secrets User for
client_id and client_secret set, Bifrost authenticates as that service principal. Otherwise it uses DefaultAzureCredential (Workload Identity, a managed identity, or AZURE_* environment variables). With Workload Identity, keep AZURE_CLIENT_SECRET out of the pod environment, since it takes precedence over the federated token. See Secret Management for the Azure-side setup.- Workload / managed identity (recommended)
- Service principal
{
"config_store": {
"vault_store": {
"enabled": true,
"type": "azure-key-vault",
"prefix": "bifrost",
"access_mode": "read_only",
"azure": {
"vault_url": "https://my-bifrost-kv.vault.azure.net"
}
}
}
}
{
"config_store": {
"vault_store": {
"enabled": true,
"type": "azure-key-vault",
"prefix": "bifrost",
"access_mode": "read_only",
"azure": {
"vault_url": "https://my-bifrost-kv.vault.azure.net",
"tenant_id": "env.AZURE_TENANT_ID",
"client_id": "env.AZURE_CLIENT_ID",
"client_secret": "env.AZURE_CLIENT_SECRET"
}
}
}
}
client_id and client_secret must be set together, and tenant_id is required with them.Azure fields
| Field | Required | Description |
|---|---|---|
vault_url | Yes | Key Vault URI, for example https://<vault-name>.vault.azure.net. Must be https. |
tenant_id | No | Microsoft Entra tenant ID. Required when client_id and client_secret are set. |
client_id | No | Service principal client ID. Must be set together with client_secret. |
client_secret | No | Service principal client secret. Must be set together with client_id. |
read_only, Key Vault Secrets Officer for read_and_write. With access policies, grant Get and List, plus Set, Delete, and Recover for read_and_write.Key Vault secret names allow only letters, digits, and -. Reference your own secrets by their exact name (vault.openai-api-key). A path containing /, _, or . is encoded to a different name, as described in Azure Key Vault secret names.Common fields
These apply regardless of backend:| Field | Required | Description |
|---|---|---|
enabled | Yes | Enable vault integration. |
type | Yes | Backend: aws-secrets-manager, gcp-secret-manager, hashicorp-vault, or azure-key-vault. |
prefix | No | Path prefix for Bifrost-managed secrets. Defaults to bifrost. |
access_mode | No | read_only (default) - resolve refs only. read_and_write - also auto-store plaintext values and delete owned secrets on removal. |
vault_store (for example token, kubernetes_role, vault_url, client_secret) accept a plain value or an env.<VAR> reference. A vault.<path> reference does not work here, because these fields are read before the vault is connected.
Using vault references
Once configured, any secret field accepts avault.<path> reference:
{
"providers": {
"openai": {
"keys": [
{
"models": ["gpt-4o", "gpt-4o-mini"],
"value": "vault.bifrost/providers/openai/key"
}
]
}
}
}
Full example
{
"config_store": {
"enabled": true,
"type": "postgres",
"config": {
"host": "env.PG_HOST",
"port": "5432",
"user": "env.PG_USER",
"password": "env.PG_PASSWORD",
"db_name": "bifrost",
"ssl_mode": "require"
},
"vault_store": {
"enabled": true,
"type": "aws-secrets-manager",
"prefix": "bifrost",
"access_mode": "read_and_write",
"aws": {
"region": "us-east-1"
}
}
},
"providers": {
"openai": {
"keys": [
{
"models": ["gpt-4o", "gpt-4o-mini"],
"value": "vault.bifrost/providers/openai/key"
}
]
},
"anthropic": {
"keys": [
{
"models": ["claude-opus-4-8", "claude-sonnet-4-6"],
"value": "vault.bifrost/providers/anthropic/key"
}
]
}
}
}

