|
|
|
@@ -770,9 +770,12 @@ func TestBuildContainerEnv_CustomEnvVarsAppended(t *testing.T) {
|
|
|
|
|
// place — i.e. the guard is proven by construction, not by environment
|
|
|
|
|
// accident.
|
|
|
|
|
func TestBuildContainerEnv_StripsSCMWriteTokens(t *testing.T) {
|
|
|
|
|
// GH_TOKEN and GITHUB_TOKEN are preserved when explicitly set (#1687)
|
|
|
|
|
// because they win over the GH_PAT alias. The unconditional strip list
|
|
|
|
|
// therefore excludes them; see TestBuildContainerEnv_GHPATAliasPrecedence
|
|
|
|
|
// for the positive assertion.
|
|
|
|
|
scmTokens := []string{
|
|
|
|
|
"GITEA_TOKEN", "GITHUB_TOKEN", "GH_TOKEN",
|
|
|
|
|
"GITLAB_TOKEN", "GL_TOKEN", "BITBUCKET_TOKEN",
|
|
|
|
|
"GITEA_TOKEN", "GITLAB_TOKEN", "GL_TOKEN", "BITBUCKET_TOKEN",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t.Run("normal path — SCM tokens explicitly set in EnvVars", func(t *testing.T) {
|
|
|
|
@@ -780,6 +783,9 @@ func TestBuildContainerEnv_StripsSCMWriteTokens(t *testing.T) {
|
|
|
|
|
for _, k := range scmTokens {
|
|
|
|
|
envVars[k] = "leaked-write-credential-" + k
|
|
|
|
|
}
|
|
|
|
|
// Explicit GH_TOKEN / GITHUB_TOKEN are now preserved (#1687).
|
|
|
|
|
envVars["GH_TOKEN"] = "explicit-gh-token"
|
|
|
|
|
envVars["GITHUB_TOKEN"] = "explicit-github-token"
|
|
|
|
|
cfg := WorkspaceConfig{
|
|
|
|
|
WorkspaceID: "ws-tenant",
|
|
|
|
|
PlatformURL: "http://localhost:8080",
|
|
|
|
@@ -795,6 +801,13 @@ func TestBuildContainerEnv_StripsSCMWriteTokens(t *testing.T) {
|
|
|
|
|
if !envContains(buildContainerEnv(cfg), "ANTHROPIC_API_KEY=sk-keep") {
|
|
|
|
|
t.Errorf("filter must not strip non-SCM API keys")
|
|
|
|
|
}
|
|
|
|
|
// Explicit GH tokens must be preserved (not stripped).
|
|
|
|
|
if !envContains(buildContainerEnv(cfg), "GH_TOKEN=explicit-gh-token") {
|
|
|
|
|
t.Errorf("explicit GH_TOKEN must be preserved")
|
|
|
|
|
}
|
|
|
|
|
if !envContains(buildContainerEnv(cfg), "GITHUB_TOKEN=explicit-github-token") {
|
|
|
|
|
t.Errorf("explicit GITHUB_TOKEN must be preserved")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("persona-file path — simulates loadPersonaEnvFile merge", func(t *testing.T) {
|
|
|
|
@@ -855,6 +868,106 @@ func TestCPProvisionerEnv_StripsSCMWriteTokens(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TestBuildContainerEnv_GHPATAliasPrecedence asserts that explicit GH_TOKEN /
|
|
|
|
|
// GITHUB_TOKEN in workspace secrets win over the GH_PAT alias (#1687 CR2
|
|
|
|
|
// review_id=5646). The alias must only inject a key when it was NOT explicitly
|
|
|
|
|
// set.
|
|
|
|
|
func TestBuildContainerEnv_GHPATAliasPrecedence(t *testing.T) {
|
|
|
|
|
pat := "ghp_pat_from_secrets"
|
|
|
|
|
explicitGH := "gh_explicit_token"
|
|
|
|
|
explicitGitHub := "github_explicit_token"
|
|
|
|
|
|
|
|
|
|
t.Run("GH_PAT alone → alias both", func(t *testing.T) {
|
|
|
|
|
cfg := WorkspaceConfig{
|
|
|
|
|
WorkspaceID: "ws-x",
|
|
|
|
|
PlatformURL: "http://localhost:8080",
|
|
|
|
|
EnvVars: map[string]string{"GH_PAT": pat},
|
|
|
|
|
}
|
|
|
|
|
env := buildContainerEnv(cfg)
|
|
|
|
|
if !envContains(env, "GH_TOKEN="+pat) {
|
|
|
|
|
t.Errorf("GH_PAT alias must set GH_TOKEN, got %v", env)
|
|
|
|
|
}
|
|
|
|
|
if !envContains(env, "GITHUB_TOKEN="+pat) {
|
|
|
|
|
t.Errorf("GH_PAT alias must set GITHUB_TOKEN, got %v", env)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("explicit GH_TOKEN wins over GH_PAT alias", func(t *testing.T) {
|
|
|
|
|
cfg := WorkspaceConfig{
|
|
|
|
|
WorkspaceID: "ws-x",
|
|
|
|
|
PlatformURL: "http://localhost:8080",
|
|
|
|
|
EnvVars: map[string]string{
|
|
|
|
|
"GH_PAT": pat,
|
|
|
|
|
"GH_TOKEN": explicitGH,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
env := buildContainerEnv(cfg)
|
|
|
|
|
if envContains(env, "GH_TOKEN="+pat) {
|
|
|
|
|
t.Errorf("explicit GH_TOKEN must win over GH_PAT alias, got GH_TOKEN=%q", pat)
|
|
|
|
|
}
|
|
|
|
|
if !envContains(env, "GH_TOKEN="+explicitGH) {
|
|
|
|
|
t.Errorf("explicit GH_TOKEN must be preserved, got %v", env)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("explicit GITHUB_TOKEN wins over GH_PAT alias", func(t *testing.T) {
|
|
|
|
|
cfg := WorkspaceConfig{
|
|
|
|
|
WorkspaceID: "ws-x",
|
|
|
|
|
PlatformURL: "http://localhost:8080",
|
|
|
|
|
EnvVars: map[string]string{
|
|
|
|
|
"GH_PAT": pat,
|
|
|
|
|
"GITHUB_TOKEN": explicitGitHub,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
env := buildContainerEnv(cfg)
|
|
|
|
|
if envContains(env, "GITHUB_TOKEN="+pat) {
|
|
|
|
|
t.Errorf("explicit GITHUB_TOKEN must win over GH_PAT alias, got GITHUB_TOKEN=%q", pat)
|
|
|
|
|
}
|
|
|
|
|
if !envContains(env, "GITHUB_TOKEN="+explicitGitHub) {
|
|
|
|
|
t.Errorf("explicit GITHUB_TOKEN must be preserved, got %v", env)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("explicit both → both preserved, no alias", func(t *testing.T) {
|
|
|
|
|
cfg := WorkspaceConfig{
|
|
|
|
|
WorkspaceID: "ws-x",
|
|
|
|
|
PlatformURL: "http://localhost:8080",
|
|
|
|
|
EnvVars: map[string]string{
|
|
|
|
|
"GH_PAT": pat,
|
|
|
|
|
"GH_TOKEN": explicitGH,
|
|
|
|
|
"GITHUB_TOKEN": explicitGitHub,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
env := buildContainerEnv(cfg)
|
|
|
|
|
if envContains(env, "GH_TOKEN="+pat) {
|
|
|
|
|
t.Errorf("explicit GH_TOKEN must win, got alias value %q", pat)
|
|
|
|
|
}
|
|
|
|
|
if envContains(env, "GITHUB_TOKEN="+pat) {
|
|
|
|
|
t.Errorf("explicit GITHUB_TOKEN must win, got alias value %q", pat)
|
|
|
|
|
}
|
|
|
|
|
if !envContains(env, "GH_TOKEN="+explicitGH) {
|
|
|
|
|
t.Errorf("explicit GH_TOKEN must be preserved, got %v", env)
|
|
|
|
|
}
|
|
|
|
|
if !envContains(env, "GITHUB_TOKEN="+explicitGitHub) {
|
|
|
|
|
t.Errorf("explicit GITHUB_TOKEN must be preserved, got %v", env)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("no GH_PAT → no alias injected", func(t *testing.T) {
|
|
|
|
|
cfg := WorkspaceConfig{
|
|
|
|
|
WorkspaceID: "ws-x",
|
|
|
|
|
PlatformURL: "http://localhost:8080",
|
|
|
|
|
EnvVars: map[string]string{"OTHER": "ok"},
|
|
|
|
|
}
|
|
|
|
|
env := buildContainerEnv(cfg)
|
|
|
|
|
for _, e := range env {
|
|
|
|
|
if strings.HasPrefix(e, "GH_TOKEN=") || strings.HasPrefix(e, "GITHUB_TOKEN=") {
|
|
|
|
|
t.Errorf("no GH_PAT present → no alias should be injected, got %q", e)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func assertNoSCMWriteToken(t *testing.T, env []string, scmTokens []string) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
for _, e := range env {
|
|
|
|
|