Vault backend

Sagewai's Sealed Identity layer can store profiles in HashiCorp Vault instead of the built-in encrypted JSON file. When you use the Vault backend, Sagewai acts as a Vault consumer: it reads credentials at runtime and relies on Vault for audit logging, leasing, and rotation.

When to use Vault

Choose the Vault backend if:

  • You already run Vault and do not want a second credential store.
  • A multi-host worker fleet needs a consistent profile view across machines.
  • You need Vault's lease, audit, and rotation primitives rather than Sagewai's.

If none of these apply, the built-in backend is the right choice.

Setup

  1. Install the optional dependency:

    pip install sagewai[vault]
    
  2. Add the Vault block to ~/.sagewai/admin-state.json:

    {
      "sealed": {
        "vault": {
          "enabled": true,
          "addr": "https://vault.your-org.internal:8200",
          "namespace": null,
          "auth_method": "approle",
          "auth_config": {
            "role_id": "00000000-0000-0000-0000-000000000000",
            "secret_id_env": "VAULT_APPROLE_SECRET_ID"
          },
          "mount": "kv",
          "tls_verify": true,
          "audit_request_id_capture": true
        }
      }
    }
    
  3. Export the AppRole secret in your worker environment:

    export VAULT_APPROLE_SECRET_ID=...
    
  4. Restart the admin server. The status page at /sealed/status will show a Vault card.

Auth methods

Token

The simplest option. Set auth_method: "token" and supply one of:

  • auth_config.token: a literal token value. Not recommended — it is written to admin-state.
  • auth_config.token_env: the name of an environment variable that holds the token. Recommended.

AppRole

Long-lived role_id paired with a short-lived secret_id. Set auth_method: "approle":

  • auth_config.role_id: literal role ID.
  • auth_config.secret_id_env: environment variable name. Sagewai never reads the secret ID from admin-state.

Kubernetes service account

For workers running inside a Kubernetes cluster. Set auth_method: "kubernetes":

  • auth_config.role: the Vault role configured for the service account.
  • auth_config.token_path: path to the projected SA token. Defaults to the standard injected location.

URI scheme

Profile references use vault://:

  • vault://kv/sagewai/acme-prod — explicit mount plus path
  • vault://secret/team-billing/staging — different mount

To make Vault the default for bare profile IDs, set sealed.default_scheme: "vault" in admin-state.

Migration from the built-in backend

Copy profiles one at a time with this pipeline:

sagewai admin sealed profiles get acme-prod --full \
  | jq '{name, description, owner, tags, env, secrets, allowed_workflows}' \
  | jq -c \
  | xargs -I {} vault kv put kv/sagewai/acme-prod {}

After copying, update all cascade refs from acme-prod (built-in) to vault://kv/sagewai/acme-prod.

Troubleshooting

  • 403 Forbidden on read. The AppRole secret_id expired (Vault's default lease is 24 hours). Renew it through your Vault rotation process.
  • Connection refused. Verify addr matches what Vault is listening on. On macOS, Vault must bind to 0.0.0.0, not 127.0.0.1.
  • Namespace not found. This is a Vault Enterprise feature. Confirm the namespace value matches an existing namespace.
  • Profiles list empty. Check the configured mount and path_prefix. Vault returns an empty list when no items exist at the prefix.

Audit cross-walk

Every secret.decrypted event records details.vault_request_id. Use that ID to find the matching entry in Vault's audit log — useful for compliance reviews. To disable the cross-reference, set sealed.vault.audit_request_id_capture: false.