Skip to content

orthrus: unify the two independently hand-maintained muzzle allowlists (and give agent/ CI coverage) #1161

Description

@Wikid82

Summary

Charon enforces its "Orthrus is strictly read-only" guarantee via two separately maintained Docker API allowlists:

  • backend/internal/orthrus/muzzle.go — filters requests inside Charon, before they enter the tunnel.
  • agent/muzzle/muzzle.go — a second, independent filter on the remote agent binary itself, right before it dials the real Docker socket (defense-in-depth).

These two files are hand-copied lists of the same intended policy, in two different Go packages. They have already diverged once in practice: a fix adding /images/{name}/json and /distribution/{name}/json support (for third-party update-checker tools like Dockhand) was implemented in the backend copy only (commits 98a68b67, b71cbd62), and shipped/rebuilt/redeployed twice before anyone noticed the agent's copy still rejected the same endpoints (fixed in eabf358d). The bug was invisible to CI because nothing caught the mismatch between the two lists.

Contributing factor: agent/ has no CI-enforced quality gates

Investigation during the fix above found that all of this repo's lint/staticcheck/coverage tooling (make lint-fast, scripts/go-test-coverage.sh, lefthook hooks, etc.) targets backend/ only. The agent/ module — which is a separate Go module/build target — has no equivalent enforcement. This is part of why the missing allowlist entries in agent/muzzle/muzzle.go weren't flagged automatically.

Suggested follow-up work

  1. Unify the allowlist source of truth. Options to evaluate: share a single allowlist definition between backend/internal/orthrus and agent/muzzle (may require restructuring given agent/ is built as a minimal standalone binary and may not want to import backend-side packages/deps), or at minimum add a CI check that diffs the two lists and fails if they drift.
  2. Wire up CI-enforced tooling for agent/: lint/staticcheck, coverage gate, and inclusion in the existing pre-commit/lefthook pipeline, matching what backend/ already has.
  3. Consider a shared test corpus (see companion issue on path-normalization order) that exercises both filters identically.

Related

docs/reports/qa_report.md, docs/plans/current_spec.md, commits 98a68b67, b71cbd62, eabf358d.

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureSystem design and structurebackendServer-side codeci-cdmediumNice to have, can be deferredtestingTest suite

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions