You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
--readonly only blocks container create; lifecycle actions and DELETE are still forwarded #75
Describe the bug --readonly only blocks container create. ReadonlyGate lives in the middleware chain, and the chain runs only when the router returns the create route (go/internal/proxy/handler.go:75, rs/src/handler.rs:78, ts/src/handler.ts:43). The flag feeds nothing else (go/main.go:82, rs/src/main.rs:106, ts/src/index.ts:67). So in read-only mode the proxy still forwards container lifecycle actions (start, stop, restart, kill, wait, pause, unpause), DELETE /containers/{name}, and image pulls that pass the router.
README.md says ReadonlyGate "Denies all POST, PUT, DELETE, PATCH", so an operator relying on --readonly gets far less than documented. Found in the review of #74 (the same unreachable-gate pattern as the ExecGate removed there).
Affected implementation(s)
All (reproduced on Go; Rust and TS have the same structure by code reading)
To Reproduce
Go binary from main, --readonly, --config-dir=deploy/config, against Docker 29.4.0:
Request
Status
Body
POST /containers/create
403
validation failed: read-only mode: POST requests are not allowed
POST /containers/zz-no-such/stop
404
{"message":"No such container: zz-no-such"} (forwarded to the daemon)
DELETE /containers/zz-no-such
404
{"message":"No such container: zz-no-such"} (forwarded to the daemon)
POST /images/create?fromImage=… (no body)
403
empty request body (denied for another reason; a pull with a body was not tried)
With a real container name, stop and DELETE would act on it.
Expected behavior
In read-only mode every method other than GET/HEAD is denied for every path, before routing or as a router rule, with the existing message read-only mode: <METHOD> requests are not allowed, in all three implementations. Spec: add a READONLY flag to spec/router.qnt with a property "readonly ⇒ no non-GET/HEAD request is allowed", a router_readonly instance, and table rows; unit tables in all three; an integration run with --readonly.
Alternatives considered:
Run the chain on every route. Rejected: the other gates are create-specific (image, binds, env, cmd) and would need per-route guards.
Document that --readonly only covers create. Rejected: that is not a useful "read-only" mode, and the README already promises more.
Environment
Docker 29.4.0 (OrbStack), main at 3c7fe0b.
Additional context
Consider a security note for the affected releases once fixed.
Activity
fix: enforce --readonly in the router for every write (#75) (#77)