Count harness-carried model auth in surface config and admin onboarding - #128
Count harness-carried model auth in surface config and admin onboarding#128haramiya wants to merge 1 commit into
Conversation
…oarding Under HARNESS=claude with only CLAUDE_CODE_OAUTH_TOKEN (or ANTHROPIC_AUTH_TOKEN), turns work but the deployment reported itself unconfigured: surface-config's modelProviderConfigured only consulted the credential store, and the admin onboarding badge said 'Needs a key'. harnessCarriedModelAuth(config) names the provider a harness authenticates on its own (claude -> anthropic via OAuth/auth token, codex -> openai via CODEX_ACCESS_TOKEN). It is OR'd into modelProviderConfigured and exposed to the admin as a sibling harnessAuth field on GET /v1/admin/model-providers. The credential-store statuses stay untouched: anthropic still reports absent, because those keys feed pi-transport calls and deleting or adding them is independent of harness OAuth.
|
This appears more precise than #267 because it checks actual harness-carried authentication rather than the harness name alone. Please rebase and run current CI; if it remains green, I recommend treating this as canonical for the harness-readiness portion of #290/#268. @16francej, can you confirm the preferred implementation? |
|
Thanks for this, @haramiya — and sorry for the slow response. We're closing this PR. Per We don't want your idea to get lost, so we've captured it in #814 to triage on our side. Please feel free to open an |
Bug
Running
HARNESS=claudeon a Claude subscription (CLAUDE_CODE_OAUTH_TOKENfromclaude setup-token, noANTHROPIC_API_KEY) serves turns fine, but the deployment tells everyone it isn't set up:/v1/surface-configreportsmodelProviderConfigured: false, so the portal 503s non-admins and bounces admins to onboarding (Route the first admin to onboarding instead of a 403 web UI #29's gate).Root cause: both read only the model credential store, which counts anthropic/openai/openrouter API keys (env or admin-managed) and knows nothing about auth the harness carries itself. #67 and #109 both hit this and proposed fixes at different layers.
Fix
harnessCarriedModelAuth(config)insrc/config.tsnames the provider a harness authenticates on its own:claude→anthropicwhenCLAUDE_CODE_OAUTH_TOKENorANTHROPIC_AUTH_TOKENis inclaudeProcessEnvcodex→openaiwhenCODEX_ACCESS_TOKENis incodexProcessEnvundefined(env API keys are already counted through the credential store's fallback, so they aren't double-counted here)Wired as an optional
ServerDeps.harnessCarriedModelAuthand surfaced at the two places that were lying:getSurfaceConfigORs it intomodelProviderConfigured. Unlike makingmodelProviderAvailabilityForunconditionally report claude as available (adr: smaller fix for the keyless-harness model gate #109's noted downside), a claude deployment with no token anywhere still reports unconfigured and keeps the onboarding gate.GET /v1/admin/model-providersgains a siblingharnessAuth: { harnessId, provider }field. The credential-storeprovidersstatuses are deliberately untouched — anthropic keeps reportingabsentwhen no key is stored, because those keys feed pi-transport calls and adding/deleting them is independent of harness OAuth. Old admin UI against new core ignores the extra field; new UI against old core sees noharnessAuthand behaves exactly as before (blue-green safe).Screenshots
Admin → Onboarding,
HARNESS=claudewith onlyCLAUDE_CODE_OAUTH_TOKEN:Rendered against the admin page served with realistic stubbed API fixtures (the machine's only dev-instance Slack slot was held by another live instance, so this wasn't exercised on a booted stack; the same states are covered by the tests below).
Tests
test/model-credential-route.test.ts: claude harness + OAuth token →modelProviderConfigured: true,harnessAuth: { harnessId: "claude", provider: "anthropic" }, and the anthropic status still{ configured: false, source: "absent" }; claude harness with no token → still unconfigured, noharnessAuthfield.start()now derives the dep from the test config the same waysrc/index.tsdoes.plugins/admin/test/onboarding-view.test.ts: runs the realloadOnboarding()(vm-extracted fromindex.html) against stubbed endpoints — harness auth alone → Ready badge + harness summary; no harness auth → Needs a key; stored admin key + harness auth → Ready with the stored-key summary.Verification
test/model-credential-route.test.ts13/13,test/external-slack-participants.test.ts+test/admin-resources.test.ts20/20,plugins/adminonboarding suite 7/7tsc --noEmit(root and plugins/admin),eslint .,prettier --check— clean (lint:oxhas a pre-existing missing-native-binding failure locally; CI covers it)🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.