From ecf8b85649d4ffbfdad85e5a9ea96f1bbcc3d234 Mon Sep 17 00:00:00 2001 From: Maggie Lou Date: Tue, 16 Sep 2025 16:43:37 -0500 Subject: [PATCH 1/3] Support forwarding unknown HTTP requests from the cache proxy --- .../server/cmd/cache_proxy/cache_proxy.go | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/enterprise/server/cmd/cache_proxy/cache_proxy.go b/enterprise/server/cmd/cache_proxy/cache_proxy.go index 624cb7a2fb7..093abd71bbc 100644 --- a/enterprise/server/cmd/cache_proxy/cache_proxy.go +++ b/enterprise/server/cmd/cache_proxy/cache_proxy.go @@ -6,6 +6,8 @@ import ( "fmt" "net" "net/http" + "net/http/httputil" + "net/url" "os" "github.com/buildbuddy-io/buildbuddy/enterprise/server/action_cache_server_proxy" @@ -50,10 +52,11 @@ import ( ) var ( - listen = flag.String("listen", "0.0.0.0", "The interface to listen on (default: 0.0.0.0)") - port = flag.Int("port", 8080, "The port to listen for HTTP traffic on") - sslPort = flag.Int("ssl_port", 8081, "The port to listen for HTTPS traffic on") - monitoringPort = flag.Int("monitoring_port", 9090, "The port to listen for monitoring traffic on") + listen = flag.String("listen", "0.0.0.0", "The interface to listen on (default: 0.0.0.0)") + port = flag.Int("port", 8080, "The port to listen for HTTP traffic on") + sslPort = flag.Int("ssl_port", 8081, "The port to listen for HTTPS traffic on") + monitoringPort = flag.Int("monitoring_port", 9090, "The port to listen for monitoring traffic on") + httpProxyTarget = flag.String("http_proxy_target", "", "The HTTP target to forward unknown HTTP requests to.") serverType = flag.String("server_type", "cache-proxy", "The server type to match on health checks") @@ -130,6 +133,19 @@ func main() { env.GetMux().Handle("/healthz", env.GetHealthChecker().LivenessHandler()) env.GetMux().Handle("/readyz", env.GetHealthChecker().ReadinessHandler()) + if *httpProxyTarget != "" { + httpProxyUrl, err := url.Parse(*httpProxyTarget) + if err != nil { + log.Fatalf("Could not parse http proxy url: %v", err) + } + proxy := httputil.NewSingleHostReverseProxy(httpProxyUrl) + + // Fallback to forward any unmatched HTTP routes to the proxy target. + env.GetMux().Handle("/", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + proxy.ServeHTTP(w, req) + })) + } + server := &http.Server{ Addr: fmt.Sprintf("%s:%d", *listen, *port), Handler: env.GetMux(), From 11ac1117e8ca3f6561841eb9b362dd4c5f456a9d Mon Sep 17 00:00:00 2001 From: Maggie Lou Date: Thu, 23 Oct 2025 15:46:23 -0500 Subject: [PATCH 2/3] Authenticate http requests --- enterprise/server/cmd/cache_proxy/cache_proxy.go | 5 +++-- enterprise/server/remoteauth/remoteauth.go | 11 ++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/enterprise/server/cmd/cache_proxy/cache_proxy.go b/enterprise/server/cmd/cache_proxy/cache_proxy.go index 093abd71bbc..6d7f962ff82 100644 --- a/enterprise/server/cmd/cache_proxy/cache_proxy.go +++ b/enterprise/server/cmd/cache_proxy/cache_proxy.go @@ -141,9 +141,10 @@ func main() { proxy := httputil.NewSingleHostReverseProxy(httpProxyUrl) // Fallback to forward any unmatched HTTP routes to the proxy target. - env.GetMux().Handle("/", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + proxyHandler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { proxy.ServeHTTP(w, req) - })) + }) + env.GetMux().Handle("/", http_interceptors.WrapAuthenticatedExternalHandler(env, proxyHandler)) } server := &http.Server{ diff --git a/enterprise/server/remoteauth/remoteauth.go b/enterprise/server/remoteauth/remoteauth.go index 71e3ec02bc7..6ca2780947d 100644 --- a/enterprise/server/remoteauth/remoteauth.go +++ b/enterprise/server/remoteauth/remoteauth.go @@ -115,7 +115,16 @@ func (a *RemoteAuthenticator) Auth(w http.ResponseWriter, r *http.Request) error } func (a *RemoteAuthenticator) AuthenticatedHTTPContext(w http.ResponseWriter, r *http.Request) context.Context { - return r.Context() + ctx := r.Context() + + apiKey := r.Header.Get(authutil.APIKeyHeader) + if apiKey == "" { + // Return unauthenticated context if there's no API key in the request headers. + return ctx + } + + ctx = metadata.AppendToOutgoingContext(ctx, authutil.APIKeyHeader, apiKey) + return a.AuthenticatedGRPCContext(ctx) } func (a *RemoteAuthenticator) SSOEnabled() bool { From 2a980d57b000db7d62df74e856df13a580b38306 Mon Sep 17 00:00:00 2001 From: Maggie Lou Date: Thu, 23 Oct 2025 16:15:37 -0500 Subject: [PATCH 3/3] Debug --- enterprise/server/remoteauth/remoteauth.go | 2 +- server/capabilities_filter/BUILD | 1 + server/capabilities_filter/capabilities_filter.go | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/enterprise/server/remoteauth/remoteauth.go b/enterprise/server/remoteauth/remoteauth.go index 6ca2780947d..72a47b33cfc 100644 --- a/enterprise/server/remoteauth/remoteauth.go +++ b/enterprise/server/remoteauth/remoteauth.go @@ -124,7 +124,7 @@ func (a *RemoteAuthenticator) AuthenticatedHTTPContext(w http.ResponseWriter, r } ctx = metadata.AppendToOutgoingContext(ctx, authutil.APIKeyHeader, apiKey) - return a.AuthenticatedGRPCContext(ctx) + return ctx } func (a *RemoteAuthenticator) SSOEnabled() bool { diff --git a/server/capabilities_filter/BUILD b/server/capabilities_filter/BUILD index 9505ad36a76..c4b6751fbe3 100644 --- a/server/capabilities_filter/BUILD +++ b/server/capabilities_filter/BUILD @@ -10,6 +10,7 @@ go_library( "//server/environment", "//server/util/capabilities", "//server/util/claims", + "//server/util/log", "//server/util/status", ], ) diff --git a/server/capabilities_filter/capabilities_filter.go b/server/capabilities_filter/capabilities_filter.go index 1e05923ae9b..96052eab276 100644 --- a/server/capabilities_filter/capabilities_filter.go +++ b/server/capabilities_filter/capabilities_filter.go @@ -9,6 +9,7 @@ import ( "github.com/buildbuddy-io/buildbuddy/server/environment" "github.com/buildbuddy-io/buildbuddy/server/util/capabilities" "github.com/buildbuddy-io/buildbuddy/server/util/claims" + "github.com/buildbuddy-io/buildbuddy/server/util/log" "github.com/buildbuddy-io/buildbuddy/server/util/status" cappb "github.com/buildbuddy-io/buildbuddy/proto/capability" @@ -283,6 +284,7 @@ func AuthorizeRPC(ctx context.Context, env environment.Env, rpcName string) erro } if !slices.Contains(AllowedRPCs(ctx, env, groupID), rpcName) { + log.Warningf("Authorize RPC blocking for %s %s", rpcName, groupID) return status.PermissionDeniedError("permission denied") }