Skip to content

firma_secret_provider (root module)

Modules

  • broker - Out-of-sandbox broker transport for the secret shim.
  • endpoint
  • gateway - Wire types and client transport for the secret-gateway control channel
  • non_empty - Non-empty wrapper types.
  • spec - Secret-provider integration specs: how to classify provider commands and
  • store - In-memory secret dictionary for the firma run secret broker.

Out-of-sandbox broker transport for the secret shim.

The shim binary connects to the broker over a Unix domain socket (Unix) or TCP loopback (Windows) and sends a newline-terminated JSON request. The broker dispatches each request to its handler, which applies config matching and authorization to decide whether the real CLI runs out of the sandbox; when it does, the handler intercepts the output, and the broker writes back a newline-terminated JSON response containing base64-encoded, stream-tagged output chunks in observed capture order.

Protocol (one round-trip per connection):

shim → {"bin":"bws","args":["secret","get","abc"]}\n
broker → {"type":"executed","output":[{"stream":"stdout","data":"<base64>"}],"status":{"type":"exited","code":0}}\n
broker → {"type":"rejected","error":"<reason>"}\n

Layout mirrors the secret gateway’s: shared wire types live here, [client] is the shim-side connector, and [server] is the broker-side listener.

Size caps: process output is base64-encoded onto the wire, so a configured response cap of N bytes admits at most roughly 3N/4 bytes of total raw output. JSON framing and per-chunk stream metadata reduce the usable payload, especially when output is split into many small chunks. The [client] and [server] defaults are aligned so both sides agree on the largest request and response lines; tune them together.

Wire types and client transport for the secret-gateway control channel between firma-sidecar’s HTTP MITM intercept and firma-run’s broker.

The broker owns the persistent secret store; the Sidecar mints placeholders locally (see [crate::SecretPlaceholder]) so it can substitute them synchronously into the response body it forwards, then reports the mapping to the broker via [PushRequest]. Later, when the Sidecar needs to inject the real value into an outbound request, it looks placeholders back up via [ResolveRequest]. [Str] borrows from the request buffer where possible to avoid copying secret material.

This module defines the wire types themselves; [client] implements the transport that speaks the protocol over a [firma_config_schema::gateway::GatewayConfig]-tuned connection to a [crate::endpoint::client::ClientEndpoint], and [server] implements the broker-side listener that serves the same protocol from the shared [crate::store::SecretStore].

Non-empty wrapper types.

[NonEmptyStr] and [NonEmptyVec] push “at least one element/character” invariants into the type system, so callers and [serde] deserialization can’t construct an empty value and downstream matching logic never has to re-check for it.

Secret-provider integration specs: how to classify provider commands and extract secrets from provider output. Callers own placeholder minting and persistence for extracted values.

A provider is either a CLI vault tool (stdout intercepted by firma-run’s broker via a stdio shim) or an HTTP vault (response bodies intercepted by firma-sidecar’s MITM path). The two shapes are deliberately distinct enum variants rather than one struct with optional fields, so a config mixing CLI-only and HTTP-only attributes (e.g. an HTTP entry carrying a binary_name) cannot be represented.

In-memory secret dictionary for the firma run secret broker.

The broker keeps real secret values out of the agent: each value is stored under an opaque placeholder token and the agent only ever sees the token. This module owns the dictionary — placeholder ↔ secret value, populated by intercept and consulted for rehydration ([SecretStore::resolve]).

The streaming rewrite and the out-of-sandbox broker transport live in other modules; this one is deliberately transport-free so it can be unit-tested in isolation. See docs/architecture/secrets-interception.md.