OpenFirma docs highlights for LLM-based retrieval:

- Transport security for Authority <-> Sidecar gRPC is documented in docs/security/transport.md.
- Sidecar should use an https:// `[sidecar.authority].url` with `[sidecar.authority].ca_cert_path` for CA verification.
- Advanced Authority routing can set `[sidecar.authority].connect_addr` or `firma sidecar --authority-connect-addr` to dial an exact physical `SocketAddr` while preserving the logical URL's HTTP authority, TLS SNI, and certificate identity. Precedence is CLI, config, then URL/DNS; remote plaintext validation follows the physical destination.
- Sidecar PSK authentication is configured with `[sidecar.authority.credentials]` in `firma.toml`.
- Authority credentials require workspace_id, sidecar_id, and exactly one of pre_shared_key_env or pre_shared_key_path.
- When Sidecar credentials are absent, OpenFirma sends no credentials and remains compatible with the local Mini Authority.
- V1.1 mTLS uses `sidecar.authority.tls_client_cert_path` + `sidecar.authority.tls_client_key_path` on Sidecar and `authority.mtls_client_ca_cert_path` + `authority.authorized_clients_path` on Authority.
- Authority allow-list file supports [[authorized]] entries with cn/san identity fields; unknown client identities are rejected at TLS handshake.
- V1.1 revocation model for mTLS clients is allow-list driven (`authorized_clients` updates) plus cert rotation/expiry; CRL/OCSP revocation checks are not performed by the TLS verifier in this release.
- `firma run --authority local` is a loopback dev-mode convenience path (`http://`) and is not an mTLS transport-hardening path.
- Registered agent identity is `[sidecar.authority].agent_id`, an `agt_` TypeID copied from FirmaTeam registration for remote agents; new local scaffolds generate one backed by UUIDv7. `[run].profile` is only the local execution profile. `firma run` fails before backend, Authority, Sidecar, or capability startup when the ID is missing or malformed.
- `firma config --agent-id <agent-id>` validates the `agt_` TypeID. Non-interactive `agent-remote` setup requires it, while a new `agent-local` config generates one when omitted. Existing valid IDs are preserved.
- `firma run` propagates the registered `agt_` TypeID through capability mint/refresh, autostart metadata/config, run-audit records, `FIRMA_AGENT_ID`, and `x-firma-agent`. It preserves the execution profile separately through `FIRMA_RUN_PROFILE`, `x-firma-profile`, runtime selection, and mediator `profile`.
- A plain http:// `[sidecar.authority].url` is only allowed by default for loopback hosts; remote plaintext requires explicit `[sidecar.authority].allow_insecure_remote_authority = true`.
- TLS mismatch on Authority stream keeps sidecar fail-closed (no policy bundle readiness).
- On WSL hosts, implicit `firma run` backend selection uses `wsl2` compatibility mode instead of Linux `bwrap`.
- The managed `vscode` profile is not supported with the `wsl2` backend; `firma run` rejects the combination before launch because the Windows VS Code shim would run on the host instead of following the WSL guest launch path.
- Non-structural (proxy-only) backends (macOS `vz`, WSL2 `wsl2`) fail closed by default; pass `--allow-non-structural` or set `run.allow_non_structural = true` in firma.toml to opt into proxy-only compatibility mode.
- Linux `bwrap` provides the current default structural confinement path. `firecracker` is planned. Default `vz` and `wsl2` are proxy-based compatibility paths that can be bypassed by non-cooperative clients.
- macOS strategy: prioritize VZ guest-based structural parity first; treat Endpoint Security Framework (ESF) as selected host hardening/audit, not as standalone sidecar-only egress or DNS confinement.
- Experimental macOS structural mode: set FIRMA_RUN_VZ_STRUCTURAL_NETWORK=1 on macOS vz backend for sandbox-exec network-deny mode; the loopback re-allow is port-scoped to the Firma proxy bridge + DNS stub, so other host loopback services are denied; network_confinement=macos_sandbox_network_deny; sandbox-exec denials are not delivered to the Sidecar, so there is no per-attempt signed loopback audit on macOS; experimental until macOS E2E assertions pass on hardware.
- Loopback egress guard (Linux bwrap): a seccomp user-notify filter traps the agent's connect(2) and blocks direct connections to any loopback address (127.0.0.0/8, ::1, IPv4-mapped) except the proxy bridge and DNS stub ports, returning EACCES; this catches direct sockets that bypass HTTP_PROXY. Each block is reported to the Sidecar and recorded as a signed DENY audit event with action class `network.loopback` and reason `loopback blocked`, visible in `firma monitor`. Fails open with a warning if seccomp user-notify is unavailable; the proxy bridge and DNS stub are exempt so Firma's own loopback traffic is unaffected. `network.loopback` is an out-of-band, audit-only action class (not in ActionClassRegistry::v0_1, never Cedar-evaluated).
- firma run audit channel: out-of-band enforcement facts flow from firma run to the Sidecar over a per-run control socket (FIRMA_RUN_AUDIT_SOCK, run-audit.sock in the sidecar marker dir) as newline-delimited JSON firma_core::RunAuditMessage { session_id, agent_id, event } where event is a tagged RunAuditEvent enum. The Sidecar owns the mapping from each variant to (action_class, decision, deny_reason, resource) and signs the result (impl From<&RunAuditMessage> for AuditPayload). Loopback block (RunAuditEvent::LoopbackBlocked) is the first variant; the channel is reused by future producers rather than adding new sockets.
- Rust audit-log consumers can deserialize Sidecar JSONL with `firma_audit_schema::ExecutionEvent`; `firma-audit-schema` is the behavior-free representation used by the Sidecar itself and includes the numeric `Decision` enum plus base64 signature encoding.
- Experimental macOS VZ guest mode: set FIRMA_RUN_VZ_GUEST=1 plus FIRMA_RUN_VZ_GUEST_RUNNER, FIRMA_RUN_VZ_GUEST_KERNEL, FIRMA_RUN_VZ_GUEST_INITRD, and FIRMA_RUN_VZ_GUEST_ROOTFS absolute paths. firma run validates artifact paths and runner executability, emits macos_vz_guest proof metadata, writes vz-guest-launch.json, and spawns the runner with --launch-contract. The operator-provided runner must implement the Apple Virtualization.framework lifecycle and in-guest bridge-only egress.
- EnforcementProof.network_confinement distinguishes linux_network_namespace (bwrap), macos_sandbox_network_deny (sandbox-exec structural), macos_vz_guest (VZ guest runner contract), kvm_micro_vm (planned), proxy_only (current vz/wsl2 defaults).
- Capability token non-exposure applies to capabilities staged for the Sidecar by the automatic `firma run` flow. `firma run --capability-file` exports capability material into the wrapped process environment, so do not use that flag when token non-exposure is required.
- Capability `token_id` values use canonical `ctok_<26-character TypeID suffix>` strings backed by RFC UUID v7 values. This namespace does not apply to local-exec HITL approval tokens.
- Sandbox identity: `firma run` generates one `sbx_...` sandbox ID and reuses it for runtime state, child propagation, Sidecar metadata, local-exec binding, and audit. `FIRMA_RUN_SANDBOX_ID` is reserved for Firma-managed child propagation and cannot override a run ID. Discover full IDs with `firma sidecar status --json`, run `metadata.toml`, or audit events.
- Capability auto-refresh: `firma run` runs a background thread that re-calls the Authority `IssueCapability` RPC before the per-session token expires (default TTL 15m, renew at `run.profiles.<id>.capability.refresh_ratio`=0.60 of remaining lifetime, no later than `run.profiles.<id>.capability.grace`="30s" before expiry) reusing the launch session identity/credentials (no interactive re-auth) and atomically rewrites `$XDG_RUNTIME_DIR/firma/capabilities/<sandbox_id>.toml`. The Sidecar watches that file and atomically hot-swaps its in-memory `CapabilityMap` (arc-swap; hot path stays lock-free). Fail-closed: Authority-unreachable retries with backoff and never serves a stale token (the token expires and requests are denied until refresh succeeds); a file that fails verification is not swapped in. Every refresh re-evaluates Authority issuance policy and revocation, so there is intentionally no hard session-lifetime cap. Config durations and byte sizes use unit-bearing strings (for example `authority.max_ttl`="1h" and `sidecar.interceptor.max_request_body_size`="4 MiB"). Authority TTL environment overrides are `FIRMA_AUTHORITY_MAX_TTL` and `FIRMA_AUTHORITY_BUNDLE_TTL` and use the same duration syntax. Config resource paths resolve relative to their containing `firma.toml`; runtime/state paths, endpoints, sandbox targets, WAL/session/revocation/CA directories, home masks, executable allowlists, and CLI paths retain their documented semantics.
- Sidecar templates selected for `firma run` local autostart must be unified, sectioned `firma.toml` documents containing `[sidecar]`. Flat, missing-section, and unknown-field templates fail before local components start or run-marker artifacts are created. The template is inherited from the resolved `firma.toml` (`--config` / `FIRMA_CONFIG` / discovery), else a generated minimal config.
- Config timeout, deadline, wait, retry, and session-lifetime controls use compact unit-bearing syntax and are strictly non-zero at deserialization. This covers secret-gateway connection/operation timeouts; Run command-mediator timeout/HITL wait; Sidecar Authority connect/reconnect controls; interceptor drain and CONNECT relay setup/session limits; connector default/per-host timeouts; and local-exec retry interval. TTL, retention, grace, and clock-skew durations have field-specific validation. Authority `max_ttl` and `bundle_ttl` are strictly non-zero because zero would create immediately expired capabilities or immediately stale policy bundles. Capability refresh grace, revocation readiness grace, MITM certificate TTL, capability clock-skew tolerance, and local-exec token TTL are not mechanically treated as timeouts. Zero clock skew means strict expiry checking; zero revocation readiness grace means immediate readiness.
- The `firma-protobuf` 0.2 `IssueCapabilityResponse.decision` field is authoritative. OpenFirma validates ALLOW, DENY, and PENDING_APPROVAL response shapes and fails closed on inconsistent or unspecified outcomes. Budget ceilings, consumed-budget metadata, remaining-budget Cedar context, and local-exec budget references are intentionally absent until the numeric model is redesigned without floating-point values.
- FirmaTeam capability verification: set `run.profiles.<id>.capability.public_key_path` (or the run default) to FirmaTeam's exported raw 32-byte Ed25519 workspace public key. This key overrides `[sidecar.authority].public_key_path` for the run, verifies every `IssueCapability` PASETO response locally, enables per-session mint/refresh management, and is written into the autostarted Sidecar config. Missing or unreadable keys, non-32-byte files, malformed or expired tokens, and signature mismatches fail closed. Relative file-config paths resolve against the containing `firma.toml`; equivalent CLI paths remain verbatim. An explicit `--capability-file` uses the signed capability TOML representation and exports that capability into the wrapped process environment.
- Runtime logs for non-structural backends use "backend compatibility proof" with `mode=proxy_only enforced=false` instead of "backend network enforcement proof".
- The managed seccomp baseline does not deny `filesystem.delete`: seccomp cannot encode path scopes, so workspace-scoped delete is enforced structurally by the bwrap read-only rootfs plus read-write workspace/runtime-home mounts (deletes outside the workspace fail on the read-only mount). This lets development tools like Cargo run.
- The built-in `copilot` profile secures the GitHub Copilot CLI: its seccomp baseline permits `filesystem.delete` (Copilot's `~/.copilot/*.db` SQLite session store), it sets CA trust mode `AppendSystemRoots` (system roots + firma-ca, fixing `UnknownIssuer` on real GitHub TLS), and it passes through `GITHUB_TOKEN`/`GH_TOKEN`/`GH_COPILOT_TOKEN`. `firma config --profile copilot` writes the `copilot` mapping plus `sidecar.interceptor.https_mitm.bypass_hosts` for `github.com`, `api.github.com`, `uploads.github.com`. `firma run -- copilot` auto-selects the profile from the command word, but `gh copilot` needs explicit `--profile copilot`. Validated on Linux `bwrap` only.
- The built-in `vscode` profile supports `firma run --profile vscode -- code .` and `firma run -- code .`. It creates a per-run `code` shim that forces `--wait`, `--new-window`, project-local isolated `--user-data-dir` and `--extensions-dir` under `.firma/vscode`, a writable per-run desktop runtime directory, and `--no-sandbox` for VS Code's inner Chromium sandbox; it seeds the isolated profile to prefer VS Code's GitHub device-code sign-in flow; it sets CA trust mode `AppendSystemRoots`; Linux bwrap closes idle sandbox-to-Sidecar adapter relays after two minutes to avoid bridge slot exhaustion during extension installs; and `firma config --profile vscode` writes a CONNECT-level `vscode` mapping for VS Code core, marketplace, sync, Microsoft account, GitHub.com, hosted GitHub Enterprise (`*.ghe.com`), GitHub social sign-in through Google or Apple, and the hosts from GitHub's Copilot allowlist (`*.githubcopilot.com` plus the plan-scoped `*.individual.githubcopilot.com`, `*.business.githubcopilot.com`, and `*.enterprise.githubcopilot.com`, along with the Copilot usage-report and voice-feature hosts), so Copilot chat, completions, telemetry, usage reporting, and voice features work without extra configuration. Add separate mappings for other embedded agents such as OpenAI/Codex or Anthropic/Claude. Integrated terminal command governance is not part of this v1 profile.
- Native GitHub HTTPS git enforcement uses the `github` mapping on `github.com`: `GET /*/*.git/info/refs` and `POST /*/*.git/git-upload-pack` map to `code.read`; `POST /*/*.git/git-receive-pack` maps to `code.write`, with delete ref updates promoted to `code.destructive`.
- GitHub branch/ref policy fields are optional Cedar context attributes: `git_provider`, `git_owner`, `git_repo`, `git_ref`, `git_ref_type`, and `git_operation` (`read`, `write`, `delete`).
- The Cedar `Firma::Resource` entity carries `id` (the full `<host><path>` display string) plus optional `host` and `path` attributes, so policies can match on host directly (e.g. `resource has host && resource.host == "169.254.169.254"`); guard optional-attribute access with `resource has host`. Evaluated identically at Authority issuance, Sidecar enforcement, and offline `firma policy test`.
- Native GitHub git enforcement and git credential injection require HTTPS MITM for `github.com`; CONNECT-only mode cannot see `git-receive-pack`, cannot enforce branch/ref policy, and cannot attach credentials to the inner request.
- GitHub PAT injection for HTTPS git supports `transform = "github_pat_basic"`, rendering `Authorization: Basic base64("x-access-token:<token>")`; scope it exactly to `target_host = "github.com"` so it does not apply to `api.github.com`.
- `firma config` reads existing target `firma.toml` values as defaults; CLI flags override only supplied fields.
- Managed `firma sidecar start` lets Authority and Sidecar bind port `0`: it validates each child-published endpoint, then injects the dynamic Authority address into Sidecar. A fixed Authority port preserves the Sidecar's explicitly configured routing.
- Simultaneous Authority and Sidecar startup is safe. The Sidecar retries Authority policy and revocation streams with exponential backoff and remains fail-closed until stream hydration.
- `sidecar ready` is emitted only after the first policy bundle is applied and the revocation stream is ready. Cloud Run multi-container deployments should probe the Sidecar `/healthz` endpoint on port 9000 instead of adding a startup script that sequences Authority before Sidecar.
- Configuration resolution selects exactly one file: explicit `--config`, then `$FIRMA_CONFIG`, then the nearest `.firma/firma.toml` found by walking up from the current directory. OpenFirma never field-merges multiple configuration files, and a selected unreadable or invalid file fails closed instead of falling through. Omitted schema fields receive defaults. Authority applies its documented `FIRMA_AUTHORITY_*` overlays after loading `[authority]`; Sidecar has only its documented explicit CLI overlays. Run alone layers the built-in profile, `[run.defaults]`, the selected profile, and supplied CLI values. At each Run layer, present scalars and booleans replace, nested patches merge field-wise, present lists replace (`[]` clears), and maps merge by key (an empty table clears). `--print-effective-config` shows the result. See https://github.com/Firma-AI/openfirma/blob/main/docs/configuration.md#configuration-resolution.
- The unified `firma.toml` surface has `[authority]`, `[sidecar]`, and `[run]` sections and rejects unknown keys recursively, including nested tagged variants and every selected or unselected Run profile; dynamic labels remain open but their values are strict. Configure logs with `--log-filter` / `FIRMA_LOG_FILTER`; bundle freshness uses the Authority-advertised TTL; seccomp checksums are always verified.
- Run capability sources use tagged `capability.source`: `kind = "disabled"`, or `kind = "file"` with `path`. Executable launch policies are keyed by executable name under `executable_policies`, including `executable_policies.codex`.
- Sidecar-internal ABORT is distinct from DENY: DENY rejects request shape/token/scope/policy before execution; ABORT blocks an already-allowed in-flight call and leaves the capability token active.
- V1 ABORT reason codes are `CONNECTOR_TIMEOUT`, `CONNECTOR_FAILURE`, `CONNECTOR_INVALID_REQUEST`, and `CREDENTIAL_INJECTION_FAILED`; HTTP-facing interceptors return 504 with `{"aborted": true, "reason": "...", "detail": "..."}`.
- AARM R4 five-decision conformance: the policy engine can produce ALLOW (1), DENY (2), ABORT (3), MODIFY (4), STEP_UP (5), and DEFER (6) for each evaluated action. The wire contract lives in the `firma-protobuf` crate `firma.v1.EnforcementDecision` enum.
- AARM R2 session context conformance: the Cedar runtime context carries `action_count`, `deny_count`, `prior_action_classes` (bounded, deduped), and `last_resource` so policies can reason about what the agent has already attempted in the same session. The session-state store is configurable (`sidecar.constraint_enforcement.session_state_capacity`, default 8192) and supports a file-backed persistent backend (`sidecar.constraint_enforcement.session_state_backend = "persistent"`) so per-session context survives eviction and process restart. Admitted (Allow/Modify) actions carry a tamper-evident provenance chain anchor (`provenance`), a server-derived `thread_id`, and a `parent_action_id` linking to the prior admitted action — all surfaced in the audit event and covered by the ECDSA signature.
- Cedar natively emits only Allow/Deny; the three remediation outcomes are sourced from `@modify("redact_header:<name>")` / `@step_up("…")` / `@defer("<ms>")` annotations on `forbid` policies, lifted by a post-Cedar layer that reads `Response::diagnostics().reason()`. Precedence when several fire is `STEP_UP > DEFER > MODIFY`; a `forbid` without an annotation is a hard DENY; a `permit` carrying any remediation annotation, or a `forbid` carrying more than one, rejects the bundle at load time; malformed annotation values (non-numeric `@defer`, unknown `@modify` kind, empty value, zero duration) also reject the bundle so the operator gets an immediate, actionable error.
- MODIFY applies a structural transformation to the dispatch clone (V1 supports `redact_header:<name>`, case-insensitive header match) before forwarding; the original envelope is preserved for audit, and the applied transformation (e.g. `redacted_header:authorization`) is recorded in the audit `deny_reason`; STEP_UP blocks with `DenyReason::StepUpRequired`; DEFER blocks with `DenyReason::Deferred`. In monitor mode, DENY/MODIFY/STEP_UP/DEFER are overridden to PASSTHROUGH with the original reason prefixed `monitor_mode:`. Monitor mode is gated behind the `FIRMA_ALLOW_MONITOR_MODE=1` env var — without it, `mode = "monitor"` in config downgrades to `enforce` at startup with an error log (`firma run --monitor` sets the env var for its autostarted sidecar, so the CLI flag is itself the opt-in). PASSTHROUGH is serialized on the wire as ALLOW (1) with an empty `token_id`. `firma monitor --decision` accepts `allow`, `deny`, `passthrough`, `modify`, `step-up`, and `defer`.
- Composio governance uses the existing Sidecar boundary and strict HTTPS MITM for app.composio.dev and backend.composio.dev; it does not add Redis, another gateway, or a new network namespace.
- Supported hosted MCP, direct execution, and Tool Router requests are decoded into `composio://<toolkit>/<tool_slug>` logical resources using pinned local catalogs. Reviewed catalogs for Gmail, Google Calendar, and Slack (toolkit version `20260721_00`) plus Notion (toolkit version `20260730_00`), 335 tools in total, are compiled into the Sidecar and every slug carries a manually assigned canonical action class. Unknown or malformed execution shapes fail closed and catalog lookup never uses the network on the hot path. Direct execution requires the pinned toolkit version in the payload and denies `unpinned_tool` without one; the Tool Router session routes (`execute`, `execute_meta`) and hosted MCP JSON-RPC define no version field in Composio's API, so those routes rest on the pinned slug allowlist, though a version a client does attach is still checked. A stated version that differs from the pin is always denied. Composio API families the decoder does not recognize fail closed as `unsupported_route`: automatic file upload/download, session file mounts, the manual Tool Router `session/{id}/search` call (use the `COMPOSIO_SEARCH_TOOLS` meta-tool instead), inline custom tools (`attach`), triggers, and MCP server management.
- `COMPOSIO_MULTI_EXECUTE_TOOL` is atomic: every child is evaluated and audited, the original request dispatches once only when all children are admitted, and any blocking child causes zero upstream dispatches.
- Composio account-lifecycle writes (POST/PATCH/PUT/DELETE on the `connected_accounts` and `auth_configs` routes, POST — the only method Composio defines there — on the Tool Router session `link` route, plus PATCH/PUT/DELETE on a Tool Router `session/{id}` resource, under `/api/v3` and `/api/v3.1`) are governed as `account.permission.change` actions with `composio://composio/<slug>` resources instead of passing through; a non-POST method on the session `link` route is not a real Composio route and fails closed instead of being governed, so an agent cannot expand its own account surface without capability and Cedar evaluation. Session creation (POST to the Tool Router session collection) is governed as well — it binds the connected accounts later session calls execute within, so it decodes into one `COMPOSIO_CREATE_SESSION` action per selected account (at most 50 per request); a session update (PATCH/PUT on `session/{id}`) can rebind those accounts, so its `connected_accounts` selection decodes into per-account `COMPOSIO_UPDATE_SESSION` actions the same way, an explicit null selection clears and decodes unbound, and an unparsable update body fails closed; the Connect Link route decodes as `COMPOSIO_CREATE_CONNECTED_ACCOUNT` with no account selector; a session write selecting no accounts carries no `composio_account` context, so account-allowlist policies must also forbid session writes lacking the attribute; a POST to an existing `session/{id}` resource fails closed, and MCP-path DELETE teardown stays passthrough. GET/HEAD/OPTIONS on the `connected_accounts` and `auth_configs` routes are governed too, as `credential.read` actions with `composio://composio/COMPOSIO_LIST_CONNECTED_ACCOUNT`-style resources, because those responses disclose which integrations exist and how they authenticate. Other read-only discovery requests (`tools`, `toolkits`, Tool Router session reads, MCP streams) still pass through; governed requests carrying a query string are denied except those lifecycle reads, where a pagination cursor is allowed through and restored onto the dispatched request while the logical resource stays query-free; hosted MCP paths deny query strings on every method, and recognized routes enforce read-method allowlists (GET/HEAD/OPTIONS, plus DELETE for MCP teardown) so extension methods fail closed.
- Composio Cedar context includes `composio_toolkit`, `composio_tool_slug`, `composio_user_id`, `composio_account`, `composio_session_id`, `composio_batch_index`, and `composio_batch_size`. Signed audit events identify each tool through its canonical action class and `composio://<toolkit>/<tool_slug>` resource without changing the shared protobuf contract or recording credentials, raw arguments, request selectors, or provider response bodies.
- The secret gateway (`fsp_…` placeholder tokens) is a distinct mechanism from static credential injection: the Sidecar rehydrates outbound placeholders and masks inbound secret echoes via `firma-run`'s broker over `FIRMA_SECRET_GATEWAY_ADDR` (`unix://` or `tcp://` endpoint), and can also intercept configured HTTP vault responses (`[[sidecar.http_secret_providers]]`) to extract, placeholder-ize, and push newly seen secrets. All three paths are fail-closed: rehydration denies the whole request if any placeholder can't be resolved (never forwards a partially-substituted body), a `blocked_command` HTTP vault path is rejected before the connector is ever contacted (not dispatched then discarded), and a failed push to the broker aborts the response (`CREDENTIAL_INJECTION_FAILED`) rather than hand the agent an unresolvable placeholder. Invalid HTTP-provider matchers and HTTP providers configured without a gateway reject Sidecar startup.
- `firma run` `secret_providers` in `firma.toml` automates the gateway for its per-run Sidecar: `[run.defaults]` / `[run.profiles.<id>] secret_providers` entries are either a bare string naming a built-in CLI integration (e.g. `"bws"`, `"op"`) or a full table `{ type = "cli", binary_name, provider_id, credential_env_vars, matchers = [{type="sensitive_command"|"safe_command"|"blocked_command", argv, matcher, stripped_options, append_options}] }` or `{ type = "http", provider_id, host, matchers = [{type="sensitive_command"|"safe_command"|"blocked_command", path, matcher}] }`. CLI entries activate an in-sandbox shim via the `firma-run` broker; HTTP entries are mirrored into the synthesized `[sidecar].http_secret_providers`. Merge: defaults + active profile, later wins on `binary_name` (CLI) / `provider_id` (HTTP); unknown bare name fails closed; presence is authorization.
