cors: add Private Network Access support for BYOC deployments#2207
cors: add Private Network Access support for BYOC deployments#2207
Conversation
4f4c6fc to
bbc32fc
Compare
Chrome's Private Network Access (PNA) blocks requests from public origins to private network addresses. This breaks BYOC deployments where users access cloud.redpanda.com but their split-tunnel VPN routes Console traffic to private IP space (e.g., 100.64.0.0/10). Switch from go-chi/cors to rs/cors which has native AllowPrivateNetwork support. Add server.allowPrivateNetwork config option to enable it. Refs: CIAINFRA-2284
bbc32fc to
6a79ea4
Compare
|
@claude Please review |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
|
Claude finished @weeco's task in 1m 38s —— View job Code Review Complete ✓
SummaryThis PR successfully implements Chrome Private Network Access (PNA) support for BYOC deployments. The implementation is clean, well-tested, and solves a real problem where Chrome blocks requests from public origins to private network addresses. Positive Findings
Issues Found1. Missing Default Value Initialization (Minor)Location: The func (s *Server) SetDefaults() {
s.Config.SetDefaults()
// ... existing code ...
s.HTTPServerWriteTimeout = 32 * time.Minute
s.AllowedOrigins = nil
+ s.AllowPrivateNetwork = false // Explicitly set default for clarity
// Debug is enabled by default for backward compatibility.
s.Debug.Enabled = true
// ...
}Recommendation: Add explicit initialization. Fix this → 2. Comment Placement Could Be Clearer (Nitpick)Location: The comment about Current: // AllowPrivateNetwork enables Chrome's Private Network Access support for BYOC
// deployments where browsers access cloud.redpanda.com but VPN routes traffic
// to private IP addresses.
baseRouter.Use(cors.New(cors.Options{
AllowOriginRequestFunc: func(r *http.Request, _ string) bool {
// ...
},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"},
AllowedHeaders: []string{"*"},
AllowCredentials: true,
MaxAge: 300, // Maximum value not ignored by any of major browsers
AllowPrivateNetwork: api.Cfg.REST.AllowPrivateNetwork,
}).Handler)Recommendation: Move the comment inline or closer to the specific field: baseRouter.Use(cors.New(cors.Options{
AllowOriginRequestFunc: func(r *http.Request, _ string) bool {
// ...
},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"},
AllowedHeaders: []string{"*"},
AllowCredentials: true,
MaxAge: 300, // Maximum value not ignored by any of major browsers
// AllowPrivateNetwork enables Chrome's Private Network Access support for BYOC
// deployments where browsers access cloud.redpanda.com but VPN routes traffic
// to private IP addresses. See: https://developer.chrome.com/blog/private-network-access-preflight
AllowPrivateNetwork: api.Cfg.REST.AllowPrivateNetwork,
}).Handler)3. Test Could Be More Comprehensive (Enhancement)Location: The test validates the header is set correctly, but doesn't test:
Recommendation: Consider adding test cases for: // Test regular request (non-OPTIONS) doesn't get PNA header
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
req.Header.Set("Origin", "https://cloud.redpanda.com")
// Should not have PNA header even when enabled
// Test OPTIONS without PNA request header
req := httptest.NewRequest(http.MethodOptions, "/", http.NoBody)
req.Header.Set("Origin", "https://cloud.redpanda.com")
req.Header.Set("Access-Control-Request-Method", "GET")
// No Access-Control-Request-Private-Network header
// Should not have PNA response headerThis would ensure the feature only activates during proper PNA preflight requests. Dependency ChangesThe switch from
Security Considerations✅ Safe: The PNA feature is opt-in (defaults to Recommendations Priority
Verdict✅ LGTM - This PR is ready to merge. The minor issues identified are nice-to-haves but don't block the implementation. The core functionality is solid, well-tested, and solves the stated problem effectively. |
What
Add Chrome Private Network Access (PNA) support via new
server.allowPrivateNetworkconfig option.Why
BYOC users with split-tunnel VPN report Console works in Safari/Firefox but fails in Chrome. Chrome's PNA enforcement blocks requests from public origins (cloud.redpanda.com) to private network addresses (100.64.0.0/10 range used by their VPN).
The fix is to respond with
Access-Control-Allow-Private-Network: trueon CORS preflight requests.Implementation details
Config: New
server.allowPrivateNetworkboolean option (default false). Environment variable:SERVER_ALLOWPRIVATENETWORK.Middleware: The go-chi/cors library lacks native PNA support, so this wraps the CORS handler to inject the response header when browsers send
Access-Control-Request-Private-Network: true.BYOC deployments should set
allowPrivateNetwork: truein their Console configuration.References