> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getbifrost.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Secret Management

> Configure AWS Secrets Manager, GCP Secret Manager, or HashiCorp Vault in config.json using config_store.vault_store

<Note>
  Secret Management is an **enterprise-only** feature and requires the enterprise Bifrost image and a PostgreSQL config store.
</Note>

Connect an external secret manager so provider keys and other credentials are never stored in Bifrost's database. Configure `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](/enterprise/secret-management) for the full list of supported fields, access modes, and secret rotation.

***

## Configuration

<Tabs group="cj-vault-backend">
  <Tab title="AWS Secrets Manager">
    <Tabs group="cj-aws-auth">
      <Tab title="IAM role (recommended)">
        Attach an IAM role to your instance, ECS task, or EKS pod. No credentials needed in config - the AWS SDK inherits the role automatically.

        ```json theme={null}
        {
          "config_store": {
           ...
            "vault_store": {
              "enabled": true,
              "type": "aws-secrets-manager",
              "prefix": "bifrost",
              "access_mode": "read_only",
              "aws": {
                "region": "us-east-1"
              }
            }
          }
        }
        ```

        For EKS with IRSA, annotate your service account with the role ARN and leave credentials unset.
      </Tab>

      <Tab title="Static credentials">
        ```json theme={null}
        {
          "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.
      </Tab>

      <Tab title="Role assumption">
        Assume a cross-account or restricted IAM role on top of any existing credential source.

        ```json theme={null}
        {
          "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"
              }
            }
          }
        }
        ```
      </Tab>
    </Tabs>

    #### 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).                                      |

    **Minimum IAM policy** for `read_only`:

    ```json theme={null}
    {
      "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`.
  </Tab>

  <Tab title="GCP Secret Manager">
    <Tabs group="cj-gcp-auth">
      <Tab title="Workload Identity (recommended)">
        Bind a GCP service account to your GKE pod or Compute Engine instance and omit credentials - Application Default Credentials are used automatically.

        ```json theme={null}
        {
          "config_store": {
            "vault_store": {
              "enabled": true,
              "type": "gcp-secret-manager",
              "prefix": "bifrost",
              "access_mode": "read_only",
              "gcp": {
                "project_id": "my-gcp-project"
              }
            }
          }
        }
        ```
      </Tab>

      <Tab title="Service account key">
        ```json theme={null}
        {
          "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.
      </Tab>
    </Tabs>

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

    **Required IAM role:** `roles/secretmanager.secretAccessor` for `read_only`. For `read_and_write`, also grant `roles/secretmanager.secretCreator`, `roles/secretmanager.secretVersionAdder`, and `roles/secretmanager.secretDeleter`.
  </Tab>

  <Tab title="HashiCorp Vault">
    Bifrost uses the KV v2 secrets engine. Auth is resolved in order: explicit `token` → AppRole → ambient `VAULT_TOKEN` env var.

    <Tabs group="cj-hcp-auth">
      <Tab title="Token">
        ```json theme={null}
        {
          "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"
              }
            }
          }
        }
        ```
      </Tab>

      <Tab title="AppRole">
        ```json theme={null}
        {
          "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"
              }
            }
          }
        }
        ```
      </Tab>

      <Tab title="Ambient token">
        If `VAULT_TOKEN` is set in the environment and no `token` or AppRole is configured, Bifrost inherits it automatically. Useful with Vault Agent injection.

        ```json theme={null}
        {
          "config_store": {
            "vault_store": {
              "enabled": true,
              "type": "hashicorp-vault",
              "prefix": "bifrost",
              "access_mode": "read_only",
              "hashicorp": {
                "address": "https://vault.internal:8200"
              }
            }
          }
        }
        ```
      </Tab>
    </Tabs>

    #### 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`. |

    **Minimum Vault policy** for `read_only`:

    ```hcl theme={null}
    path "secret/data/bifrost/*" {
      capabilities = ["read"]
    }
    path "secret/metadata/bifrost/*" {
      capabilities = ["list"]
    }
    ```

    Add `create`, `update`, and `delete` on both paths for `read_and_write`.
  </Tab>
</Tabs>

***

## Common fields

These apply regardless of backend:

| Field         | Required | Description                                                                                                                         |
| ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `enabled`     | Yes      | Enable vault integration.                                                                                                           |
| `type`        | Yes      | Backend: `aws-secrets-manager`, `gcp-secret-manager`, or `hashicorp-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. |

***

## Using vault references

Once configured, any secret field accepts a `vault.<path>` reference:

```json theme={null}
{
  "providers": {
    "openai": {
      "keys": [
        {
          "models": ["gpt-4o", "gpt-4o-mini"],
          "value": "vault.bifrost/providers/openai/key"
        }
      ]
    }
  }
}
```

***

## Full example

```json theme={null}
{
  "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"
        }
      ]
    }
  }
}
```
