diff --git a/workspace-server/internal/handlers/workspace_provision.go b/workspace-server/internal/handlers/workspace_provision.go index f023e240..4c954008 100644 --- a/workspace-server/internal/handlers/workspace_provision.go +++ b/workspace-server/internal/handlers/workspace_provision.go @@ -439,12 +439,12 @@ func (h *WorkspaceHandler) ensureDefaultConfig(workspaceID string, payload model // Model always at top level — config.py reads raw["model"] for all runtimes. configYAML += fmt.Sprintf("model: %s\n", quoteModel) - // Add required_env based on runtime — preflight checks these are set via secrets API. + // Add runtime_config. required_env is intentionally omitted — the + // platform injects secrets at container-start time via the secrets API, + // and preflight already validates that the env vars are present before + // the agent loop starts. Hardcoding token names here caused #1028 + // (expired CLAUDE_CODE_OAUTH_TOKEN baked into config.yaml). switch runtime { - case "claude-code": - configYAML += "runtime_config:\n required_env:\n - CLAUDE_CODE_OAUTH_TOKEN\n timeout: 0\n" - case "codex": - configYAML += "runtime_config:\n required_env:\n - OPENAI_API_KEY\n timeout: 0\n" case "langgraph", "deepagents": // These runtimes read API keys from env directly, no runtime_config needed. default: diff --git a/workspace-server/internal/handlers/workspace_provision_test.go b/workspace-server/internal/handlers/workspace_provision_test.go index 3dafa96f..9eda95df 100644 --- a/workspace-server/internal/handlers/workspace_provision_test.go +++ b/workspace-server/internal/handlers/workspace_provision_test.go @@ -247,11 +247,10 @@ func TestEnsureDefaultConfig_ClaudeCode(t *testing.T) { if !contains(content, "runtime_config:") { t.Errorf("config.yaml should have runtime_config section for claude-code, got:\n%s", content) } - if !contains(content, "required_env:") { - t.Errorf("config.yaml should have required_env for claude-code, got:\n%s", content) - } - if !contains(content, "CLAUDE_CODE_OAUTH_TOKEN") { - t.Errorf("config.yaml should require CLAUDE_CODE_OAUTH_TOKEN, got:\n%s", content) + // required_env is no longer hardcoded — tokens are injected at runtime + // via the secrets API (#1028). + if contains(content, "CLAUDE_CODE_OAUTH_TOKEN") { + t.Errorf("config.yaml should NOT hardcode CLAUDE_CODE_OAUTH_TOKEN (fix #1028), got:\n%s", content) } // Should NOT have .auth-token file if _, ok := files[".auth-token"]; ok {