ACP auth banner is a host-only signal — inaccurate on Docker/cloud backends
#1244 aperta il 8 giu 2026
Metriche repository
- Star
- (43 star)
- Metriche merge PR
- (Metriche PR in attesa)
Descrizione
Summary
The ACP "already signed in to {provider}" auth banner — shown in onboarding (setup-acp-secrets-step) and now in Settings → Agent → Credentials (added in #1102 via the shared AcpAuthStatusBanner) — only reflects auth correctly on a native local backend. On a Docker (containerized) backend it almost never shows for Claude/Codex even when the conversation is fully authenticated, and on cloud it never runs. The banner is currently a host-only signal, not a true "will the agent authenticate" signal.
Root cause
The banner is driven by useAcpAuthStatus → AcpService.getAuthStatus (src/api/acp-service/acp-service.api.ts), which detects login by shelling the provider's interactive CLI through the agent-server bash endpoint:
- claude-code →
claude auth status --json - codex →
codex login status - gemini-cli →
test -f "$HOME/.gemini/oauth_creds.json"
These commands run wherever the agent-server runs. That's fine on a native local backend (the user's machine has claude/codex + their login), but:
- The agent-server container ships only the ACP wrappers (
claude-agent-acp,codex-acp) — not the interactiveclaude/codexCLIs — so the probe commands hit "command not found" and classify asunknown→ banner renders nothing. - The agent actually authenticates via the materialized secret (Claude
CLAUDE_CODE_OAUTH_TOKENenv, CodexCODEX_AUTH_JSON→auth.json, Gemini Vertex SA) seeded at conversation start through the ACP wrappers — which the probe never inspects. - On cloud, the probe is gated off entirely (
isSupported = backend.kind === "local"), so status is alwaysunknown.
Net: unknown ≠ "logged out" — it means "couldn't tell" — and in a container/cloud it's the default, so the banner is silent even when credentials are correctly configured.
Evidence (verified locally)
| Provider | Native backend (probes the host) | Docker backend (probes inside the container) |
|---|---|---|
| claude-code | {"loggedIn": true, "authMethod":"claude.ai"} → authenticated (banner shows) |
claude: not found → not JSON → unknown (no banner) |
| codex | Logged in using ChatGPT → authenticated (banner shows) |
codex: not found → unknown (no banner) |
| gemini-cli | checks ~/.gemini/oauth_creds.json on host |
gemini present but creds file absent in fresh container → unauthenticated (no banner) |
Container CLI inventory: claude-agent-acp, codex-acp, gemini are present; claude and codex are not.
Proposed improvements (pick one / combine)
- Make detection container/cloud-aware. Instead of (only) shelling
claude/codex, detect auth from what the agent actually uses: the materialized credential files (e.g. Codexauth.jsonunder the relocatedCODEX_HOME, the Gemini Vertex SA JSON) and/or the relevant env-var/secret being set. This makes the signal meaningful in a container. - Distinguish "credentials configured" from "signed in (host login)." When a provider secret exists for the active backend, show a "credentials configured" state even if no host login is detected. (The fields already render an
alreadySetper-field marker — a section-level summary banner could build on that.) - At minimum, scope it honestly. Treat the host-login banner as a native-backend nicety and don't imply anything on Docker/cloud (current behavior), but document that and lean on the per-field
alreadySetmarkers there.
Acceptance criteria
- On a Docker/cloud backend with a provider credential configured, the Credentials section conveys an accurate auth/credentials state (not a misleading silence).
- No false "signed in" on a backend where we can't actually tell.
- Onboarding and Settings → Agent stay consistent (they share
AcpAuthStatusBanner).
References
- Banner component:
src/components/features/settings/acp-auth-status-banner.tsx - Probe:
src/api/acp-service/acp-service.api.ts,src/hooks/query/use-acp-auth-status.ts - Surfaces:
src/components/features/onboarding/steps/setup-acp-secrets-step.tsx,src/components/features/settings/acp-credentials-section.tsx - Introduced alongside #1102 (containerized + cloud ACP) and the cloud ACP epic #988