NAS-142245 / 27.0.0-BETA.1 / ci: prefer the Claude Code OAuth token over the API key - #11
Merged
Merged
Conversation
The shared review workflow accepted either credential but required exactly one, failing the job when both were mapped. That forces the secret grant and the caller change to land in lockstep in every repo. Prefer the token instead: fail only when both are empty, and pass the API key to the action only when the token is empty, so the CLI never sees two credentials and the billing account is decided here rather than by whichever it happens to read first. UX_CLAUDE_CODE_OAUTH_TOKEN is an org secret granted per repository, and one that has not been granted resolves to the empty string rather than failing. With both mapped, a repo runs on the subscription where the grant exists and on API billing where it does not, and flips over on its own when the grant lands -- no second pull request, and no window where review is broken because the secret and the workflow arrived in the wrong order. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018z1AokioSumsXkmVAGo9pq
Contributor
Automatic reviewOne finding: one LOW. Nothing at or above MEDIUM, so the review gate passes. The credential pick itself checks out end to end:
Worth noting for the record, not as a finding: the pre-existing fork paragraph in The one LOW is on |
The README said mapping both secrets means an expired OAuth token degrades to API billing. It does not. The pick is made on emptiness and an expired token is a non-empty string, so it still wins and the API key is still blanked -- every repo holding the grant fails auth at once. The pair covers a missing grant, not a bad credential. Also names the three orgs the secret is set on, since a reader outside them would find "check the grant" a dead end. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018z1AokioSumsXkmVAGo9pq
The paragraph named expiry as the case the mapped pair does not cover, but the property is about validity in general: a revoked token, or one that has hit the subscription's usage limit, is equally non-empty, so it still wins and the API key is still blanked. Same failure, same blast radius. Also points at what does report it -- check-review-threshold.mjs reads the execution log when there is no structured output, so the gate names the API error instead of passing a review that never ran. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018z1AokioSumsXkmVAGo9pq
AlexKarpov98
marked this pull request as ready for review
August 18, 2026 16:22
william-gr
approved these changes
Aug 18, 2026
Contributor
|
This PR has been merged and conversations have been locked. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The shared review workflow accepted either credential but required exactly one, failing the job when both were mapped. That forces the secret grant and the caller change to land in lockstep in every repo.
Prefer the token instead: fail only when both are empty, and pass the API key to the action only when the token is empty, so the CLI never sees two credentials and the billing account is decided here rather than by whichever it happens to read first.
UX_CLAUDE_CODE_OAUTH_TOKEN is an org secret granted per repository, and one that has not been granted resolves to the empty string rather than failing. With both mapped, a repo runs on the subscription where the grant exists and on API billing where it does not, and flips over on its own when the grant lands -- no second pull request, and no window where review is broken because the secret and the workflow arrived in the wrong order.