Skip to content

Add ALLOW_EXEC / ALLOW_KILL / ALLOW_DELETE granular flags (fixes #114)#176

Open
gilberg-vrn wants to merge 1 commit into
Tecnativa:masterfrom
gilberg-vrn:feat-allow-exec-kill-delete
Open

Add ALLOW_EXEC / ALLOW_KILL / ALLOW_DELETE granular flags (fixes #114)#176
gilberg-vrn wants to merge 1 commit into
Tecnativa:masterfrom
gilberg-vrn:feat-allow-exec-kill-delete

Conversation

@gilberg-vrn

Copy link
Copy Markdown

Closes #114.

Problem

Setting CONTAINERS=1 + POST=1 (a common minimum for builders/runners that need to inspect/create containers) implicitly grants three high-impact operations:

  • POST /containers/<id>/exec — create a new exec session in any container
  • POST /containers/<id>/kill — kill any container
  • DELETE /containers/<id> — remove any container

In a typical sandboxing setup (untrusted workload talks to host Docker via this proxy) these are exactly what one wants to deny by default. The existing EXEC env flag controls only /exec/<id>/start|resize|inspect (operations on already-created sessions), not creation of new sessions via the /containers/<id>/exec path — see #114 for the original report.

Change

Three new env flags, following the same pattern as the existing ALLOW_START / ALLOW_STOP / ALLOW_RESTARTS:

Flag Endpoint
ALLOW_EXEC POST /containers/<id>/exec
ALLOW_KILL POST /containers/<id>/kill
ALLOW_DELETE DELETE /containers/<id>

All default to 0 (deny). Deny rules run before the generic CONTAINERS allow rule.

Backward compatibility

This does change behavior: existing deployments using CONTAINERS=1 POST=1 to perform docker exec / docker kill / docker rm will start getting 403 until they add the corresponding ALLOW_*=1. The README has been updated to document the new flags and the limitation of the existing EXEC flag.

I chose to make this an opt-in change rather than gate it behind a "strict mode" toggle because:

  1. It matches the precedent of ALLOW_START / ALLOW_STOP / ALLOW_RESTARTS, which are also off by default even with CONTAINERS=1.
  2. The previous behavior is a security footgun that surprises users (the issue has been open for years).
  3. The migration is mechanical: a single env-var addition where needed.

If the maintainers prefer a non-breaking rollout, I'm happy to gate the new behavior behind a STRICT_CONTAINERS=1 flag instead — let me know.

Tests

Added three deny-path regression tests (test_*_denied_without_allow_*) verifying that CONTAINERS=1 POST=1 alone is not enough for exec/kill/delete. Updated the existing test_exec_permissions to also set ALLOW_EXEC=1, documenting the new requirement for callers that need exec.

The allow path of ALLOW_EXEC is covered by the updated existing test. I did not add explicit allow-path tests for ALLOW_KILL / ALLOW_DELETE because docker kill / docker rm -f over HAProxy's TCP proxy is flaky with newer dockercli versions (the client opens a hijack-mode connection that HAProxy doesn't keep alive past the response). The deny path is verified by ProcessExecutionError regardless of which side closes the connection. I'm happy to switch the test suite to a requests-based client if you prefer explicit allow-path coverage.

Verification

$ docker build -t test:docker-socket-proxy .
$ python3 -m pytest tests/ -v -n 0
[...]
============================== 8 passed in 13.07s ==============================

Fixes Tecnativa#114.

Until now, setting CONTAINERS=1 + POST=1 implicitly granted three
high-impact operations:
  * POST /containers/<id>/exec  — create new exec sessions
  * POST /containers/<id>/kill  — kill a container
  * DELETE /containers/<id>     — remove a container

In a typical sandboxing setup (an untrusted workload reaching the host
Docker socket only via this proxy) these are exactly the operations one
wants to deny by default, while still allowing inspect/logs/create-only
flows via CONTAINERS=1. The existing EXEC env controls only
/exec/<id>/start|resize|inspect (operations on already-created sessions),
not creation of new ones — see issue Tecnativa#114.

This change introduces three new env flags following the same pattern as
the existing ALLOW_START / ALLOW_STOP / ALLOW_RESTARTS:

  * ALLOW_EXEC   — POST /containers/<id>/exec
  * ALLOW_KILL   — POST /containers/<id>/kill
  * ALLOW_DELETE — DELETE /containers/<id>

All three default to 0 (deny). The deny rules are evaluated before the
generic CONTAINERS allow rule, so existing deployments that wanted these
operations under CONTAINERS=1 must now opt in explicitly — this is the
intended behavior change.

Tests cover the deny path (default behavior) for each new flag. The
existing test_exec_permissions is updated to set ALLOW_EXEC=1 alongside
the existing CONTAINERS=1 EXEC=1 POST=1, documenting the new requirement
for callers that genuinely need exec.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

exec / any other methods open when POST is set to 1 and how is DELETE handled ?

1 participant