Repository navigation
docs: define the socket trust model; drop per-caller framing - #50
Merged
Merged
Conversation
The proxy selects a policy by the request's image and never identifies the caller. Document that as the supported model: the listening socket is the trust boundary, every caller of a socket can use every policy behind it, and separate trust domains run as separate instances with their own socket group (systemd template unit, verified under real systemd). Record in spec/README.md that the Quint model has no caller by design.
abienkowski
force-pushed
the
docs/trust-model-39
branch
from
October 7, 2026 14:50
d8012b7 to
ad05b0c
Compare
4 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Closes #39.
#39 points out that the README promises "per-service policies", but the proxy never learns who is calling. It picks a policy from the request's
Image, so any caller of a socket can use any policy behind it. This PR settles the question as a documented decision, with no code changes: the listening socket is the trust boundary.Why not authenticate callers (option 2 in #39)
The deployment this proxy is built for gives external developers access to a host through one shared account. Peer credentials (
SO_PEERCRED) and socket-group permissions both identify a Unix account, and every developer shares the same one. No proxy feature can tell apart people whom the host's own access model does not tell apart. Option 2 would also have left a second gap like #46 in TypeScript, because Node cannot read peer credentials without a native addon.What the docs now say
--config-dir. The kernel enforces the separation. This works today with no code, because Listening socket: dockerd parity, Unix path only (drop fd:// and --listen-socket-mode, add single-instance lock) #45 gave every instance its own group-owned socket and lock.Changes
README.md:docker-socket-policy@.service) for running several domains on one host.go/internal/audit/audit.gohas no such field), so shared-account developers have to be told apart at login.spec/README.md: a Modeling Note recording that the Quint model has no caller by design, so the invariant Policy is selected from the request body, not the caller: "per-service" enforcement has no caller identity #39 asked about is deliberately unstatable.Rejected alternatives
Type of change
Implementation(s) changed
Testing
Documentation only.
make lint-allpasses.The systemd template unit was run under real systemd (Debian 12 container, systemd as PID 1, a Go binary built from
main), with two domains,teamaandteamb:A connect test was run as each domain's shared account. The
502comes from the proxy answering/_ping; the test container had no Docker daemon behind it.This confirms two things. systemd expands
%iinGroup=andRuntimeDirectory=, which its man page does not state for those settings. And the kernel refuses cross-domain connections, as the README says.make test-all): not applicable, no code changesmake test-integration): not applicablemake verify): not applicable, model unchangedChecklist