Skip to content

improve-docker-security: pin D-3 at the revision whose policy is verified (#34, #37) - #48

Merged
phoenix-server merged 1 commit into
mainfrom
fix/improve-docker-security-repin
Sep 17, 2026
Merged

phoenix-server merged 1 commit into
mainfrom
fix/improve-docker-security-repin

Conversation

@phoenix-server

Copy link
Copy Markdown
Collaborator

Closes #34. Closes #37.

Both issues are the same change, so they are one commit and one PR: #34 asked for the re-pin plus one clause on R-2 once #19 landed, and #37 asks for the same re-pin at #36's merge commit once that landed. Both landed, so this does it once.

The pin

Before After
Revision 81721d8 6775510 — the merge commit of #36
Version in the link v0.2.1 v0.5.0 (the version the pinned file declares at that commit)
SHA-256 73a1a242… 1ba2b19c6bc5a8f079d1a0bbeb2003a0e1680611efa4c426d7d2ea90009c9534

The digest was recomputed from the file at 6775510 (git show 6775510:schematics/authorize-docker-requests/SCHEMATIC.md | sha256sum), not carried over. That commit is not fd1d6f2 — the #19 squash, whose policy still has the PathPlain defect — and not 81721d8. 6775510's copy of the file is byte-identical to main's today, so the pin names a fixed revision that will not drift under it.

D-2 and D-4 stay at 81721d8: both digests still match the files at that commit, and nothing about this change concerns them.

The claim

R-2 now ends:

What OPA narrows is the policy at D-3's pinned revision: this composition cannot promise a property that lives in another package's revision, so if that pin lags, this claim lags with it.

That is #34's clause. The Decisions entry that named 81721d8 as the pinned commit is corrected to say each dependency is pinned to the commit in its own link — after this change they sit at two revisions, and the old sentence had become false.

Frontmatter: version: 0.1.1 → 0.1.2, updated: 2026-09-17.

A-2 re-run, live

A-2 (R-2): a network client attempting a policy-denied operation receives OPA's denial; the same client's allowed operations work.

Run from the sandbox — a real network client (DOCKER_HOST=tcp://…:2376, client certificate, every request through the authorization plugin) against Docker 29.6.1, whose deployed policy is the revision at the pinned commit plus the extra bind roots the operator added by hand:

# allowed read (the same client, an allowed operation)
$ docker ps -q | wc -l
45

# denied: an operation the policy refuses
$ docker exec agent-sandbox true
Error response from daemon: authorization denied by plugin opa-docker-authz:latest: request rejected by administrative policy

# denied: a create that carries no project/testcontainers label
$ docker create alpine:latest true
Error response from daemon: authorization denied by plugin opa-docker-authz:latest: request rejected by administrative policy

# allowed: the same create, labelled as the policy requires
$ docker create --label org.testcontainers=true alpine:latest true && docker start <id>
<id>
cleaned up afterwards

# denied: --privileged, and a bind of /   (created with `docker create`, never started)
$ docker create --label org.testcontainers=true --privileged alpine:latest true
Error response from daemon: authorization denied by plugin opa-docker-authz:latest: request rejected by administrative policy
$ docker create --label org.testcontainers=true -v /:/host alpine:latest true
Error response from daemon: authorization denied by plugin opa-docker-authz:latest: request rejected by administrative policy

The identical create spec, run through docker run instead, stops at the attach:

$ docker run --rm --label org.testcontainers=true alpine:latest true
unable to upgrade to tcp, received 403

So the property holds where it did not before: the revision's policy denies --privileged, a / bind, an unlabelled create and exec — the create paths that carried HostConfig.Privileged and Binds: ["/:/host"] under v0.2.1's policy — while the allowed operations of the same client work.

A-5: not re-run, and why

A-5 (R-5) asks that stopping OPA blocks network control of the daemon (fail closed), that D-3's rollback line re-opens it, and that re-applying the daemon config closes it again. Every step of that is a host-side change to the daemon's authorization plugin configuration, which this sandbox cannot make: it holds authorized Docker access (create/start, no exec, no privileged), not host root. It was not attempted even as a probe, because disabling the plugin removes the only path this client — and the operator's own tooling on that host — has to the daemon.

What the deployment record says the claim rests on, for the reviewer's benefit, is two different cases that the composition's A-5 does not distinguish:

  • the plugin unreachable or returning an error → the daemon's authorization middleware denies (fail closed) — the composition's claim;
  • the policy file missing → the plugin fails open and allows the request (modules/policy-reload.md) — D-3's documented one fail-open path, and the reason policy edits are installed by temp file plus mv.

That asymmetry sits in D-3, not in this composition's pin, so it is flagged here rather than changed: deciding whether the composition should state it is the owner's call.

Validator

$ BASE_REF=main bash scripts/validate-catalog.sh
frontmatter ok: 18 specs checked against schemas/spec-1/SCHEMATIC.md.schema
catalog ok: 19 entries, featured=[...], 18 specs, 21 pins verified
exit=0

The pin checks in that run are the ones that matter here: the target commit is reachable, the file exists at it, its SHA-256 matches the recorded digest, and the link's version matches the pinned file's frontmatter at that commit.

Diff: schematics/improve-docker-security/SCHEMATIC.md, +8/−5, one file.

…fied

D-3 named authorize-docker-requests v0.2.1 at 81721d8, a revision whose policy
loaded on no installable plugin, so R-2's claim was carried by a revision that
could not deliver it. The pin now targets 0.5.0 at 6775510, the revision whose
policy is verified on a live daemon, carrying the SHA-256 of the file at that
commit.

R-2 gains the consequence: what OPA narrows is the policy at D-3's pinned
revision, so if that pin lags, the claim lags with it.

The Decisions entry that named 81721d8 as the pinned commit is corrected: the
three dependencies now sit at two revisions, each named in its own link.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying agentic-schematics with  Cloudflare Pages  Cloudflare Pages

Latest commit: 01fcf97
Status: ✅  Deploy successful!
Preview URL: https://3b478e33.agentic-schematics.pages.dev
Branch Preview URL: https://fix-improve-docker-security.agentic-schematics.pages.dev

View logs

@phoenix-server
phoenix-server merged commit 6516968 into main Sep 17, 2026
3 checks passed
@phoenix-server
phoenix-server deleted the fix/improve-docker-security-repin branch September 17, 2026 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants