Conversation
3b159d0 to
72fa00c
Compare
Adds token vault capabilities which translate auth tokens on the fly, so that the proxees do not actually ever see the real tokens. Flow: ```sh $ ./sandworm token add bearer --host api.github.com --secret "$GITHUB_API_TOKEN" created bearer mapping "api.github.com" for api.github.com * using proxy token "default" $ ./sandworm token list default - bearer api.github.com * ``` ```sh $ ./sandworm --domains api.github.com --translate-tokens time=2026-04-27T09:45:37.688+02:00 level=INFO msg="Starting proxy" addr=0.0.0.0:2137 mode=allow allowed_domains=[api.github.com] allowed_cidrs=[] blocked_domains=[] blocked_cidrs=[] time=2026-04-27T09:45:37.688+02:00 level=INFO msg="Starting admin panel" addr=127.0.0.1:2138 time=2026-04-27T09:45:37.688+02:00 level=INFO msg="Proxy started successfully" port=2137 admin_bind=127.0.0.1 mode=allow domains=[api.github.com] cidrs=[] blocked_domains=[] blocked_cidrs=[] translate_tokens=true translate_tokens_db=./sandworm.db time=2026-04-27T09:52:49.262+02:00 level=INFO msg="Proxy request" method=CONNECT host=api.github.com:443 url=//api.github.com:443 remote=127.0.0.1:58068 time=2026-04-27T09:52:59.189+02:00 level=INFO msg="Proxy request" method=CONNECT host=api.github.com:443 url=//api.github.com:443 remote=127.0.0.1:43258 time=2026-04-27T09:53:02.509+02:00 level=INFO msg="Proxy request" method=CONNECT host=api.github.com:443 url=//api.github.com:443 remote=127.0.0.1:54504 ``` ```sh $ . <(./sandworm token config) $ echo $HTTPS_PROXY http://x:sand_-khhQ0jx0wOPxaoyGajlCdchfBWB-ZXu@127.0.0.1:2137 $ curl -sSfL https://api.github.com/user | jq -r '.name,.company' Piotr Sarna poolside Revoking path: ``` $ ./sandworm token revoke revoked proxy token "default" $ ./sandworm token list default - no mappings $ curl -sSfL https://api.github.com/user | jq -r '.name,.company' curl: (22) The requested URL returned error: 401 ```
|
O_O this is beyond my know how . I will take a look but it will be slow (Update: looked. Still don't think I'm the right person to look. I have nothing useful to offer) |
bronsted
left a comment
There was a problem hiding this comment.
This is very cool.
A few places, it might be a good idea to add a few more tests touching some of the edge cases.
Lets try it!
| } | ||
|
|
||
| func NewProxy(port int, adminBind string, mode string, allowedDomains []string, allowedCIDRs []string, blockedDomains []string, blockedCIDRs []string, ipProxyRange string, ipPorts []int, dnsPort int) *Proxy { | ||
| func NewProxy(port int, adminBind string, mode string, allowedDomains []string, allowedCIDRs []string, blockedDomains []string, blockedCIDRs []string, ipProxyRange string, ipPorts []int, dnsPort int, tokenDB string) (*Proxy, error) { |
There was a problem hiding this comment.
The list of arguments is becoming a bit long. Consider using an argument struct or an option pattern
| } | ||
|
|
||
| proxyURL := fmt.Sprintf("http://x:%s@%s:%d", token.Token, args.BindHost, args.Port) | ||
| fmt.Fprintln(os.Stdout, "# sandworm token config") |
There was a problem hiding this comment.
I guess we might as well use fmt.Println here.
|
|
||
| tokens := store.ListTokens() | ||
| if len(tokens) == 0 { | ||
| fmt.Fprintln(os.Stdout, "no proxy tokens") |
There was a problem hiding this comment.
maybe this should be an error or go to stderr (I am not sure)
| Use: "list", | ||
| Short: "List proxy tokens", | ||
| RunE: func(cmd *cobra.Command, cmdArgs []string) error { | ||
| store, err := proxy.OpenTranslationStore(args.DB) |
There was a problem hiding this comment.
Maybe the body of this function should go into a separate function - that also makes it easier to test
| continue | ||
| } | ||
| for _, value := range values { | ||
| if _, err := fmt.Fprintf(writer, "%s: %s\r\n", name, value); err != nil { |
There was a problem hiding this comment.
I cant remember if HTTP has special format/rules for writing headers - maybe we can use the function in the http package https://cs.opensource.google/go/go/+/refs/tags/go1.26.2:src/net/http/header.go;l=85 - otherwise consider adding a comment why we cannot use it
| defer upstream.Close() | ||
|
|
||
| upstreamURL, err := url.Parse(upstream.URL) | ||
| if err != nil { |
There was a problem hiding this comment.
This is equivalent to:
require.NoError(t, err, "parse upstream url)
| t.Fatalf("create rule: %v", err) | ||
| } | ||
|
|
||
| ctx, cancel := context.WithCancel(context.Background()) |
There was a problem hiding this comment.
Use t.Context() - that will also be automatically cancelled
| } | ||
| for input, want := range cases { | ||
| if got := NormalizePathPattern(input); got != want { | ||
| t.Fatalf("NormalizePathPattern(%q) = %q, want %q", input, got, want) |
There was a problem hiding this comment.
This will fail the whole test on the first failure case. Consider using
assert.Equal(t, got, want, "NormalizePathPattern(%q) = %q, input)
Adds token vault capabilities which translate auth tokens
on the fly, so that the proxees do not actually ever see
the real tokens.
Flow:
Revoking path: