Skip to content

fix(deploy): scope harness credential probes to deploy auth - #335

Merged
khaliqgant merged 3 commits into
mainfrom
fix/cloud-harness-oauth-probe
Sep 4, 2026
Merged

fix(deploy): scope harness credential probes to deploy auth#335
khaliqgant merged 3 commits into
mainfrom
fix/cloud-harness-oauth-probe

Conversation

@khaliqgant

@khaliqgant khaliqgant commented Sep 4, 2026

Copy link
Copy Markdown
Member

Summary

  • stop treating /api/v1/cloud-agents responses from an unrelated stored user login as authoritative for a workspace-token deploy
  • classify a 403 from the user-credential listing as undeterminable (null), preserving the existing cloud-authority fallback
  • retain a definite false when the same deploy credential can list agents and the provider is genuinely absent
  • cover Claude setup-token rows (harness=claude, modelProvider=anthropic, authType=oauth_token) with no harness-source override
  • fail immediately when interactive --reconnect cannot verify completion under the deploy identity, instead of connecting and polling null for 60 seconds

Proven root cause

The credential row itself already matches the CLI predicate: a Claude persona derives anthropic; connectedHarnessEntries accepts both anthropic and its claude alias; status=connected is accepted; and authType, credentialExpiresAt, and lastError are not exclusion criteria.

The false answer came from identity scope instead:

  1. fetchCloudAgents ignored the deployment bearer (WORKFORCE_WORKSPACE_TOKEN) and built its client from readStoredAuth(), an independent stored user login.
  2. Cloud's packages/web/app/api/v1/cloud-agents/route.ts gates the route to session/cli:auth, then queries provider_credentials with both user_id = auth.userId and workspace_id = auth.workspaceId.
  3. Cloud's deployment-token route creates subjectType=ci tokens with deployment scopes, not cli:auth; presenting that deploy token to /cloud-agents returns 403. Presenting the unrelated stored login can instead return 200 plus an empty list for that login's user/current workspace.
  4. The CLI interpreted that scoped empty list as a definite absence in the deployment workspace and returned false.

The fix requires identity continuity before trusting the list. If the stored access token differs from the token driving this deploy, the probe returns null without issuing the misleading request. A 403 also returns null. This uses the existing deliberate tri-state path; it does not turn every result into OAuth. A same-token 200 response with no matching connected row still returns false and fails --no-prompt.

Cloud route proof inspected at AgentWorkforce/cloud commit a7ebcc55c7e3bd35d9663534843dc3239e152d71:

  • packages/web/app/api/v1/cloud-agents/route.ts
  • packages/web/lib/auth/request-auth.ts
  • packages/web/app/api/v1/workspaces/[workspaceId]/deployment-api-tokens/route.ts
  • packages/web/app/api/v1/workspaces/[workspaceId]/provider-credentials/setup-token/route.ts

Verification

  • pnpm --filter @agentworkforce/deploy test — 280 passed
  • pnpm typecheck — clean across the workspace and examples
  • git diff --check — clean

Targeted mutation proof (each mutation was applied, its focused test run failed, then production code was restored):

  • bypassed the stored-login/deploy-token equality guard → the CI regression failed with the original credentials are not connected error
  • removed 403 from the undeterminable statuses → the 403 regression failed with cloud harness check failed: 403
  • removed the claude alias from Anthropic matching → the setup-token regression failed with claude credentials are not connected
  • forced every visible response to return connected → the genuine-empty-list fail-closed regression failed
  • disabled the unverifiable-reconnect guard → the harness regression failed with the original poll timeout

The completed Codex review identified the reconnect/poll edge case; the second commit fixes it for both normal harness and useSubscription flows and adds regressions for both.

Wider preflight issue

This is another instance of a preflight reporting the operator's configuration as broken when its actual requirement was narrower: it needed an identity authorized to observe that configuration. Preflight results should distinguish absent from unobservable/insufficiently scoped and report the missing observation capability rather than asserting that the customer's resource is missing. This PR fixes that distinction for the harness credential probe without broadening the genuinely-absent case.

Session-Id: 01a06c6f-8413-7fd0-b597-e34a2d154421
@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 8 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 2e368e24-692e-401d-ac98-c46f1081d623

📥 Commits

Reviewing files that changed from the base of the PR and between 17c37c8 and 913660a.

📒 Files selected for processing (3)
  • packages/deploy/src/modes/cloud-subscription.test.ts
  • packages/deploy/src/modes/cloud.test.ts
  • packages/deploy/src/modes/cloud/index.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T13:08:20.359449Z 78d2535 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 78d2535e7c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/deploy/src/modes/cloud/index.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/deploy/src/modes/cloud/index.ts Outdated
Ricky Schema Cascade added 2 commits September 4, 2026 15:13
Session-Id: 01a06c6f-8413-7fd0-b597-e34a2d154421
Comparing the deploy token after refreshing stored auth made a same-identity
rotation look like an unrelated login. That turned authoritative credential
checks into indeterminate results and could strand post-connect polling.

Verify the stored token before refresh, then reuse the resulting refresh-capable
client throughout the credential flow. Unrelated workspace deploy tokens still
fail the identity check without issuing a misleading user-scoped request.
@khaliqgant

Copy link
Copy Markdown
Member Author

Review follow-up

Addressed the remaining token-rotation finding in 913660a6.

The probe still requires the deploy token to match the stored login, but now establishes that identity continuity before refreshing. It then reuses the resulting refresh-capable client for the full credential flow. This keeps unrelated CI/workspace tokens isolated while preventing a same-session refresh from turning later normal-harness or useSubscription polls into indeterminate results.

Non-vacuity mutations

  • moved the identity comparison back after refresh: both new regressions failed 0/2 (the subscription flow skipped connection and the normal flow lost its credential selection);
  • removed per-flow probe reuse: both regressions failed 0/2 (the subscription flow reproduced the poll timeout and the normal flow lost its credential selection).

Each mutation was reverted before final validation.

Validation

  • focused token-refresh regressions: 2/2 passed
  • pnpm --filter @agentworkforce/deploy test: 282/282 passed
  • pnpm -r build: passed
  • pnpm run typecheck: passed
  • pnpm run lint: passed
  • git diff --check: passed
  • Veto diff review: PASS, zero code/security/secrets findings and zero decision drift

@khaliqgant
khaliqgant merged commit f7be392 into main Sep 4, 2026
4 checks passed
@khaliqgant
khaliqgant deleted the fix/cloud-harness-oauth-probe branch September 4, 2026 20:08
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