Skip to content

Config reference

Every configuration field, extracted from the Go structs (field · JSON key · type · doc comment). See Operations for worked examples and the *.example.json files.

Broker / MCP config (config.json)

Config in internal/broker/engine.go

JSON key Type Description
listen string HTTP only: e.g. ":8443"
server_cert string TLS / mTLS for the HTTP frontend (not used by the MCP, which runs over stdio).
server_key string
client_ca string
ca_key string CAKey — LOCAL mode ONLY (in-process signing). When the Signer block is present, this field is ignored and the broker holds no CA key. ca_keys: per-group CA key overrides. "_default" overrides ca_key when present. See ca.CAKeyConfig for the three supported backends: "pem" (local key file), "akv" (Azure Key Vault) and "agent" (ssh-agent — YubiKey PIV / SoftHSM / TPM). Local mode only; ignored when Signer is set.
ca_keys map[string]ca.CAKeyConfig
signer *SignerClientConfig Signer, when present, externalises signing to a remote service (HTTP+mTLS). The broker no longer holds the CA key or the policy.
audit_log string Audit.
audit_key string Ed25519 seed (>=32 bytes)
audit_fail_mode string AuditFailMode governs what happens when the audit log cannot be written. "closed" (default): the audited action (ssh_execute, session open/exec, file transfer, k8s action) is denied with "audit unavailable" — the result is withheld. "open": log the error, count the metric, and return the result anyway (the pre-2.0 behaviour). Empty = "closed".
source_address string SourceAddress: broker egress IP/CIDR, used in local mode.
max_ttl_seconds int MaxTTLSeconds caps the maximum requestable TTL.
hosts_refresh_seconds int HostsRefreshSeconds: host-list reload interval from the signer. Remote mode only. Default: 300 (5 minutes).
revocation_poll_seconds int RevocationPollSeconds: how often the broker polls the signer's freeze set and force-closes matching live sessions (kill switch, #117). Remote mode only; this is the kill latency for an established session. Default: 10.
approval_via_elicitation bool ApprovalViaElicitation lets the stdio mcp-broker ask the human to approve a require_approval command IN THE MCP CLIENT (#118) instead of failing. It waives four-eyes (the requesting and approving human are the same), so the signer must also opt the broker's CN into self-approval (caller self_approve). Off by default; only meaningful for the interactive stdio frontend.
session_idle_seconds int Persistent session idle-close and maximum lifetime.
session_max_seconds int default 1800
session_recording_dir string SessionRecordingDir: directory for session recordings in ASCIIcast v2 format (.cast files). One file per session: .cast. Empty = recording disabled.
session_recording_strict bool SessionRecordingStrict makes recording failures fatal to the session instead of best-effort: if the .cast file cannot be opened, the session open fails, and if a recording event write fails the in-flight command aborts and the session is broken. Use when recording is a compliance control that must not fail open. Off by default (recording stays best-effort). Failures are always counted by recording_write_errors_total.
redact *redact.Config Redact enables secret redaction on this broker's persistent/outbound sinks: the audit log's free-text fields and session recordings. Present (even empty, "redact": {}) = built-in default patterns; absent = disabled (backward compatible). Redaction never touches the decision path — the signer and the certificate force-command always see the original command.
hosts map[string]HostConfig Hosts: used only in local mode (single-binary). In remote mode the host list is fetched from the signer via /v1/hosts and refreshed periodically.
command_policies map[string]signer.CommandPolicy CommandPolicies (local mode) is a named library of command policies, attachable to groups. GroupCommandPolicies maps a group name to the policy names that apply to its hosts; the reserved group "_default" applies to every host. A host's effective firewall is the composition of its inline command_policy and the policies of all its groups (additive union; deny wins).
group_command_policies map[string][]string
monitor_listen string MonitorListen: optional plain-HTTP monitoring listener serving /healthz (liveness) and /metrics (Prometheus text format), started by every frontend (broker, mcp-broker, mcp-broker-http). No authentication — bind to localhost or a private scrape interface. Empty = disabled.
file_transfer_max_bytes int FileTransferMaxBytes caps ssh_put_file content and ssh_get_file reads. Default 524288 (512 KiB). The HTTP MCP frontend additionally bounds the whole request body at 1 MiB, which base64-encoded content must fit.
oauth *OAuthConfig OAuth and ResourceURL are used only by the HTTP+OAuth frontend (cmd/mcp-broker-http); other frontends ignore them.
resource_url string ResourceURL is the canonical URL of this MCP server, used in the Protected Resource Metadata document (RFC 9728) and the WWW-Authenticate header.

Broker signer client (signer, remote mode)

SignerClientConfig in internal/broker/engine.go

JSON key Type Description
url string
client_cert string
client_key string
ca string
approval_wait_seconds int ApprovalWaitSeconds: maximum time the broker waits for a human approval to be resolved (202 response from the control plane). 0 = do not wait.

Broker OAuth (oauth, cmd/mcp-broker-http only)

OAuthConfig in internal/broker/engine.go

JSON key Type Description
issuer string Issuer is the OIDC provider URL (e.g. https://keycloak.example/realms/x).
audience string Audience is the expected value of the aud claim (this resource server).
required_scopes []string RequiredScopes are the scopes the token must carry to be accepted.
user_claim string UserClaim is the claim used as user identity (default "sub").
groups_claim string GroupsClaim is the claim that carries groups/roles to propagate to the signer. Empty = groups are not propagated (no per-user RBAC).
max_token_age_seconds int MaxTokenAgeSeconds limits the age of the token since issuance (iat claim). 0 = no limit (accepts any token within its exp). Recommended: 3600 (1h). M3: reduces the replay risk of leaked tokens within their exp window.
clock_skew_seconds int ClockSkewSeconds is the tolerance applied to the nbf and iat claims to absorb small clock differences between the IdP and this host. 0 selects a 1-minute default; a negative value disables the tolerance.

Broker host (hosts.<name>, local mode)

HostConfig in internal/broker/engine.go

JSON key Type Description
addr string
user string
principal string
host_key string
jump string
source_address string SourceAddress: per-host override of the global value for THIS host's cert. LOCAL mode only.
allow_sudo bool Elevation (NOPASSWD) — local mode.
allowed_sudo_users []string
allow_pty bool AllowPTY — local mode.
allow_file_transfer bool AllowFileTransfer authorises ssh_put_file / ssh_get_file on this host — local mode. Default false (secure by default). In remote mode this is defined by the signer in signer.json.
groups []string Groups lists the RBAC groups this host belongs to. When ca_keys are configured (multi-CA), the first matching group determines which CA signs certificates for this host. Also used for per-user RBAC in local mode.
allow_as_bastion bool AllowAsBastion authorises this host to be used as a ProxyJump hop (permit-port-forwarding in its cert). Local mode only; default false to match the remote-signer default-deny gate (ARCHITECTURE.md § routing). A host referenced as another host's Jump target is enabled automatically (see policyFromHosts), so existing jump chains keep working without per-host config.
command_policy signer.CommandPolicy CommandPolicy — local mode (AI-action firewall). In remote mode this is defined by the signer in signer.json.

CA key (ca_keys.<name>)

CAKeyConfig in internal/ca/loader.go

JSON key Type Description
type string "pem" | "akv" | "agent"
path string PEM backend.
socket string ssh-agent backend. Socket empty = $SSH_AUTH_SOCK. PublicKeyPath is the CA public key (.pub / authorized_keys line) used to pin which agent key is the CA.
public_key_path string
vault_url string Azure Key Vault backend.
key_name string
key_version string empty = latest version
tenant_id string AKV authentication overrides. When TenantID and ClientID are both empty, DefaultAzureCredential is used (recommended for production: picks up managed identity, workload identity, AZURE_* env vars, and Azure CLI).
client_id string
client_secret_env string ClientSecretEnv is the name of the environment variable holding the client secret. The secret is never stored in the config file.

Signer config (signer.json)

Config in cmd/signer/main.go

JSON key Type Description
listen string e.g. ":9443"
server_cert string mTLS: presents server_cert and requires clients signed by client_ca.
server_key string
client_ca string CA that signs authorised brokers
ca_key string CA key custody. ca_key: legacy path to a PEM CA key (backward compatible). ca_keys: per-group CA key overrides. The reserved key "_default" overrides ca_key when present. See CAKeyConfig for the three supported backends: "pem" (local key file — lab/dev, the signer logs a warning), "akv" (Azure Key Vault — the key never leaves the vault; RSA/EC only) and "agent" (ssh-agent — a YubiKey PIV slot / SoftHSM / TPM; the signer holds no key bytes and supports Ed25519).
ca_keys map[string]ca.CAKeyConfig
audit_log string Issuance audit log (independent of the broker).
audit_key string
audit_fail_mode string AuditFailMode governs what happens when the audit log cannot be written. "closed" (default): the action being audited is denied — no signed audit record, no certificate. "open": log the error, count the metric, and proceed (the pre-2.0 behaviour). Empty = "closed".
max_ttl_seconds int MaxTTLSeconds: global cap when the host policy does not set one.
auto_reload_seconds int AutoReloadSeconds: if > 0, the signer polls signer.json's mtime every N seconds and hot-reloads on change — same validated, atomic path as SIGHUP / POST /v1/reload, so a transiently-invalid in-progress save is rejected and the previous good state is kept. 0 or absent = disabled (default).
sign_rate_limit_per_min int SignRateLimitPerMin caps POST /v1/sign requests per authenticated client CN per minute (token bucket: burst up to the cap, continuous refill). Keyed on the mTLS peer CN — not on_behalf_of — and enforced before body parsing; excess requests get 429 with a Retry-After hint. Hot-reloadable. 0 or absent = disabled (backward compatible).
monitor_listen string MonitorListen: optional plain-HTTP monitoring listener serving /healthz (liveness) and /metrics (Prometheus text format). No authentication — bind to localhost or a private scrape interface. Empty = disabled.
redact *redact.Config Redact enables secret redaction on the signer's audit log free-text fields. Present (even empty, "redact": {}) = built-in default patterns; absent = disabled (backward compatible). The signer's audit carries request metadata rather than the raw command, but errors can embed user text — every persistent sink applies the same invariant.
state_db string StateDB: optional path to the SQLite state database that persists runtime grants, approve-and-learn waivers, and the kill-switch freeze set (#117) across restarts (pure-Go driver, no system dependency; WAL mode leaves state.db-wal/-shm sidecar files next to it). Empty or absent = in-memory only (previous behaviour: grants/waivers/freezes are lost on restart, kept across reloads); without it a /v1/freeze is refused unless opted in as volatile. If set and the database cannot be opened or migrated, the signer refuses to start (fail-closed). Production: /var/lib/infrabroker/signer/state.db.
max_grant_ttl_seconds int MaxGrantTTLSeconds: optional upper bound on a runtime grant's TTL (POST /v1/policy/hosts/{host}/grants). 0 or absent = no cap.
reload_callers []string ReloadCallers: client cert CNs authorised to invoke POST /v1/reload. Empty = HTTP endpoint disabled (403); SIGHUP still works locally.
trusted_forwarders []string TrustedForwarders: client cert CNs authorised to act on behalf of another broker (on_behalf_of field / X-On-Behalf-Of header). This is the control plane CN. Only these CNs may impersonate a broker for RBAC; any other CN sending on_behalf_of is rejected.
hosts signer.PolicyTable Hosts: issuance policy + connectivity per host. Single source of truth: the broker fetches addr/user/host_key/jump via GET /v1/hosts.
callers signer.CallerTable Callers: group-based RBAC. Maps broker mTLS cert CN → allowed groups. A non-empty table is authoritative and default-deny (v2.0.0): a CN absent from it sees and signs NO hosts. An unlisted CN inherits a reserved "_default" entry if present, else the zero policy (no groups). Add "_default" with groups to grant unlisted CNs a baseline. An empty/absent table configures no RBAC and leaves every caller unrestricted. A present CN can only see and sign hosts whose groups field intersects allowed_groups.
command_policies map[string]signer.CommandPolicy CommandPolicies is a named library of command policies, attachable to groups. GroupCommandPolicies maps a group name to the policy names that apply to its hosts; the reserved group "_default" applies to every host. A host's effective firewall is the composition of its inline command_policy and the policies of all its groups (additive union; deny wins).
group_command_policies map[string][]string
kubernetes *K8sConfig Kubernetes is the optional Kubernetes target: a parallel map of clusters, each with its own default-deny ActionPolicy, ServiceAccount bindings, and a minter credential (token_file) whose RBAC is only create on serviceaccounts/token. Absent = SSH-only signer (backward compatible).
envelope_key string EnvelopeKey is the path to the 32-byte Ed25519 seed that signs sealed-exec envelopes (#144) — a dedicated key, not the SSH CA. Required when any host sets sealed_exec (config load fails otherwise: that host's sessions would be pinned to the shim with nothing able to sign the envelopes it demands). The signer logs the matching public key at startup; pin it on each sealed host with deploy/install-shim.sh. Exactly one seed: rotation is done on the HOST side, where the pinned file accepts the outgoing and incoming key together (runbook in docs/OPERATIONS.md § 2.2). Absent = sealed exec unavailable (the default).
end_user_oidc *EndUserOIDCConfig EndUserOIDC configures signer-side re-validation of the end user's OIDC bearer token (#143). When set, callers opted in via callers[cn].require_verified_end_user get their end_user/end_user_groups derived from the verified JWT (forwarded by the HTTP frontend) instead of trusted verbatim — closing THREAT_MODEL gap #2. Absent = the feature is off and any caller that sets require_verified_end_user fails closed. The audience MUST match the HTTP frontend's resource_url, or aud validation rejects every token; issuer/user_claim/groups_claim SHOULD mirror the frontend's oauth block so the signer derives the same identity and groups.

Control-plane config (control-plane.json)

Config in cmd/control-plane/main.go

JSON key Type Description
listen string e.g. ":7443"
server_cert string mTLS toward the broker: presents server_cert and requires clients signed by client_ca.
server_key string
client_ca string
sign_callers []string SignCallers: client cert CNs authorised to use the signing path (/v1/sign, /v1/hosts, /v1/sign/result) — i.e. the brokers. This separates the broker role from the approver role (approval.callers) when both are signed by the same client_ca. If non-empty, only these CNs may request signing. If empty/absent, any authenticated broker may — EXCEPT a CN that is in approval.callers, which is an approver, not a broker, and is denied the sign path (role separation, secure by default).
signer (object) Signer: mTLS client toward the signing service.
signer.url string
signer.client_cert string
signer.client_key string
signer.ca string
approval (object) Approval: human-approval orchestration.
approval.notifier string ""/"log" (default) | "webhook" | "teams"
approval.webhook_url string required when notifier=webhook or teams
approval.timeout_seconds int TTL for pending requests
approval.callers []string CNs authorised to approve/deny
approval.teams_format string Teams-specific fields (notifier=teams).
approval.approval_url_template string URL with "{id}" to link the request
behavior control.BehaviorConfig Behavior: behaviour guardrails (anomaly detection + rate limiting).
trusted_forwarders []string TrustedForwarders: broker client cert CNs whose end_user claim is trusted (brokers that authenticate end users, e.g. via OIDC). Mirrors the signer's trusted_forwarders semantics. Behaviour guardrails key on ":" only for these CNs; for any other CN the client-supplied end_user is ignored and the authenticated broker CN alone is used, so a client cannot evade rate limits or anomaly detection by rotating end_user. Empty/absent = end_user never qualifies the subject.
audit_log string Audit log for the control plane (independent of broker and signer).
audit_key string
audit_fail_mode string AuditFailMode governs what happens when the control-plane audit log cannot be written for an approval-critical record (the approval decision and the grant that hands out a certificate/token). "" and "closed" fail closed (reject the approval rather than grant it with the "who approved" record only on stderr — the secure default, matching the signer #184); "open" logs the error and proceeds (pre-2.0 behaviour). Best-effort records (forwarded, denied, anomaly, rate-limited) are unaffected.
monitor_listen string MonitorListen: optional plain-HTTP monitoring listener serving /healthz (liveness) and /metrics (Prometheus text format). No authentication — bind to localhost or a private scrape interface. Empty = disabled.
redact *redact.Config Redact enables secret redaction on the control plane's persistent and outbound sinks: the audit log's free-text fields and the approval notification payload (log/webhook/Teams). Present (even empty, "redact": {}) = built-in default patterns; absent = disabled (backward compatible). The approval registry itself keeps the original command: the mTLS approval UI and API show the approver exactly what will run, and the approved request forwarded to the signer is untouched.
state_db string StateDB: optional path to the SQLite state database that persists the approval registry (pending and approved-but-uncollected requests, with their original wire request) across restarts (pure-Go driver; WAL mode leaves state.db-wal/-shm sidecar files next to it). Empty or absent = in-memory only (previous behaviour: a restart clears pending approvals). If set and the database cannot be opened or migrated, the service refuses to start (fail-closed). Production: /var/lib/infrabroker/control-plane/state.db.

Control-plane behaviour guardrails (behavior)

BehaviorConfig in internal/control/behavior.go

JSON key Type Description
mode string Mode: "off"|"observe"|"enforce".
rate_limit_per_min int RateLimitPerMin: maximum requests per subject per minute (0 = no limit).
max_subjects int MaxSubjects caps how many subjects are tracked before the least-recently -seen one is evicted (0 = defaultMaxSubjects).
subject_ttl_minutes int SubjectTTLMinutes evicts subjects idle for longer than this (0 = defaultSubjectTTL).
max_distinct_per_subject int MaxDistinctPerSubject caps the distinct hosts and command fingerprints retained per subject (0 = defaults). Once full, novelty detection for that dimension degrades to "seen" rather than growing without bound.

Host policy (hosts.<name>)

HostPolicy in internal/signer/signer.go

JSON key Type Description
addr string Connectivity — exposed to the broker via /v1/hosts.
user string remote SSH account
host_key string authorized_keys line for the host key
jump string logical name of the preceding bastion
principal string Issuance policy — internal, never exposed to the broker.
source_address string
max_ttl_seconds int
allow_as_bastion bool
allowed_callers []string AllowedCallers restricts which CNs may request this host. Empty = any authenticated caller.
allow_sudo bool Elevation (sudo NOPASSWD). AllowSudo enables privilege elevation for this host.
allowed_sudo_users []string AllowedSudoUsers lists the permitted target users (e.g. ["root","deploy"]). Empty = root only. "root" is always implied when AllowSudo=true.
allow_pty bool AllowPTY authorises the permit-pty extension in certificates for this host. If false, PTY requests are rejected.
allow_file_transfer bool AllowFileTransfer authorises the file-transfer tools (ssh_put_file / ssh_get_file) for this host. If false (the default — secure by default), signing requests flagged file_transfer are rejected. The generated transfer command is still subject to the host's command policy.
groups []string Groups lists the RBAC groups this host belongs to. A caller restricted by groups can only access hosts that share at least one of its allowed_groups. Empty = host belongs to no group.
sealed_exec bool SealedExec makes session exec HOST-enforced on this host (#144, THREAT_MODEL gap #1): the session certificate carries force-command=infrabroker-shim, and every ssh_session_exec must present a signed {nonce, host, command, expiry} envelope that the shim verifies against a pinned public key before running anything. A broker that skips the per-command preflight then holds nothing the host will run. Requires envelope_key on the signer and the shim + pinned pubkey deployed on the host (deploy/install-shim.sh); sessions on a sealed host are restricted to mode=exec (shell/pty are not envelope-verifiable). Off by default. Remote topology only: it exists to survive broker compromise, which presupposes broker != signer, so it has no local-mode (single-binary) counterpart.
command_policy CommandPolicy CommandPolicy restricts which commands may run on this host (AI-action firewall). Empty/off = no command restriction. Session commands are preflighted against the current signer policy before each exec, so reloads affect already-open sessions: target and bastion access, end-user groups, sudo, sudo_user and PTY are revalidated; the broker also rejects already-open sessions if the host's physical SSH route changed. mode=exec is allowed, while shell/pty sessions are rejected when rules are present because stateful commands are not independently verifiable.

Command policy (command_policy)

CommandPolicy in internal/signer/cmdpolicy.go

JSON key Type Description
mode string Mode: "off" (or empty) | "allowlist" | "denylist". Controls allow/deny.
enforcement string Enforcement: "enforce" (or empty) blocks/gates matching commands; "audit" lets them run and returns/audits a warning instead. In composed policies, enforce wins over audit.
allow []string Allow: in allowlist mode, the command must match at least one.
deny []string Deny: in denylist mode, the command must not match any.
require_approval []string RequireApproval: commands that match require out-of-band human approval. Evaluated independently of the mode (orchestrated by the control plane).
shell_parse *bool ShellParse controls POSIX-sh parsing of the command before the policy is evaluated. When parsing is on, each simple command is evaluated separately and dangerous nodes (subshells, process substitution, file redirects, environment mutations) are rejected unconditionally, so a compound command like "kubectl get pods; rm -rf /etc" cannot ride past an allowlist entry that only matches its first word. Parsing is ON BY DEFAULT — a nil pointer, i.e. the "shell_parse" key absent, parses — so an active command policy covers chained commands without extra configuration. Set it explicitly to false ("shell_parse": false) to restore the legacy raw-string matching for a policy. The three-state pointer keeps the absent-means-on default distinguishable from an explicit opt-out.

Secret redaction (redact, all three services)

Config in internal/redact/redact.go

JSON key Type Description
patterns []Pattern Patterns are extra operator-defined rules, applied after the built-in defaults. See Pattern for the regex contract.
disable_defaults bool DisableDefaults turns off the built-in default rules, leaving only the operator's Patterns. Escape hatch when a default rule produces false positives that hurt forensics.

Redaction pattern (redact.patterns[])

Pattern in internal/redact/redact.go

JSON key Type Description
name string Name identifies the rule inside the [REDACTED:] marker.
regex string Regex is an RE2 expression (linear-time, no catastrophic backtracking — same engine and rationale as the command-policy rules). If it defines a capturing group named "secret", only that group is masked; otherwise the whole match is masked.

Kubernetes cluster policy (kubernetes.clusters.<name>)

ClusterPolicy in internal/signer/k8spolicy.go

JSON key Type Description
api_server string Connectivity — exposed to the broker via /v1/clusters.
ca_cert string path to the cluster CA bundle (PEM)
token_file string TokenFile is the signer's minter credential for this cluster: a ServiceAccount token whose entire RBAC is create on serviceaccounts/token for the bound SAs below. Never exposed.
token_ttl_seconds int TokenTTLSeconds bounds the minted bound-token lifetime. 0 selects 600; the valid range is [600, 900] (TokenRequest refuses less than 600).
groups []string Groups / AllowedCallers: same RBAC semantics as HostPolicy.
allowed_callers []string
sa_bindings []SABinding SABindings select the ServiceAccount (layer B: its native cluster RBAC) per end-user group. At least one binding is required.
rules []K8sRule Rules is the cluster's ActionPolicy. Unlike SSH hosts (default-allow without a command_policy, for backward compatibility), a cluster is DEFAULT-DENY: at least one allow/require_approval rule is required, and anything unmatched is refused. There is no legacy to preserve here.
extra_resources []k8s.ResourceDef ExtraResources extends the curated core resource table for this cluster (explicit CRDs — no API discovery).

Kubernetes SA binding (kubernetes.clusters.<name>.sa_bindings[])

SABinding in internal/signer/k8spolicy.go

JSON key Type Description
groups []string
namespace string
service_account string

Kubernetes action rule (kubernetes.clusters.<name>.rules[])

K8sRule in internal/signer/k8spolicy.go

JSON key Type Description
verbs []string
resources []string
namespaces []string
names []string
effect string allow | deny | require_approval

Kubernetes resource (kubernetes.clusters.<name>.extra_resources[])

ResourceDef in internal/k8s/resources.go

JSON key Type Description
resource string Resource is the lowercase plural name used in tool calls, policy rules, and REST paths (e.g. "deployments").
group string Group is the API group; empty = core ("" → /api/v1, else /apis/).
version string Version is the served API version (e.g. "v1").
kind string Kind is the manifest kind (e.g. "Deployment") — descriptive metadata for the resource entry; required so an extra_resources declaration is self-documenting.
namespaced bool Namespaced marks namespace-scoped resources.

Vocabulary (enumerated constants)

Role distinguishes the role of a hop in the chain.: target, bastion

Purpose distinguishes the intended use of the connection.: oneshot, session

SessionMode distinguishes broker-managed session styles.: exec, shell, pty

CommandPolicy modes.: off, allowlist, denylist

CommandPolicy enforcement modes.: enforce, audit