From eb14852d963f4e5704d3f030240d69228fa03246 Mon Sep 17 00:00:00 2001 From: Abhishek Bhaskar Date: Tue, 15 Sep 2026 16:35:23 -0500 Subject: [PATCH] refactor egress allowlist experiment names --- internal/handlers/egress_allowlist.go | 7 +++++-- internal/handlers/egress_allowlist_test.go | 22 ++++++++++++++++++++++ proxy_test.go | 4 ++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/internal/handlers/egress_allowlist.go b/internal/handlers/egress_allowlist.go index 7b9dc39..3e51c05 100644 --- a/internal/handlers/egress_allowlist.go +++ b/internal/handlers/egress_allowlist.go @@ -15,9 +15,12 @@ import ( // Experiment flags (job experiments) that toggle egress filtering. They are // independent: observe logs non-allowlisted hosts, enforce drops them with a // 403. Both default off (fail-open) when absent. +// +// The keys are dash-cased to match the job-details payload: the API serializes +// experiments through the JSON:API adapter, whose default key transform is dash. const ( - egressObserveExperiment = "proxy_egress_observe" - egressEnforceExperiment = "proxy_egress_enforce" + egressObserveExperiment = "proxy-egress-observe" + egressEnforceExperiment = "proxy-egress-enforce" ) // egressHostMetric is the metric emitted for every observed outbound host. The diff --git a/internal/handlers/egress_allowlist_test.go b/internal/handlers/egress_allowlist_test.go index e164916..a739159 100644 --- a/internal/handlers/egress_allowlist_test.go +++ b/internal/handlers/egress_allowlist_test.go @@ -45,6 +45,28 @@ func egressResult(t *testing.T, h *EgressAllowlistHandler, rawURL string) *http. return resp } +// TestEgressAllowlist_DashCasedExperimentKeys guards the dash/underscore key +// contract with the API. The API serializes experiments through the JSON:API +// adapter (default key transform: dash), so the observe/enforce flags arrive in +// the job-details payload as "proxy-egress-observe"/"proxy-egress-enforce". The +// constants must match those literal keys, otherwise the flags never activate. +func TestEgressAllowlist_DashCasedExperimentKeys(t *testing.T) { + require.Equal(t, "proxy-egress-observe", egressObserveExperiment) + require.Equal(t, "proxy-egress-enforce", egressEnforceExperiment) + + experiments := config.Experiments{ + "proxy-egress-observe": true, + "proxy-egress-enforce": false, + } + assert.True(t, experiments.Enabled("proxy-egress-observe"), "dash-keyed observe flag is enabled") + assert.False(t, experiments.Enabled("proxy-egress-enforce")) + assert.False(t, experiments.Enabled("proxy_egress_observe"), "underscore key does not match the forwarded dash key") + + // A handler built from the dash-keyed payload logs but does not block. + h := NewEgressAllowlistHandler(&config.Config{Experiments: experiments}, config.ProxyEnvSettings{}, nil) + assert.Nil(t, egressResult(t, h, "https://evil.com/steal"), "observe mode allows the request through") +} + func TestEgressAllowlist_FailOpenWhenDisabled(t *testing.T) { h := newEgressHandler(false, false, "npm_and_yarn") diff --git a/proxy_test.go b/proxy_test.go index 42e9b02..7fed4ac 100644 --- a/proxy_test.go +++ b/proxy_test.go @@ -69,7 +69,7 @@ func TestProxyEgressAllowlistEnforceBlocks(t *testing.T) { cfg := &config.Config{ CA: testProxyConfig.CA, - Experiments: config.Experiments{"proxy_egress_enforce": true}, + Experiments: config.Experiments{"proxy-egress-enforce": true}, } env := config.ProxyEnvSettings{PackageManager: "npm_and_yarn"} client, proxy := testProxyServerWithEnv(t, env, cfg, nil, upstream.Certificate()) @@ -99,7 +99,7 @@ func TestProxyEgressAllowlistObserveAllows(t *testing.T) { cfg := &config.Config{ CA: testProxyConfig.CA, - Experiments: config.Experiments{"proxy_egress_observe": true}, + Experiments: config.Experiments{"proxy-egress-observe": true}, } env := config.ProxyEnvSettings{PackageManager: "npm_and_yarn"} client, proxy := testProxyServerWithEnv(t, env, cfg, nil, upstream.Certificate())