cellos-broker-vault 0.5.1

HashiCorp Vault SecretBroker for CellOS — runtime-leased credentials per cell with auto-revoke on teardown.
Documentation

cellos-broker-vault

SecretBroker that fetches secrets from HashiCorp Vault via AppRole authentication.

What it is

Implements cellos_core::ports::SecretBroker. For each secretRef, the broker:

  1. POSTs {addr}/v1/auth/approle/login with the configured role_id and secret_id.
  2. GETs {addr}/v1/{kv_mount}/data/{kv_path_prefix}/{key} with the freshly-issued X-Vault-Token.
  3. Extracts data.data.{key} from the Vault KV v2 envelope and returns it as a SecretView.

By default every resolve performs a fresh AppRole login. Combined with a use_limit=1 or short-ttl AppRole policy, this yields one-shot tokens with no persistent state in the supervisor.

When the cell spec opts into runtimeLeasedBroker, the broker performs a single login per cell, reuses the cached token for on-demand fetches, and actively calls /v1/auth/token/revoke-self in revoke_for_cell — the only broker in the family that implements meaningful runtime revocation.

Selected in cellos-supervisor::composition::build_secret_broker when CELLOS_BROKER=vault-approle.

What it does NOT do:

  • It does not refresh tokens proactively. For classic env delivery, the child process holds the materialized secret already; revocation depends on short Vault TTLs.
  • It does not perform any Vault auth method other than AppRole.

Public API surface

Symbol Purpose
VaultAppRoleBroker The broker.
VaultAppRoleBroker::from_env() Construct from the env vars below; returns Err if required vars are missing or malformed.
VaultAppRoleBroker::has_runtime_lease(cell_id) Test helper: cached lease for a given cell.
VaultAppRoleBroker::runtime_lease_count() Observability helper: number of cached leases.
DEFAULT_REQUEST_TIMEOUT_MS / DEFAULT_CONNECT_TIMEOUT_MS 15 s / 10 s defaults; overridable.
resolve_timeout_ms(env_var, default_ms) Pure helper.

Source: src/lib.rs.

Configuration

Selection:

CELLOS_BROKER=vault-approle

Required:

Env var Description
CELLOS_VAULT_ADDR Vault server URL, e.g. https://vault.example.com
CELLOS_VAULT_ROLE_ID AppRole role_id
CELLOS_VAULT_SECRET_ID AppRole secret_id

Optional:

Env var Default Description
CELLOS_VAULT_KV_MOUNT secret KV v2 mount name
CELLOS_VAULT_KV_PATH_PREFIX (none) Prefix prepended to every key (e.g. cellos/prod)
CELLOS_VAULT_NAMESPACE (none) Vault Enterprise namespace (X-Vault-Namespace)
CELLOS_CA_BUNDLE (none) PEM CA bundle path for private Vault PKI
CELLOS_VAULT_TIMEOUT_MS 15 000 Request timeout
CELLOS_VAULT_CONNECT_TIMEOUT_MS 10 000 Connect timeout

HTTP_PROXY / HTTPS_PROXY / NO_PROXY are honoured automatically by reqwest. The client is never built without explicit timeouts.

Examples

authority:
  secretRefs:
    - DB_PASSWORD
export CELLOS_BROKER=vault-approle
export CELLOS_VAULT_ADDR=https://vault.example.com
export CELLOS_VAULT_ROLE_ID=...
export CELLOS_VAULT_SECRET_ID=...
export CELLOS_VAULT_KV_PATH_PREFIX=cellos/prod
cellos-supervisor --spec cell.yaml
# Reads secret/data/cellos/prod/DB_PASSWORD

Testing

cargo test -p cellos-broker-vault

Related crates

  • cellos-broker-env / cellos-broker-file — env / file delivery.
  • cellos-broker-oidc — GitHub Actions OIDC alternative.
  • cellos-supervisor — selects this broker via CELLOS_BROKER.
  • cellos-core — defines the SecretBroker port and SecretView.

Operator note: tracing

reqwest can emit X-Vault-Token (and the AppRole login response with auth.client_token) at TRACE level. Every CellOS binary that initializes tracing wires cellos_core::observability::redacted_filter into the fmt layer so RUST_LOG=reqwest=trace cannot leak Vault tokens to stderr. Do not bypass this filter in custom tracing-init paths.

ADRs

  • ADR-0007 — RBAC and secretRef admission contract; AppRole is the canonical machine-to-machine path.