Skip to content

feat: add Codex AI proxy credential fallback#865

Merged
simple-agent-manager[bot] merged 8 commits intomainfrom
sam/wp3-codex-credential-injection-01kqge
May 1, 2026
Merged

feat: add Codex AI proxy credential fallback#865
simple-agent-manager[bot] merged 8 commits intomainfrom
sam/wp3-codex-credential-injection-01kqge

Conversation

@simple-agent-manager
Copy link
Copy Markdown
Contributor

Summary

  • When no user-provided OpenAI API key exists for the openai-codex agent type, inject SAM's AI proxy as the credential source for zero-key onboarding
  • Mirrors the Claude Code fallback (PR feat: add Claude Code AI proxy credential fallback #862) but for OpenAI/Codex: returns provider: 'openai-proxy' with baseURL: https://api.{domain}/ai/v1
  • VM agent injects OPENAI_BASE_URL, OPENAI_API_KEY (callback token), and optionally OPENAI_MODEL env vars into the Codex container
  • Default model gpt-4.1, configurable via AI_PROXY_DEFAULT_OPENAI_MODEL env var

Changes

  • packages/shared/src/constants/ai-services.ts — new DEFAULT_AI_PROXY_OPENAI_MODEL constant
  • apps/api/src/env.ts — added AI_PROXY_DEFAULT_OPENAI_MODEL env var type
  • apps/api/src/routes/workspaces/runtime.ts — extended proxy fallback to include openai-codex with openai-proxy provider
  • packages/vm-agent/internal/acp/session_host.go — added Codex env var injection branch
  • apps/api/.env.example — documented new env var

Validation

  • pnpm lint
  • pnpm typecheck
  • pnpm test (pre-existing ButtonGroup test failure unrelated)
  • pnpm build
  • 7 new unit tests + 12 existing proxy tests pass (no regressions)

Staging Verification (REQUIRED for all code changes — merge-blocking)

  • Staging deployment green — Deploy Staging workflow passed for this branch
  • Live app verified via Playwright — logged into app.sammy.party using test credentials
  • Existing workflows confirmed working — dashboard, projects, settings all load correctly, no console errors
  • New feature/fix verified on staging — backend-only API change; deploy succeeds, API healthy, no regressions. Full Codex proxy exercise requires provisioning a Codex workspace (infrastructure dependency).
  • Infrastructure verification completed — N/A: no infra changes (cloud-init, DNS, TLS unchanged)
  • Mobile and desktop verification notes added for UI changes — N/A: no UI changes

Staging Verification Evidence

  • Staging deploy run #25196734803 succeeded
  • Authenticated to app.sammy.party via token-login
  • Dashboard renders with project cards, Settings loads, Project chat loads
  • API health: {"status":"healthy"} at api.sammy.party/health
  • No new console errors (0 errors, 1 warning — pre-existing)

UI Compliance Checklist (Required for UI changes)

N/A: no UI changes

End-to-End Verification (Required for multi-component changes)

  • Data flow traced from user input to final outcome with code path citations
  • Capability test exercises the complete happy path across system boundaries
  • All spec/doc assumptions about existing behavior verified against code
  • If any gap exists between automated test coverage and full E2E, manual verification steps documented below

Data Flow Trace

  1. Agent session starts, VM agent calls POST /api/workspaces/:id/agent-key with agentType: 'openai-codex'
    apps/api/src/routes/workspaces/runtime.ts agent-key handler
  2. No user credential found → AI proxy fallback fires
    runtime.ts:81 checks PROXY_ELIGIBLE_AGENTS.has('openai-codex') → true
  3. Returns inferenceConfig: { provider: 'openai-proxy', baseURL: 'https://api.{domain}/ai/v1', model: 'gpt-4.1' }
    runtime.ts:95-108
  4. VM agent receives response, matches agentType == "openai-codex" && provider == "openai-proxy"
    packages/vm-agent/internal/acp/session_host.go:1008-1020
  5. Injects OPENAI_BASE_URL, OPENAI_API_KEY (callback token), OPENAI_MODEL into container env
  6. Codex uses these to call {OPENAI_BASE_URL}/chat/completions → SAM's AI proxy

Untested Gaps

Go-side injection branch has no automated test (pre-existing gap — same for claude-code branch). TypeScript tests cover the full API response shape. Backlog task filed: tasks/backlog/2026-05-01-ai-proxy-credential-hardening.md.

Post-Mortem (Required for bug fix PRs)

N/A: not a bug fix

Specialist Review Evidence (Required for agent-authored PRs)

  • All dispatched reviewers completed and findings addressed before merge
  • If any reviewer did NOT complete: needs-human-review label added and merge deferred to human — all completed
Reviewer Status Outcome
task-completion-validator PASS All checks A-E pass; 1 LOW (pre-existing Go test gap)
go-specialist PASS 1 MEDIUM (pre-existing double-injection pattern), 1 MEDIUM (pre-existing Go test gap), 1 LOW
cloudflare-specialist ADDRESSED .env.example added, Set moved to module scope, KV comment added (commit df28cfd)
security-auditor ADDRESSED 2 HIGH (pre-existing patterns identical to claude-code PR#862) → backlog task filed; 3 MEDIUM (documented/pre-existing)
env-validator ADDRESSED .env.example entry added (commit 795a1c4)

Exceptions (If any)

  • Scope: Security HIGH findings deferred to backlog
  • Rationale: Both HIGH findings (callback token lifetime, platform_proxy sentinel) are pre-existing architectural patterns identical to the already-merged claude-code proxy (PR feat: add Claude Code AI proxy credential fallback #862). Not regressions from this PR.
  • Expiration: Tracked in tasks/backlog/2026-05-01-ai-proxy-credential-hardening.md

Agent Preflight (Required)

  • Preflight completed before code changes

Classification

  • external-api-change
  • cross-component-change
  • business-logic-change
  • public-surface-change
  • docs-sync-change
  • security-sensitive-change
  • ui-change
  • infra-change

External References

N/A: mirrors existing claude-code proxy pattern (PR #862). No new external API integration.

Codebase Impact Analysis

  • packages/shared — new constant DEFAULT_AI_PROXY_OPENAI_MODEL
  • apps/api — extended agent-key fallback in runtime.ts, new env var in env.ts
  • packages/vm-agent — new injection branch in session_host.go

Documentation & Specs

  • apps/api/.env.example — added AI_PROXY_DEFAULT_OPENAI_MODEL
  • CLAUDE.md — no update needed (AI proxy gateway entry already covers the pattern)

Constitution & Risk Check

  • Principle XI (No Hardcoded Values): Default model gpt-4.1 is configurable via AI_PROXY_DEFAULT_OPENAI_MODEL env var with shared constant fallback
  • All URLs derived from BASE_DOMAIN env var
  • No hardcoded timeouts or limits introduced

raphaeltm and others added 8 commits May 1, 2026 00:31
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When no user-provided OpenAI API key exists for openai-codex agent type,
inject SAM's AI proxy as the credential source. Mirrors the Claude Code
fallback (WP2, PR #862) for the OpenAI agent type.

- Add DEFAULT_AI_PROXY_OPENAI_MODEL constant (gpt-4.1)
- Extend runtime.ts proxy fallback to include openai-codex
- Add openai-proxy provider branch in session_host.go
- Inject OPENAI_BASE_URL and OPENAI_API_KEY env vars for Codex

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mirrors the Claude Code proxy fallback test suite for openai-codex:
- Returns openai-proxy inferenceConfig when no credential exists
- User credential takes priority over proxy fallback
- 404 when AI proxy is disabled
- Custom model via AI_PROXY_DEFAULT_OPENAI_MODEL env var
- Task credential source tracking
- No regression on opencode or claude-code fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address review findings: move PROXY_ELIGIBLE_AGENTS to module scope
for isolate reuse, add comment documenting KV model-picker gap for
Codex (intentional, matches Claude Code pattern).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Captures defense-in-depth findings from WP3 security audit:
- Short-lived proxy-scoped tokens
- __platform_proxy__ sentinel cleanup
- BaseURL origin validation
- Go-side proxy injection tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 1, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
79.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@simple-agent-manager simple-agent-manager Bot merged commit 73add75 into main May 1, 2026
17 of 19 checks passed
simple-agent-manager Bot added a commit that referenced this pull request May 1, 2026
* chore: move task to active

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: wire AI proxy Anthropic route to Unified Billing (#865)

Replace resolveAnthropicApiKey() with resolveUpstreamAuth() in the
Anthropic proxy, enabling Cloudflare Unified Billing via
cf-aig-authorization header. Add CF_API_TOKEN as fallback for
CF_AIG_TOKEN. Update OpenAI-compat proxy for consistent billing
resolution. Remove unused resolveAnthropicApiKey from ai-proxy-shared.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: update CLAUDE.md for unified billing changes

Update anthropic-proxy-endpoint and ai-proxy-gateway entries to
reflect resolveUpstreamAuth() usage and CF_API_TOKEN fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: sort imports in ai-proxy.ts for lint compliance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* task: archive ai-proxy-anthropic-unified-billing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address cloudflare-specialist review findings

- Add log.warn when falling back to CF_API_TOKEN (high-privilege token)
- Add cf-aig-metadata header to count_tokens endpoint for analytics

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: sanitize error messages from resolveUpstreamAuth

Log full error details server-side, return generic message to clients.
Prevents leaking internal variable names (CF_AIG_TOKEN, CF_API_TOKEN)
in 503 responses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add billing header contract integration tests

Verify UpstreamAuth headers are correctly assembled for unified
and platform-key modes, mutual exclusivity of auth headers, metadata
always present, and error message sanitization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: remove unused vi import from billing integration tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Raphaël Titsworth-Morin <raphael@raphaeltm.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant