(t *testing.T)
| 1936 | } |
| 1937 | |
| 1938 | func TestEnvironmentDoNotLeak(t *testing.T) { |
| 1939 | // NOTE: Cannot use t.Parallel() here because subtests use t.Setenv which requires sequential execution. |
| 1940 | |
| 1941 | // Test that environment variables containing API keys/tokens are not leaked to upstream requests. |
| 1942 | // See https://github.com/coder/aibridge/issues/60. |
| 1943 | testCases := []struct { |
| 1944 | name string |
| 1945 | fixture []byte |
| 1946 | path string |
| 1947 | envVars map[string]string |
| 1948 | headerName string |
| 1949 | }{ |
| 1950 | { |
| 1951 | name: config.ProviderAnthropic, |
| 1952 | fixture: fixtures.AntSimple, |
| 1953 | path: pathAnthropicMessages, |
| 1954 | envVars: map[string]string{ |
| 1955 | "ANTHROPIC_AUTH_TOKEN": "should-not-leak", |
| 1956 | }, |
| 1957 | headerName: "Authorization", // We only send through the X-Api-Key, so this one should not be present. |
| 1958 | }, |
| 1959 | { |
| 1960 | name: config.ProviderOpenAI, |
| 1961 | fixture: fixtures.OaiChatSimple, |
| 1962 | path: pathOpenAIChatCompletions, |
| 1963 | envVars: map[string]string{ |
| 1964 | "OPENAI_ORG_ID": "should-not-leak", |
| 1965 | }, |
| 1966 | headerName: "OpenAI-Organization", |
| 1967 | }, |
| 1968 | } |
| 1969 | |
| 1970 | for _, tc := range testCases { |
| 1971 | t.Run(tc.name, func(t *testing.T) { |
| 1972 | // NOTE: Cannot use t.Parallel() here because t.Setenv requires sequential execution. |
| 1973 | |
| 1974 | ctx, cancel := context.WithTimeout(t.Context(), testutil.WaitLong) |
| 1975 | t.Cleanup(cancel) |
| 1976 | |
| 1977 | fix := fixtures.Parse(t, tc.fixture) |
| 1978 | upstream := newMockUpstream(ctx, t, newFixtureResponse(fix)) |
| 1979 | |
| 1980 | // Set environment variables that the SDK would automatically read. |
| 1981 | // These should NOT leak into upstream requests. |
| 1982 | for key, val := range tc.envVars { |
| 1983 | t.Setenv(key, val) |
| 1984 | } |
| 1985 | |
| 1986 | bridgeServer := newBridgeTestServer(ctx, t, upstream.URL) |
| 1987 | |
| 1988 | resp, err := bridgeServer.makeRequest(t, http.MethodPost, tc.path, fix.Request()) |
| 1989 | require.NoError(t, err) |
| 1990 | defer resp.Body.Close() |
| 1991 | require.Equal(t, http.StatusOK, resp.StatusCode) |
| 1992 | |
| 1993 | // Verify that environment values did not leak. |
| 1994 | received := upstream.receivedRequests() |
| 1995 | require.Len(t, received, 1) |
nothing calls this directly
no test coverage detected