authorize-docker-requests: P-16 extra bind roots, and the host facts a snap install teaches (#38, #39) - #49
Open
phoenix-server wants to merge 2 commits into
Open
phoenix-server wants to merge 2 commits into
phoenix-server wants to merge 2 commits into
Conversation
The bind allow-list was the project directory plus named volumes, which covers a stack whose data lives under its own directory and nothing else: a host whose media, library or document trees sit elsewhere cannot create those containers at all, and the operator's only route was to edit the deployed policy by hand. P-16 names further roots, comma-separated, empty by default. Each is a prefix grant matched as a path boundary — a directory accepts its whole subtree, and a single file is named exactly without granting the directory that holds it — and a `..` segment stays refused under every root, which is what a prefix grant otherwise reaches. With P-16 empty the policy decides exactly as the shipped one does, verified row by row on the plugin's own engines.
…nap install teaches Three facts a deployment rediscovers the hard way, now stated where they are needed. The daemon's configuration file is found from the daemon's own command line: `ps -o args= -C dockerd` carries `--config-file`, which on a snap install names a revision-numbered directory that a `snap refresh` replaces, with the `current` symlink as its stable alias. The paths around the daemon are snap-layout too — the plugin mounts the snap's `/etc/docker` at `/opa` — so the host-side policy path is under the snap root while every path inside the daemon is `/etc/docker`, and the plugin's own report (`--discover`) is what resolves it. And a policy that grants neither exec nor attach changes what a client command can do: `docker run` never completes its attach, a build needs `DOCKER_BUILDKIT=0`, and exec-based tooling stops working — each of those is a decision the client reports as a denial, which is worth saying because it otherwise reads as a broken tool. A second daemon started with `dind --privileged --network host` on a host that is already running containers is called out as the way a working stack loses `docker0`.
Deploying agentic-schematics with
|
| Latest commit: |
73cca64
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://031167b1.agentic-schematics.pages.dev |
| Branch Preview URL: | https://feat-authorize-docker-reques.agentic-schematics.pages.dev |
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.
Closes #38. Closes #39.
Two commits, one per issue:
e179f69implements the parameterised extra roots (#38),73cca64adds the host-path and client-consequence facts (#39). Frontmatter:version: 0.5.0 → 0.6.0,updated: 2026-09-17.#38 — the allow-list was narrower than real deployments
The bind allow-list accepted the project directory plus named volumes, so a host whose media, library or document trees live elsewhere could not create those containers at all — the only route was editing the deployed Rego by hand, which is what happened on the host this was reported from (18 of 45 bind sources covered; 42 → 45 containers after the hand-edit).
P-16 EXTRA_BIND_ROOTS— comma-separated absolute directories, empty by default — is the knob:/srv/mediaaccepts/srv/media/x, and/srv/mediaXis still refused./srv/media/../../etcstarts with the root and is denied. That was the point of keeping the check where it is; a prefix grant is exactly whatpath..reaches./or/**is accepted and means the directory itself;/and empty entries are dropped rather than accepted, so a root cannot make the gate decorative.scripts/reload-opa-policy.sh), so a copy deployed without it is caught by the check rather than silently deployed.The limitation is documented as well as fixed — SCHEMATIC.md's Limitations,
modules/opa-policy.md's Limitations, and P-16's own row all say the same thing: the allow-list is exactly as wide as P-15 plus P-16, a root is a prefix grant, and the operator's real layout is the one input to R-15 that the API's shape does not decide.#38 — proof
Eight probe rows were added to
skeleton/agent.rego.schema(78 → 86), and the new rows were run on the engines the plugin releases embed, plus a newer one —openpolicyagent/opa:1.3.0(whatv0.10embeds),0.60.0(whatv0.9embeds),1.7.1.With
P-16 = /srv/media,/srv/data/known_hosts— deliberately a directory and a single file:With
P-16empty — the default — the same twelve inputs decide12/12as the table says, all four extra-root grants denied, every denial still denied.And the check that matters for the existing contract: the shipped template and this one decide identically on all twelve inputs when
P-16is empty, on all three engines:With
P-16set, the four extra-root shapes flip to allow whileer-traversal,er-string-prefix,er-symlink,er-file-dir,regr-privilegedandregr-project-traversalstay denied.The rows were run with the plugin's real input shape (
Path/PathPlain/PathArrcarrying the API version prefix,Queryparsed, identityUser: sandbox-agent). The probe inputs and the comparison harness are throwaway — not committed.#39 — three facts from a live snap deployment
ps -o args= -C dockerdcarries--config-file; a snap install names a revision-numbered directory there (/var/snap/docker/<revision>/config/daemon.json) that asnap refreshreplaces, with/var/snap/docker/current/config/daemon.jsonas its stable alias. P-13's discovery cell, Phase 1 step 6 and the daemon-config module now say that, and record that writing the wrong file produces no error at all./etc/dockerat/opa, so the host-side policy path is under the snap root while every path inside the daemon and the plugin is/etc/docker. The daemon-config module gains that section, and the policy-reload module now says why--discoverbeats any documented path — it resolves the plugin's own argument through its own mount.docker runcannot complete (create granted, attach refused →docker create+docker start, ordocker compose up -d); a build needsDOCKER_BUILDKIT=0, because BuildKit'sPOST /grpcis denied and its builder container is refused by the project-name rules; exec-based tooling stops working, and the denial message is what tells the operator it is a decision rather than a fault. SCHEMATIC.md's Limitations andmodules/opa-policy.mdcarry it. The second-daemon trap is now a failure mode: adind --privileged --network hosttrial takesdocker0down, and with it the network of every container already running.Notes
improve-docker-securitypins this package at6775510(v0.5.0) in improve-docker-security: pin D-3 at the revision whose policy is verified (#34, #37) #48, which is unaffected: a pin names a revision, and P-16 arrives in 0.6.0. When that composition wants the parameter, its pin moves with its own change.BASE_REF=main bash scripts/validate-catalog.sh→frontmatter ok: 18 specs,catalog ok: 19 entries … 21 pins verified, exit 0.