Skip to content

implement per-container allowlists specified by Docker container labels#69

Merged
wollomatic merged 29 commits into
wollomatic:28-fr-support-granular-api-permissions-on-a-per-host-basis-via-allowfromfrom
amanda-wee:per-container-allowlists
Nov 29, 2025
Merged

implement per-container allowlists specified by Docker container labels#69
wollomatic merged 29 commits into
wollomatic:28-fr-support-granular-api-permissions-on-a-per-host-basis-via-allowfromfrom
amanda-wee:per-container-allowlists

Conversation

@amanda-wee
Copy link
Copy Markdown
Contributor

This pull request implements per-container allowlists that are specified using Docker container labels.

Summary

  • An "allowlist" is defined as the combination of a map of HTTP methods to allowed request regex and a slice of allowed bind mounts from strings (which can be empty).
  • There is a default allowlist that provides all the features that were already implemented, but additionally there is a map of container IP addresses (IPv4 and IPv6) to allowlists.
  • When a request is made to the proxy, the proxy attempts to find the allowlist matching the requesting container's IP address. If none is found, then the default allowlist is used, otherwise the found allowlist is used. The fundamental logic of checking if the request is allowed remains the same.
  • A goroutine is started to watch for container start/restart/die events and update the per-container allowlists accordingly.

Backwards Compatibility

To enable per-container allowlists, either the -proxycontainername parameter must be passed to the command, or the SP_PROXYCONTAINERNAME environment variable must be set. Otherwise, the functionality is skipped entirely, hence only the default allowlist will be used. If the proxy socket endpoint is provided, then likewise the functionality is skipped. Therefore, socket-proxy can still be used to proxy socket connections that are not for the Docker socket.

Security

Container labels can be set when a container is created through the Docker Engine API. This means that if a container has a per-container allowed request regex for POST requests that allows /containers/create, then an attacker that gains access to the container can perform privilege escalation that would not be possible with the default allowlist (without also being able to create an image). Since the usual use of socket-proxy is for read-only access and container creation access should be relatively rare, this risk should be worth the ease of use of Docker container labels to specify allowlists.

Docker Engine API Client

For development, the Docker SDK for Go (as in the low-level Moby) was used for API calls. Once a proof-of-concept was working, the part of the client that ended up being used was then extracted into packages under the internal folder so that socket-proxy will not need any external dependencies.

This client uses the socket path specified by the -socketpath parameter or the SP_SOCKETPATH environment variable, defaulting to the socket-proxy's defaultSocketPath. It also does Docker Engine API version negotiation for maximum compatibility.

@wollomatic
Copy link
Copy Markdown
Owner

Thanks @amanda-wee for this amazing work! I'll try to get the review done as soon as possible.

@wollomatic wollomatic changed the base branch from develop to 28-fr-support-granular-api-permissions-on-a-per-host-basis-via-allowfrom November 23, 2025 16:40
@wollomatic wollomatic requested a review from Copilot November 23, 2025 16:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements per-container allowlists that can be specified using Docker container labels, enabling fine-grained access control for each container accessing the Docker socket through the proxy. The feature is opt-in via the -proxycontainername parameter and maintains backward compatibility.

Key Changes:

  • Adds an embedded Docker API client (extracted from Moby) to monitor container events and manage per-container allowlists
  • Refactors configuration to use an AllowListRegistry that maintains both default and per-container allowlists mapped by IP address
  • Implements real-time allowlist updates through Docker event stream monitoring for container start/restart/die events

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/go-connections/sockets/sockets.go Adds socket configuration utilities extracted from docker/go-connections for the Docker client
internal/docker/client/*.go Implements Docker Engine API client with version negotiation, event streaming, and container listing
internal/docker/api/types/*.go Defines Docker API types for events, containers, filters, and responses
internal/config/config.go Refactors config to support allowlist registry with per-container allowlists, adds Docker event monitoring
cmd/socket-proxy/main.go Launches goroutine for allowlist updates when per-container feature is enabled
cmd/socket-proxy/handlehttprequest.go Updates request handling to determine and use appropriate allowlist based on client IP
cmd/socket-proxy/bindmount.go Refactors bind mount validation to accept allowedBindMounts parameter instead of using global config
cmd/socket-proxy/bindmount_test.go Updates tests to pass allowedBindMounts parameter directly
README.md Documents per-container allowlist feature setup and configuration
LICENSE Updates attribution for Apache 2.0 licensed code in new internal packages

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md Outdated
Comment thread internal/docker/api/types/events/events.go Outdated
Comment thread internal/config/config.go Outdated
Comment thread internal/config/config.go
Comment thread README.md Outdated
wollomatic and others added 4 commits November 23, 2025 17:52
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Wolfgang Ellsässer <67168186+wollomatic@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Wolfgang Ellsässer <67168186+wollomatic@users.noreply.github.com>
To fix number of retries when querying Docker Engine API for proxy container summary.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Amanda Wee <amanda@aranel.net>
To fix formatting of SP_PROXYCONTAINERNAME

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Amanda Wee <amanda@aranel.net>
@wollomatic wollomatic merged commit 599e190 into wollomatic:28-fr-support-granular-api-permissions-on-a-per-host-basis-via-allowfrom Nov 29, 2025
1 check passed
@amanda-wee amanda-wee deleted the per-container-allowlists branch January 18, 2026 03:37
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.

3 participants