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 supported backends ("pem" for local files, "akv" for Azure Key Vault). 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)
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).
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.
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"
path string PEM backend.
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 supported backends ("pem" for local files, "akv" for Azure Key Vault).
ca_keys map[string]ca.CAKeyConfig
audit_log string Issuance audit log (independent of the broker).
audit_key string
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 and approve-and-learn waivers 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 are lost on restart, kept across reloads). 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 CN absent from the table has no group restriction (backward compatible) unless a reserved "_default" entry exists, in which case absent CNs inherit its allowed_groups — "_default": {"allowed_groups": []} makes the table default-deny. A CN present can only see and sign hosts whose groups field intersects with its 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).

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
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.
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: if true, the command is parsed as POSIX sh before evaluating the policy. Each simple command is evaluated separately; dangerous nodes (subshells, process substitution, file redirects) are rejected unconditionally. Backward compatible: false by default.

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