Skip to content

--readonly only blocks container create; lifecycle actions and DELETE are still forwarded #75

Closed

Description

@abienkowski

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

  1. added
    Priority: P1Added to issues and PRs relating to a high severity bugs.
    Type: BugAdded to issues and PRs if they are addressing a bug
    on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority: P1Added to issues and PRs relating to a high severity bugs.Type: BugAdded to issues and PRs if they are addressing a bug

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions