Skip to content

feat: support use allow* multiple times in env, flag and docker labels#86

Merged
wollomatic merged 10 commits intowollomatic:feature/99-use-allow-multiple-timesfrom
qianlongzt:main
Mar 1, 2026
Merged

feat: support use allow* multiple times in env, flag and docker labels#86
wollomatic merged 10 commits intowollomatic:feature/99-use-allow-multiple-timesfrom
qianlongzt:main

Conversation

@qianlongzt
Copy link

@qianlongzt qianlongzt commented Feb 13, 2026

fix: #99

I test env, flag and docker labels

SP_ALLOW_GET=/version3 SP_ALLOW_GET_aal=/version4 ./socket-proxy '-allowGET=/_ping' '-allowGET=/exec/.*' '-allowGET=/version'
time=2026-02-13T20:24:50.504+08:00 level=INFO msg="starting socket-proxy" version=dev os=linux arch=amd64 runtime=go1.26.0 URL=github.com/wollomatic/socket-proxy
time=2026-02-13T20:24:50.505+08:00 level=INFO msg="configuration info" socketpath=/var/run/docker.sock listenaddress=127.0.0.1:2375 loglevel=INFO logjson=false allowfrom=127.0.0.1/32 shutdowngracetime=10
time=2026-02-13T20:24:50.505+08:00 level=INFO msg="watchdog disabled"
Default request allowlist:
   Method   Regex
   GET      [^/version4$ ^/version3$ ^/_ping$ ^/exec/.*$ ^/version$]
time=2026-02-13T20:24:50.505+08:00 level=INFO msg="socket-proxy running and listening..."
^Zfish: Job 1, 'SP_ALLOW_GET=/version3 SP_ALLOW…' has stopped
ubuntu@tx-hk-1 ~> bg
Send job 1 'SP_ALLOW_GET=/version3 SP_ALLOW_GET_aal=/version4 ./socket-proxy '-allowGET=/_ping' '-allowGET=/exec/.*' '-allowGET=/version'' to background
ubuntu@tx-hk-1 ~> curl http://127.0.0.1:2375/version4
{"message":"page not found"}
ubuntu@tx-hk-1 ~> curl http://127.0.0.1:2375/version3
{"message":"page not found"}
ubuntu@tx-hk-1 ~> curl http://127.0.0.1:2375/version
{"Platform":{"Name":"Docker Engine - Community"},"Version":"29.2.1","ApiVersion":"1.53","MinAPIVersion":"1.44","Os":"linux","Arch":"amd64","Components":[{"Name":"Engine","Version":"29.2.1","Details":{"ApiVersion":"1.53","Arch":"amd64","BuildTime":"2026-02-02T17:17:19.000050134+00:00","Experimental":"false","GitCommit":"6bc6209","GoVersion":"go1.25.6","KernelVersion":"6.17.0-14-generic","MinAPIVersion":"1.44","Os":"linux"}},{"Name":"containerd","Version":"v2.2.1","Details":{"GitCommit":"dea7da592f5d1d2b7755e3a161be07f43fad8f75"}},{"Name":"runc","Version":"1.3.4","Details":{"GitCommit":"v1.3.4-0-gd6d73eb8"}},{"Name":"docker-init","Version":"0.19.0","Details":{"GitCommit":"de40ad0"}}],"GitCommit":"6bc6209","GoVersion":"go1.25.6","KernelVersion":"6.17.0-14-generic","BuildTime":"2026-02-02T17:17:19.000050134+00:00"}
ubuntu@tx-hk-1 ~> curl http://127.0.0.1:2375/xxx
time=2026-02-13T20:25:07.347+08:00 level=WARN msg="blocked request" reason="path not allowed" method=GET URL=/xxx client=127.0.0.1:49310 response=403
Forbidden
services:
  alpine:
    image: alpine
    network_mode: bridge
    command:
    - sleep
    - "3600"
    labels:
      - 'socket-proxy.allow.get=/version'
      - 'socket-proxy.allow.get.0=/_ping'
      - 'socket-proxy.allow.get.1=/_ping2'
time=2026-02-13T21:21:12.081+08:00 level=INFO msg="removed allowlist for container" id=b0eecf7e611e ip=172.17.0.6
Request allowlist for d7be59ae6bfe (172.17.0.6):
   Method   Regex
   GET      [^/_ping2$ ^/version$]
time=2026-02-13T21:21:37.958+08:00 level=INFO msg="removed allowlist for container" id=d7be59ae6bfe ip=172.17.0.6
Request allowlist for 34e2ab1d42fd (172.17.0.6):
   Method   Regex
   GET      [^/version$ ^/_ping$ ^/_ping2$]

Summary by CodeRabbit

Release Notes

  • New Features

    • Support for multiple allowlist entries per HTTP method via Docker labels, environment variables, and command-line parameters.
  • Documentation

    • Updated README with expanded examples demonstrating multiple allowances in various configuration formats.
  • Tests

    • Added unit tests for configuration parsing and environment variable handling.


> [!NOTE]
> Starting with version 1.6.0, the socket-proxy container image is also available on GHCR.
> Starting with version todo, the socket-proxy can set multiple times -allow* in params or environment of docker labels
Copy link
Author

Choose a reason for hiding this comment

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

TODO, version

@qianlongzt qianlongzt marked this pull request as draft February 13, 2026 13:03
@qianlongzt qianlongzt marked this pull request as ready for review February 13, 2026 13:24
@wollomatic wollomatic changed the base branch from main to feature/99-use-allow-multiple-times February 27, 2026 17:02
@wollomatic
Copy link
Owner

wollomatic commented Feb 27, 2026

@coderabbitai review the PR

@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Tip

For best results, initiate chat on the files or code changes.

@wollomatic Hello! How can I help you with this PR? I can:

  • Review the changes in this pull request
  • Answer questions about the code or implementation
  • Generate tests or documentation
  • Analyze specific files or code sections
  • Help with any other task related to this PR

Just let me know what you'd like me to do!

@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

@wollomatic: I'll review the changes in this PR now. Based on the objectives, this PR adds support for using allow* directives multiple times across environment variables, flags, and Docker labels to fix issue #99. I can see from your test results that the functionality is working as expected - multiple allowlist entries are being combined correctly.

Let me perform a comprehensive review of the code changes.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This pull request introduces support for specifying multiple allow rules per HTTP method instead of requiring a single regex pattern. It modifies the configuration structure to store multiple compiled regular expressions per method, adds parsing helpers for environment variables and command-line parameters, and updates the request matching logic to iterate over all applicable patterns.

Changes

Cohort / File(s) Summary
Documentation
README.md
Added notes and examples demonstrating multiple allow parameters for a single HTTP method via command-line (e.g., SP_ALLOW_GET_2) and environment-variable forms, plus Traefik label examples with indexed entries.
HTTP Request Matching
cmd/socket-proxy/handlehttprequest.go
Introduced matchURL helper function that iterates over a slice of compiled regex patterns and returns true if any pattern matches the request URI, replacing direct regex matching logic.
Configuration Structure
internal/config/config.go
Changed AllowList.AllowedRequests field type from map[string]*regexp.Regexp to map[string][]*regexp.Regexp to support multiple patterns per HTTP method; updated initialization, label extraction, and default allowlist population to aggregate regexes into slices per method.
Configuration Tests
internal/config/config_test.go
Added unit tests validating label extraction for socket-proxy.allow patterns with method indices, error handling for invalid regex, and filtering of non-matching labels.
Environment Variable Parsing
internal/config/env.go, internal/config/env_test.go
Introduced getAllowFromEnv function to parse SP_ALLOW_* prefixed environment strings (including indexed variants) into a map of HTTP methods to regex pattern slices; included table-driven tests covering single/multiple entries and methods.
Parameter Collection
internal/config/param.go
Added private arrayParams type implementing flag.Value interface to support multi-value flag collection via repeated command-line parameters, with helper type param tracking value origin (environment or parameter).

Sequence Diagram

sequenceDiagram
    actor User
    participant Parser as Config Parser
    participant Env as Environment<br/>Parser
    participant Params as Param<br/>Collector
    participant Compiler as Regex<br/>Compiler
    participant Config as AllowList<br/>Config
    participant Handler as Request<br/>Handler
    participant Matcher as URL<br/>Matcher

    User->>Parser: Load configuration
    activate Parser
    Parser->>Env: Parse SP_ALLOW_* variables
    activate Env
    Env->>Env: Extract method & patterns<br/>(SP_ALLOW_GET, GET_1, etc.)
    Env-->>Parser: map[method][]patterns
    deactivate Env
    
    Parser->>Params: Collect flag values<br/>(-allowGET, -allowGET, ...)
    activate Params
    Params->>Params: Aggregate by method
    Params-->>Parser: map[method][]patterns
    deactivate Params
    
    Parser->>Compiler: Compile patterns to regex
    activate Compiler
    Compiler->>Compiler: For each method,<br/>compile all patterns
    Compiler-->>Parser: map[method][]*Regexp
    deactivate Compiler
    
    Parser->>Config: Populate AllowedRequests
    activate Config
    Config->>Config: Store as slices per method
    deactivate Config
    Parser-->>User: Config ready
    deactivate Parser
    
    User->>Handler: Send HTTP request
    activate Handler
    Handler->>Matcher: Match request path
    activate Matcher
    Matcher->>Matcher: Get regex slice for method
    Matcher->>Matcher: Iterate & test patterns
    Matcher-->>Handler: Match found?
    deactivate Matcher
    Handler-->>User: Allow or deny request
    deactivate Handler
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

A rabbit hops through rules with glee,
Multiple patterns, now we're free!
No more tangled regex, side by side,
Each allow can take a gentle stride. 🐰✨
Simpler rules for hearts of code!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding support for using allow* directives multiple times across environment variables, flags, and Docker labels.
Linked Issues check ✅ Passed The pull request fully implements the requested feature from issue #99: allowing allow* directives to be specified multiple times across environment variables, CLI flags, and Docker labels, with entries being combined into effective allowlists.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing support for multiple allow* directives as specified in issue #99; no unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
README.md (1)

30-30: ⚠️ Potential issue | 🟡 Minor

Replace the placeholder version and reword this note.

Line 30 still uses todo and the sentence is unclear. Please replace it with the concrete release version and clearer wording (for example, “Starting with version X.Y.Z, -allow* can be specified multiple times via CLI flags, environment variables, and Docker labels.”).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 30, Replace the placeholder "todo" with the actual release
version (e.g., X.Y.Z) and rewrite the sentence to be clearer: change the line
containing "todo" and the phrase "-allow*" so it reads something like “Starting
with version X.Y.Z, `-allow*` can be specified multiple times via CLI flags,
environment variables, and Docker labels.” Ensure you update the exact string
that currently contains "todo" and the `-allow*` token.
🧹 Nitpick comments (3)
README.md (1)

97-103: Tighten wording in the new repeated-allow examples.

Line 97 and Line 102 read awkwardly (“allow use GET multiple times”). Suggest rephrasing to “GET can be specified multiple times” for readability and consistency.

Proposed docs wording tweak
-+ `'-allowGET=/version' '-allowGET=/_ping'` allow use `GET` multiple times
++ `'-allowGET=/version' '-allowGET=/_ping'` shows that `GET` can be specified multiple times.

-+ `'SP_ALLOW_GET="/version" SP_ALLOW_GET_2=/_ping'` allow use `GET` multiple times
++ `'SP_ALLOW_GET="/version" SP_ALLOW_GET_2=/_ping'` shows that `GET` can be specified multiple times.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 97 - 103, Update the README examples wording that
currently says "allow use `GET` multiple times" to a clearer phrase like "`GET`
can be specified multiple times" wherever that exact text appears (e.g.,
adjacent to the quoted examples with `-allowGET=/version` / `-allowGET=/_ping`
and the env examples
`SP_ALLOW_GET="/v1\..{1,2}/(version|containers/.*|events.*)"` and
`SP_ALLOW_GET="/version" SP_ALLOW_GET_2=/_ping"`); keep the surrounding example
strings (`SP_ALLOW_GET`, `SP_ALLOW_HEAD`, and the quoted patterns) unchanged,
only replace the awkward sentence to improve readability and consistency.
internal/config/env.go (1)

7-7: Consider using camelCase for the unexported constant.

Go convention prefers camelCase for unexported identifiers. Consider renaming sp_allowPrefix to spAllowPrefix.

♻️ Suggested change
-const sp_allowPrefix = "SP_ALLOW_"
+const spAllowPrefix = "SP_ALLOW_"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/config/env.go` at line 7, The constant sp_allowPrefix uses
snake_case but Go convention prefers camelCase for unexported identifiers;
rename the identifier to spAllowPrefix (update its declaration and all
references to sp_allowPrefix in this package, e.g., in internal/config/env.go)
to follow Go naming conventions and keep it unexported.
internal/config/config_test.go (1)

47-58: Consider explicitly setting wantErr: false for completeness.

While the zero value for bool is false, explicitly setting wantErr: false improves readability and makes the test expectation clearer.

💡 Suggested change
 		{
 			name: "non-allow labels are ignored",
 			cntr: container.Summary{
 				Labels: map[string]string{
 					"socket-proxy.allow.get": "regex1",
 					"other.label":            "value",
 				},
 			},
 			want: map[string][]*regexp.Regexp{
 				"GET": {regexp.MustCompile("^regex1$")},
 			},
+			want2:   nil,
+			wantErr: false,
 		},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/config/config_test.go` around lines 47 - 58, Add an explicit
wantErr: false to the table-driven test case named "non-allow labels are
ignored" so the expectation is clear; locate the test case that builds
container.Summary with Labels ("socket-proxy.allow.get": "regex1",
"other.label": "value") and add the wantErr: false field alongside the existing
want map (map[string][]*regexp.Regexp{"GET": {regexp.MustCompile("^regex1$")}}).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/config/config_test.go`:
- Around line 72-74: The test currently uses reflect.DeepEqual to compare maps
of *regexp.Regexp which is brittle; replace that comparison with a helper that
compares regex pattern strings instead (e.g., add a regexMapsEqual function that
iterates the map returned by extractLabelData and compares lengths and each
regexp's String() values), then use regexMapsEqual(got, tt.want) in place of
reflect.DeepEqual; ensure the helper handles nil/length mismatches and preserves
ordering when comparing slices for each key.

In `@internal/config/config.go`:
- Around line 164-173: Call getAllowFromEnv(os.Environ()) once before the loop
and reuse its returned map instead of invoking it inside each iteration;
specifically, compute allowFromEnv := getAllowFromEnv(os.Environ()) prior to
iterating over mr, then inside the for i := range mr loop use that allowFromEnv
to lookup values and append param{value: v, from: fromEnv} to mr[i].regexStrings
— this avoids repeated work and preserves existing behavior.

In `@internal/config/env_test.go`:
- Around line 25-34: The test cases in env_test.go define two table entries with
the identical name field "multiple entries for one method"; rename the second
test's name to a distinct string (e.g. "multiple entries for one method with _2"
or "multiple entries for one method (alt)") so each table-driven test case (the
name fields used in the test struct) is unique and test output can be
disambiguated when running the tests.

In `@README.md`:
- Line 243: The Markdown table row for `-shutdowngracetime` /
`SP_SHUTDOWNGRACETIME` has an extra trailing cell delimiter (`|  |`) which
causes a column mismatch (MD056); edit the README table row containing
`-shutdowngracetime` and `SP_SHUTDOWNGRACETIME` to remove the extra trailing `| 
|` so the row has the same number of cells as the header and other rows.

---

Duplicate comments:
In `@README.md`:
- Line 30: Replace the placeholder "todo" with the actual release version (e.g.,
X.Y.Z) and rewrite the sentence to be clearer: change the line containing "todo"
and the phrase "-allow*" so it reads something like “Starting with version
X.Y.Z, `-allow*` can be specified multiple times via CLI flags, environment
variables, and Docker labels.” Ensure you update the exact string that currently
contains "todo" and the `-allow*` token.

---

Nitpick comments:
In `@internal/config/config_test.go`:
- Around line 47-58: Add an explicit wantErr: false to the table-driven test
case named "non-allow labels are ignored" so the expectation is clear; locate
the test case that builds container.Summary with Labels
("socket-proxy.allow.get": "regex1", "other.label": "value") and add the
wantErr: false field alongside the existing want map
(map[string][]*regexp.Regexp{"GET": {regexp.MustCompile("^regex1$")}}).

In `@internal/config/env.go`:
- Line 7: The constant sp_allowPrefix uses snake_case but Go convention prefers
camelCase for unexported identifiers; rename the identifier to spAllowPrefix
(update its declaration and all references to sp_allowPrefix in this package,
e.g., in internal/config/env.go) to follow Go naming conventions and keep it
unexported.

In `@README.md`:
- Around line 97-103: Update the README examples wording that currently says
"allow use `GET` multiple times" to a clearer phrase like "`GET` can be
specified multiple times" wherever that exact text appears (e.g., adjacent to
the quoted examples with `-allowGET=/version` / `-allowGET=/_ping` and the env
examples `SP_ALLOW_GET="/v1\..{1,2}/(version|containers/.*|events.*)"` and
`SP_ALLOW_GET="/version" SP_ALLOW_GET_2=/_ping"`); keep the surrounding example
strings (`SP_ALLOW_GET`, `SP_ALLOW_HEAD`, and the quoted patterns) unchanged,
only replace the awkward sentence to improve readability and consistency.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad94676 and f6fee10.

📒 Files selected for processing (7)
  • README.md
  • cmd/socket-proxy/handlehttprequest.go
  • internal/config/config.go
  • internal/config/config_test.go
  • internal/config/env.go
  • internal/config/env_test.go
  • internal/config/param.go

@qianlongzt
Copy link
Author

@wollomatic I’ve fixed all the comments from CodeRabbit. Is this ready to merge?

@wollomatic
Copy link
Owner

Hi @qianlongzt, thank you very much! I have planned to check this later and to create a build for testing.

@wollomatic wollomatic merged commit efea0f9 into wollomatic:feature/99-use-allow-multiple-times Mar 1, 2026
3 checks passed
@wollomatic
Copy link
Owner

Container image to test: ghcr.io/wollomatic/socket-proxy:testing-efea0f9cc41ba59fc0154e492f7118407e65e636

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.

[feature]: Support use allow* multiple times

2 participants