diff --git a/internal/infra/config.go b/internal/infra/config.go index 2d75689c..412d32d4 100644 --- a/internal/infra/config.go +++ b/internal/infra/config.go @@ -9,6 +9,7 @@ const ConfigFilePath = "/config.json" type Config struct { Credentials []model.Credential `json:"all_credentials"` CA CertificateAuthority `json:"ca"` + Experiments model.Experiment `json:"experiments,omitempty"` } // CertificateAuthority includes the MITM CA certificate and private key diff --git a/internal/infra/proxy.go b/internal/infra/proxy.go index f3646334..1985b9a4 100644 --- a/internal/infra/proxy.go +++ b/internal/infra/proxy.go @@ -42,6 +42,7 @@ func NewProxy(ctx context.Context, cli *client.Client, params *RunParams, nets * proxyConfig := &Config{ Credentials: params.Creds, CA: ca, + Experiments: params.Job.Experiments, } hostCfg := &container.HostConfig{ @@ -79,7 +80,7 @@ func NewProxy(ctx context.Context, cli *client.Client, params *RunParams, nets * } config := &container.Config{ Image: params.ProxyImage, - Env: proxyEnv(params.ApiUrl), + Env: proxyEnv(params.ApiUrl, params.Job.PackageManager), Entrypoint: []string{ "sh", "-c", "update-ca-certificates && /dependabot-proxy", }, @@ -133,7 +134,7 @@ func NewProxy(ctx context.Context, cli *client.Client, params *RunParams, nets * } // proxyEnv builds the environment variables passed to the proxy container. -func proxyEnv(apiURL string) []string { +func proxyEnv(apiURL, packageManager string) []string { env := []string{ "HTTP_PROXY=" + os.Getenv("HTTP_PROXY"), "HTTPS_PROXY=" + os.Getenv("HTTPS_PROXY"), @@ -143,6 +144,8 @@ func proxyEnv(apiURL string) []string { "LOG_RESPONSE_BODY_ON_AUTH_FAILURE=true", "ACTIONS_ID_TOKEN_REQUEST_TOKEN=" + os.Getenv("ACTIONS_ID_TOKEN_REQUEST_TOKEN"), "ACTIONS_ID_TOKEN_REQUEST_URL=" + os.Getenv("ACTIONS_ID_TOKEN_REQUEST_URL"), + // PACKAGE_MANAGER lets the proxy load the right per-ecosystem egress allowlist defaults. + "PACKAGE_MANAGER=" + packageManager, } // Only forward JOB_TOKEN and DEPENDABOT_API_URL when JOB_TOKEN is set on the // host. The proxy uses DEPENDABOT_API_URL to decide which host to inject the diff --git a/internal/infra/proxy_test.go b/internal/infra/proxy_test.go index 8e66ed9e..80be57aa 100644 --- a/internal/infra/proxy_test.go +++ b/internal/infra/proxy_test.go @@ -20,7 +20,7 @@ func Test_proxyEnv_ProxyCache(t *testing.T) { t.Run("uses host PROXY_CACHE when set", func(t *testing.T) { t.Setenv("PROXY_CACHE", "false") - env := proxyEnv("") + env := proxyEnv("", "") value, ok := envValue(env, "PROXY_CACHE") if !ok { @@ -35,7 +35,7 @@ func Test_proxyEnv_ProxyCache(t *testing.T) { t.Setenv("PROXY_CACHE", "placeholder") os.Unsetenv("PROXY_CACHE") - env := proxyEnv("") + env := proxyEnv("", "") value, ok := envValue(env, "PROXY_CACHE") if !ok { @@ -49,7 +49,7 @@ func Test_proxyEnv_ProxyCache(t *testing.T) { t.Run("falls back to true when host PROXY_CACHE is empty", func(t *testing.T) { t.Setenv("PROXY_CACHE", "") - env := proxyEnv("") + env := proxyEnv("", "") value, ok := envValue(env, "PROXY_CACHE") if !ok { @@ -61,11 +61,37 @@ func Test_proxyEnv_ProxyCache(t *testing.T) { }) } +func Test_proxyEnv_PackageManager(t *testing.T) { + t.Run("passes PACKAGE_MANAGER from the parameter", func(t *testing.T) { + env := proxyEnv("", "go_modules") + + value, ok := envValue(env, "PACKAGE_MANAGER") + if !ok { + t.Fatal("expected PACKAGE_MANAGER to be present in proxy env") + } + if value != "go_modules" { + t.Errorf("expected PACKAGE_MANAGER to be %q, got %q", "go_modules", value) + } + }) + + t.Run("sets an empty PACKAGE_MANAGER when not provided", func(t *testing.T) { + env := proxyEnv("", "") + + value, ok := envValue(env, "PACKAGE_MANAGER") + if !ok { + t.Fatal("expected PACKAGE_MANAGER to be present in proxy env") + } + if value != "" { + t.Errorf("expected PACKAGE_MANAGER to be empty, got %q", value) + } + }) +} + func Test_proxyEnv_OpenSSLForceFIPSMode(t *testing.T) { t.Run("passes OPENSSL_FORCE_FIPS_MODE from environment", func(t *testing.T) { t.Setenv("OPENSSL_FORCE_FIPS_MODE", "1") - env := proxyEnv("") + env := proxyEnv("", "") value, ok := envValue(env, "OPENSSL_FORCE_FIPS_MODE") if !ok { @@ -80,7 +106,7 @@ func Test_proxyEnv_OpenSSLForceFIPSMode(t *testing.T) { t.Setenv("OPENSSL_FORCE_FIPS_MODE", "placeholder") os.Unsetenv("OPENSSL_FORCE_FIPS_MODE") - env := proxyEnv("") + env := proxyEnv("", "") if _, ok := envValue(env, "OPENSSL_FORCE_FIPS_MODE"); ok { t.Error("expected OPENSSL_FORCE_FIPS_MODE to be absent from proxy env when host has it unset") @@ -92,7 +118,7 @@ func Test_proxyEnv_JobToken(t *testing.T) { t.Run("passes JOB_TOKEN from environment", func(t *testing.T) { t.Setenv("JOB_TOKEN", "super-secret-token") - env := proxyEnv("") + env := proxyEnv("", "") value, ok := envValue(env, "JOB_TOKEN") if !ok { @@ -107,7 +133,7 @@ func Test_proxyEnv_JobToken(t *testing.T) { t.Setenv("JOB_TOKEN", "placeholder") os.Unsetenv("JOB_TOKEN") - env := proxyEnv("") + env := proxyEnv("", "") if _, ok := envValue(env, "JOB_TOKEN"); ok { t.Error("expected JOB_TOKEN to be absent from proxy env when host has it unset") @@ -117,7 +143,7 @@ func Test_proxyEnv_JobToken(t *testing.T) { t.Run("omits JOB_TOKEN when set to empty", func(t *testing.T) { t.Setenv("JOB_TOKEN", "") - env := proxyEnv("") + env := proxyEnv("", "") if _, ok := envValue(env, "JOB_TOKEN"); ok { t.Error("expected JOB_TOKEN to be absent from proxy env when host has it empty") @@ -129,7 +155,7 @@ func Test_proxyEnv_DependabotAPIURL(t *testing.T) { t.Run("sets DEPENDABOT_API_URL from the apiURL parameter when JOB_TOKEN is set", func(t *testing.T) { t.Setenv("JOB_TOKEN", "super-secret-token") - env := proxyEnv("https://api.example.com") + env := proxyEnv("https://api.example.com", "") value, ok := envValue(env, "DEPENDABOT_API_URL") if !ok { @@ -144,7 +170,7 @@ func Test_proxyEnv_DependabotAPIURL(t *testing.T) { t.Setenv("JOB_TOKEN", "placeholder") os.Unsetenv("JOB_TOKEN") - env := proxyEnv("https://api.example.com") + env := proxyEnv("https://api.example.com", "") if _, ok := envValue(env, "DEPENDABOT_API_URL"); ok { t.Error("expected DEPENDABOT_API_URL to be absent when JOB_TOKEN is unset") @@ -154,7 +180,7 @@ func Test_proxyEnv_DependabotAPIURL(t *testing.T) { t.Run("omits DEPENDABOT_API_URL when JOB_TOKEN is empty", func(t *testing.T) { t.Setenv("JOB_TOKEN", "") - env := proxyEnv("https://api.example.com") + env := proxyEnv("https://api.example.com", "") if _, ok := envValue(env, "DEPENDABOT_API_URL"); ok { t.Error("expected DEPENDABOT_API_URL to be absent when JOB_TOKEN is empty")