Pod

Yes, this is on purpose. Pod is built for agents, so the default page is plain HTML.
Human? View the normal website.
Agent? You probably prefer /mcp/infrabroker/issues.md or /mcp/infrabroker/issues.json, or Pod over MCP.

Reported issues for infrabroker

Pod holds 17 of 45 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to infrabroker.

Most discussed

merge the three broker frontends (broker, mcp-broker, mcp-broker-http) into one binary with transport subcommands

File references are against a28ca75.

Context

Three of the seven binaries are thin wrappers around the same broker.Engine + internal/mcpserver, differing only in transport:

Each main repeats the same wiring (LoadConfigNewEnginemonitor.Serve → serve/run loop), and every release artifact, Doc

Read the thread · 2026-07-09 · closed · 2 comments

install.sh --bindir is ignored by the shipped systemd units

audit-id: a409f4c31c61

Category: logic · Severity: low — see description

Location: deploy/install.sh:48

Description: --bindir DIR installs signer/control-plane/mcp-broker-http to $BINDIR, but the units copied in step 5 hard-code ExecStart=/usr/local/bin/.... A non-default bindir yields enabled units that exec missing binaries. install-shim.sh handles --bindir correctly.

Proposed fix & verification: Rewrite ExecStart to ${BINDIR}/ when installing the units, or reje

Read the thread · 2026-08-13 · closed · 1 comment

install.sh never heals existing *.env or broker-ctl.json modes

audit-id: e406c27d8510

Category: security · Severity: medium — see description

Location: deploy/install.sh:176

Description: The installer claims re-run heals, never widens. Service JSON is converged to 0640 on every run, but two secret-adjacent files are left as-is:

Read the thread · 2026-08-13 · closed · 1 comment

reload() is not serialized with writeMu, so a concurrent policy narrowing can be reverted in memory

audit-id: c805ca866a5d

Category: security · Severity: medium — see description

Location: cmd/signer/main.go:771

Description: writeMu serializes POST/DELETE /v1/policy mutations (mutateAllow reads, edits, writes, then swaps s.local). reload() — SIGHUP, POST /v1/reload, and the mtime watcher — reads signer.json and later swaps s.local under s.mu only. buildState can take seconds (CA/AKV). Sequence: reload reads v1 → mutateAllow writes and applies v2 (DELETE last dangerous allow)

Read the thread · 2026-08-13 · closed · 1 comment

Command-policy wrapper gate misses versioned interpreters, ash, and /usr/bin/time

audit-id: 1427d5fdc887

Category: security · Severity: high — see description

Location: internal/signer/cmdpolicy.go:351

Description: After #371 the wrapper set is still an exact path.Base map. A live Decide() against denylist ^rm still allows:

Read the thread · 2026-08-13 · closed · 1 comment

Deploy skill still teaches obsolete empty _default callers and omits agent CA custody

audit-id: dcafd283e94a

Category: documentation · Severity: medium — see description

Location: .agents/skills/deploy/SKILL.md:76

Description: #338 fixed install.sh/checklist: a non-empty callers table is already default-deny without requiring "_default": {"allowed_groups": []}. The deploy skill still requires empty _default and later expects {} when callers._default is default-deny — wrong post-v2.0.0. Skill CA custody section also lists only akv|pem and says those are the

Read the thread · 2026-08-12 · closed · 1 comment

main is red: the go-sdk v1.7.0 bump (#314) breaks in-conversation approvals — SEP-2322 forbids server-initiated elicitation during tools/call

audit-id: d43e5a27e54a

Category: logic · Severity: high — see description

Location: internal/mcpserver/tools.go:454

Description: chore(deps): bump github.com/modelcontextprotocol/go-sdk (de4bba1, #314) moved the SDK from v1.6.1 to v1.7.0 and landed on main with a FAILING "Build Go Project" check — main has been red since 2026-08-01T07:05Z and build is a required check, so every PR is blocked.

go test -race ./internal/mcpserver fails:

--- FAIL: TestApprovalDeclinedV

Read the thread · 2026-08-01 · closed · 1 comment

Control plane drops allow_file_transfer when forwarding GET /v1/hosts, so every host behind it advertises file_transfer=false

audit-id: f848933a1873

Category: logic · Severity: medium — see description

Location: cmd/control-plane/main.go:660

Description: The signer serves allow_file_transfer on GET /v1/hosts (cmd/signer/main.go:1115), and signer.Remote.FetchHosts maps it into HostInfo.AllowFileTransfer (internal/signer/remote.go:435). But when a broker talks to the SIGNER THROUGH THE CONTROL PLANE, handleHosts re-marshals the result into a fresh signer.WireHostInfo and copies only Addr/User

Read the thread · 2026-08-01 · closed · 1 comment

Most recent

docs/USAGE.md opens with 'the seven MCP tools' but documents thirteen (the six k8s_* tools have their own section)

audit-id: b83a3a7006c9

Category: documentation · Severity: low — see description

Location: docs/USAGE.md:3

Description: The guide's first sentence says it 'covers practical usage of the seven MCP tools exposed by cmd/mcp-broker (stdio) and cmd/mcp-broker-http'. Thirteen tools ship and the same file documents all of them: the seven ssh_* tools plus the six k8s_* tools (k8s_list_clusters, k8s_get, k8s_list, k8s_logs, k8s_apply, k8s_delete) in section 10, added with the Kubernete

Read the thread · 2026-07-24 · closed · 1 comment

Elicitation (#118) approve/decline outcome is not distinctly audited; an elicitation-approved exec is indistinguishable from a non-gated one

audit-id: e8f2340c7124

Category: logic · Severity: low — see description

Location: internal/mcpserver/tools.go:238

Description: With approval_via_elicitation, a require_approval command triggers an in-conversation elicitation. The approval REQUEST is audited (the first Execute withholds the cert and audits Outcome:error,'requires human approval'), but: (1) the DECLINE path (tools.go:238) returns 'approval declined' with NO audit write — the log cannot distinguish 'human asked

Read the thread · 2026-07-14 · closed · 1 comment

Redaction can inflate an audit entry past the 256 KiB reader buffer, bricking fail-closed startup (no write-time entry-size cap)

audit-id: 0503a78eb63b

Category: security · Severity: high — see description

Location: internal/audit/log.go:396

Description: Redaction runs on every Append (log.go:392-401) and EXPANDS free-text: the env-assignment default rule (internal/redact/defaults.go) turns AUTH=a (6 bytes) into AUTH=[REDACTED:env-assignment] (30 bytes). The sign request body is capped at 64 KiB (cmd/signer/main.go:589) but there is NO cap on command length, and no cap on the serialized entry size. Ever

Read the thread · 2026-07-14 · closed · 1 comment

Command-policy deny/require_approval bypass via shell quoting/encoding: extractCommands matches the re-printed (quote-preserving) command, not its decoded literal

audit-id: 0f3773740cd1

Category: security · Severity: high — see description

Location: internal/signer/cmdpolicy.go:197

Description: extractCommands re-prints each parsed simple command with printer.Print (cmdpolicy.go:197), which PRESERVES quoting/encoding, and PolicySet.decideOne matches deny/require_approval regexes against that printed form (policyset.go:145,157). On a denylist host (no allowlist) a non-matching command default-allows (policyset.go:187-189). The target she

Read the thread · 2026-07-14 · closed · 1 comment

infrabroker init --register-mcp writes a broker config with CWD-relative paths, so the registered MCP server never starts

audit-id: c82cfe6f18b8

Category: logic · Severity: medium — see description

Location: internal/initcmd/config.go:122

Description: infrabroker init emits config.json (and signer.json) with paths relative to the init directory: the broker's mTLS client cert/key/CA (pki/broker.crt, pki/broker.key, pki/mtls_ca.crt), the audit key (pki/audit.seed) and audit log (audit.log). The broker resolves these against the PROCESS working directory: broker.LoadConfig (internal/brok

Read the thread · 2026-07-14 · closed · 1 comment

GET /v1/revocations returns Reason and FrozenBy to any authenticated caller, unfiltered by callers-RBAC (a default-denied broker still reads the whole freeze ledger)

audit-id: b7e69dd303ca

Category: security · Severity: low — see description

Location: cmd/signer/main.go:1002

Description: handleRevocations authenticates the mTLS caller then returns s.freezes.List() unconditionally. List() includes each entry's Value (broker CNs / end-user ids), Reason (free-text operator notes, e.g. 'employee under investigation'), FrozenBy (admin CN) and FrozenAt. The handler comment justifies this as 'like GET /v1/hosts', but /v1/hosts is group-filtered (

Read the thread · 2026-07-10 · closed · 1 comment

Broker revocation poll (kill switch) degrades silently: repeated FetchRevocations failures emit only a log line, no metric/liveness signal

audit-id: a9f984f658f9

Category: security · Severity: medium — see description

Location: internal/broker/engine.go:687

Description: startRevocationPoll is the broker half of the kill switch (#126): it force-closes live sessions matching the signer freeze set. On FetchRevocations error it does 'log.Printf(warning: revocation poll failed ...); continue' with NO counter, gauge, or last-success timestamp. Every frontend exposes Prometheus via monitor.Serve, so /metrics is the moni

Read the thread · 2026-07-10 · closed · 1 comment

k8s path: audit dry-run decisions and stop leaking the API-server URL to the model

Summary

Two independent gaps on the Kubernetes broker path:

  1. Dry-run decisions are not audited. The SSH dry-run path audits dry_run_allowed/dry_run_denied, but K8sExecute returns on dry-run with no audit entry — an agent can enumerate the whole k8s ActionPolicy surface (allowed/approval-gated verbs/resources/namespaces) leaving no trace in the broker audit log.
  2. API-server URL leaks to the model on transport errors, violating the stated invariant that the broker never expose

Read the thread · 2026-07-10 · closed · 0 comments

Kill-switch freeze coverage gaps: forwarder on_behalf_of bypass and unchecked /v1/clusters

Summary

The signer's freeze check runs on the resolved caller, so a trusted forwarder acting via on_behalf_of is never freeze-checked on its own mTLS CN — freezing a compromised forwarder/control-plane is a near no-op. Separately, GET /v1/clusters has no freeze check at all.

Where

Read the thread · 2026-07-10 · closed · 0 comments

The remaining reports are on the project's issue tracker.