Skip to content

ums: pull_request_target is rejected by the App-token exchange - #1006

Merged
d-morrison merged 3 commits into
mainfrom
ums/2026-07-31-oidc-exchange-rejects-pr-target
Aug 1, 2026
Merged

ums: pull_request_target is rejected by the App-token exchange#1006
d-morrison merged 3 commits into
mainfrom
ums/2026-07-31-oidc-exchange-rejects-pr-target

Conversation

@d-morrison

Copy link
Copy Markdown
Collaborator

UMS entry from a UCD-SERG/ucd-serg.github.io session where every Claude review
had been failing for a day.

What it records

Anthropic's github-app-token-exchange endpoint rejects OIDC tokens minted for
pull_request_target, so a review workflow on that trigger dies at
401 Unauthorized - Invalid OIDC token before the model is reached. Upstream
anthropics/claude-code-action#713,
open since 2025-12-02.

The reason it is worth a corpus entry rather than a repo note: the action's own
side supports the trigger --- #347 is closed as completed and docs/security.md
has a section on it --- so the broken workflow reads as correct and documented,
and the failure names something (Invalid OIDC token) that sounds like a
credential problem.

It also separates the three different 401s that arrive at that same step, which
had not been written down together:

Message Cause
Invalid OIDC token the trigger event (new)
User does not have write access on this repository non-collaborator triggering actor
Workflow validation failed ... not a failure --- the action skips and exits 0

That third one matters beyond this entry: a green claude-review on any PR that
edits the review workflow is a skip, not a review.

Relationship to what is already there

This is a fourth distinct cause in the same short-duration band on the same
repository that fully-clean.md's "short failures are not a signature" entry
already cites for three. Three of the four run 25 seconds or less and none is
about credentials, so it corroborates that rule rather than competing with it.

The workflow-validation skip is cross-referenced to the existing self-mod skip
bullet in the same file rather than restated.

One correction worth flagging

Issue #713's own body credits pull_request_target support to "PR #759".
gh pr view 759 does not resolve --- #759 is an unrelated open bug report about
a wrong bot ID constant. The entry cites #347 instead and says so, so the next
reader does not re-derive it.

Verification

Source PR: UCD-SERG/ucd-serg.github.io#89,
issue #88.

Anthropic's exchange endpoint 401s on OIDC tokens minted for
pull_request_target, so a review workflow on that trigger never reaches
the model. The action's own side supports it, which is what makes the
misconfiguration read as correct.

Also separates the three 401s that share that step -- the trigger event,
a non-collaborator triggering actor, and the workflow-validation skip
that exits 0 -- and records a fourth distinct cause in the
short-duration band fully-clean.md already warns not to read as a
credential signature.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMmB6db4xpbuqcqaQKArZb
Copilot AI review requested due to automatic review settings August 1, 2026 02:41
@d-morrison

Copy link
Copy Markdown
Collaborator Author

Working on this --- paws off until I'm done.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Claude finished reviewView run


No --comment flag was passed in the arguments, so per the review process I'll output findings here rather than posting to GitHub. Verification is complete — let me summarize.

Review summary: #1006

Scope: Adds one new section (~57 lines) to memories/claude-bot-workflows.md documenting that Anthropic's github-app-token-exchange endpoint rejects OIDC tokens minted for pull_request_target events.

Extensive fact-checking performed: verified anthropics/claude-code-action#347 (closed/completed ✓), #713 (open since 2025-12-02 ✓, body credits "PR #759" ✓, workaround is pull_request ✓), #759 (confirmed to be an unrelated open issue, not a PR ✓), docs/security.md's pull_request_target section and allowed_non_write_users "significant security risk" language ✓, and the UCD-SERG/ucd-serg.github.io #83/#84/#88/#89 case narrative ✓. Also verified: 0 banned punctuation glyphs in the diff, 998-line file total (under the 1200-line cap), 0 multi-sentence lines, and that the ../shared/workflow/fully-clean.md relative link resolves. All of this checks out — the PR's own "Verification" section is accurate.

Two independent review passes (plus my own check) converged on the same two issues, both in the closing paragraph of the new section:

Issues found

  1. Misquoted citation (memories/claude-bot-workflows.md:987-988) — The text puts "a short duration is corroboration, not a test" in straight quotes immediately after a link to fully-clean.md, presenting it as a verbatim quote. That exact string does not appear anywhere in fully-clean.md (confirmed by grep — zero matches). This violates this repo's own shared/writing/citations.md convention, which requires exact-substring verification before quoting a source. It's a paraphrase of the section titled "That duration signature does not run backwards..." — should be reworded as a paraphrase (no quotation marks) or replaced with an actual verbatim fragment.

  2. Inaccurate "same repository" claim (memories/claude-bot-workflows.md:985-986) — "This is a fourth distinct cause in the same short-duration band on the same repository..." The antecedent case record in fully-clean.md (the "13-to-28-second band" paragraph) cites three failures: two on UCD-SERG/ucd-serg.github.io (25s, 13s) and one on a different repo, d-morrison/qwt (28s). So this new (fourth) failure is on the same repo as only 2 of the 3 antecedents, not all of them. The "three of the four run 25 seconds or less" and "none of them is about credentials" claims in the same sentence are both accurate — only "on the same repository" overclaims. Notably, this is the exact "grouping by symptom" overreach that fully-clean.md's very next section warns against, while this entry is invoking that section's authority.

  3. Minor/low-confidence: "Two neighbouring 401s" (memories/claude-bot-workflows.md:972) lists three bullets, not two, and the third (Workflow validation failed...) is explicitly described two lines later as "not a failure at all" — so it isn't a 401 and arguably shouldn't be introduced under that heading. Worth a wording tweak (e.g., "three neighbouring failures") but low severity.

Nothing else rose to a blocking level — no hallucinated symbols/APIs (this is a prose-only memory file, no code), no CLAUDE.md structural violations (Do/Don't-pair convention doesn't clearly apply here, since this documents an infrastructure finding rather than a user-given correction, consistent with precedent elsewhere in the same file), and semantic-line-break/ASCII-punctuation formatting is clean.

Since no --comment flag was provided, I have not posted these as GitHub comments — reporting here only, per the review process.

Verdict

Needs minor changes — two citation/factual-precision issues (findings 1 and 2) should be fixed before merge; finding 3 is optional polish.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

💰 Cost: $12.9955 (review) — run

Three findings from round 1, all correct:

- The fully-clean.md reference put a paraphrase in quotation marks.
  Replaced with the section's real heading, verified verbatim, plus the
  point stated in my own words.
- "on the same repository" was wrong: the three antecedent failures are
  two on ucd-serg.github.io and one on d-morrison/qwt. Named both, and
  said what they actually share.
- "Two neighbouring 401s" introduced three bullets, the third of which
  is not a 401 at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMmB6db4xpbuqcqaQKArZb
Copilot AI review requested due to automatic review settings August 1, 2026 03:01
@d-morrison

Copy link
Copy Markdown
Collaborator Author

Round 1: three findings, all Addressed in 4017e65

Note for anyone reading the checks rather than the comment: require-review passed and all eight checks were green while this review carried a Needs minor changes verdict. No --comment flag was passed, so the findings live in the run comment and never became threads --- the surface fully-clean.md calls the one that defeats the gate itself.

1. Paraphrase presented as a verbatim quote --- Addressed.
I had put "a short duration is corroboration, not a test" in quotation marks after a link to fully-clean.md. That string appears nowhere in the file; I confirmed it with a normalized search (backticks and whitespace collapsed), so this is not a line-break artifact. Replaced with the section's real heading, That duration signature does not run backwards, verified verbatim at fully-clean.md:719, and the point restated in my own words outside the quotes.

2. "On the same repository" was an overclaim --- Addressed.
The three antecedent failures are two on UCD-SERG/ucd-serg.github.io and one on d-morrison/qwt. The entry now names both and says the band is what they share rather than the repo. The review's sharper point stands and is worth recording: this was the grouping-by-symptom overreach that the very section I was invoking warns against, committed inside the entry citing it.

3. "Two neighbouring 401s" introducing three bullets --- Addressed.
Correct, and the third is not a 401 at all. Now reads "Three messages arrive at that same exchange step, and only the first two are 401s."

One thing the review did not catch, found while fixing 2

My first draft of the fix read "three of the four are on this repository". In a memory file inside ai-config, "this repository" reads as ai-config, not as the repo the failures happened on --- so the fix for an overclaim would have shipped a new ambiguity. Both repos are now named explicitly.

I also re-ran the quotation check against my own replacement before committing, which is the only reason finding 1's fix is not finding 1 again.

Scan on the round: 14 added lines, 0 banned glyphs, 0 multi-sentence lines, 0 over 80 characters.

Comment thread memories/claude-bot-workflows.md Outdated
@claude

claude Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Code review

Reviewed this UMS memory-entry PR against the CLAUDE.md/shared/ corpus conventions (fact-checking, ASCII punctuation, semantic line breaks, citation hygiene) and independently verified every checkable claim against live GitHub data (issues/PRs in anthropics/claude-code-action and UCD-SERG/ucd-serg.github.io), per this run's hallucination-watch instructions.

Almost everything checks out:

  • anthropics/claude-code-action#347 is closed/completed; #713 is open since 2025-12-02 and its body does credit "PR Coding rule: use memoisation (memoise::memoise()) when it helps #759"; #759 is in fact an unrelated open issue (not a PR) about the CLAUDE_APP_BOT_ID constant — the entry's correction is accurate.
  • docs/security.md's allowed_non_write_users / write-access claims match the live doc text closely.
  • UCD-SERG/ucd-serg.github.io#88/#89's five-failing-pull_request_target-runs table and the #84 write-access case both match the actual issue bodies and check-run data.
  • No banned punctuation (em/en-dash, curly quotes, ×) in the added lines; the ../shared/workflow/fully-clean.md cross-reference and the "self-mod skip bullet above" cross-reference both resolve correctly within the repo.

One finding, posted inline: the closing historical note's claim that PR #89's own pull_request-triggered run "stopped at workflow validation instead" of the OIDC-token failure does not match that PR's actual CI history — that run succeeded. See the inline comment for the run-by-run evidence.

Verdict

Needs minor changes — one inline finding (a likely-fabricated claim about a specific CI run) should be corrected or removed before merge; everything else in the entry is well-sourced and accurate.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Claude finished reviewView run


Code review

Reviewed this UMS memory-entry PR against the CLAUDE.md/shared/ corpus conventions (fact-checking, ASCII punctuation, semantic line breaks, citation hygiene) and independently verified every checkable claim against live GitHub data (issues/PRs in anthropics/claude-code-action and UCD-SERG/ucd-serg.github.io), per this run's hallucination-watch instructions.

Almost everything checks out:

  • anthropics/claude-code-action#347 is closed/completed; #713 is open since 2025-12-02 and its body does credit "PR Coding rule: use memoisation (memoise::memoise()) when it helps #759"; #759 is in fact an unrelated open issue (not a PR) about the CLAUDE_APP_BOT_ID constant — the entry's correction is accurate.
  • docs/security.md's allowed_non_write_users / write-access claims match the live doc text closely.
  • UCD-SERG/ucd-serg.github.io#88/#89's five-failing-pull_request_target-runs table and the #84 write-access case both match the actual issue bodies and check-run data.
  • No banned punctuation (em/en-dash, curly quotes, ×) in the added lines; the ../shared/workflow/fully-clean.md cross-reference and the "self-mod skip bullet above" cross-reference both resolve correctly within the repo.

One finding, posted inline: the closing historical note's claim that PR #89's own pull_request-triggered run "stopped at workflow validation instead" of the OIDC-token failure does not match that PR's actual CI history — that run succeeded. See the inline comment for the run-by-run evidence.

Verdict

Needs minor changes — one inline finding (a likely-fabricated claim about a specific CI run) should be corrected or removed before merge; everything else in the entry is well-sourced and accurate.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

💰 Cost: $7.0209 (review) — run

Round 2 read run 30680266785's success conclusion and reported the
sentence describing it as fabricated. The run did succeed and did stop
at workflow validation -- the action skips and exits 0, which is what
the third bullet of this same section says.

Rebutted with the log, and reworded so the conclusion cannot be read as
excluding an early exit: both runs are now named, the exit-0 is stated
outright, and the misreading itself is recorded as a worked example of
the bullet above.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMmB6db4xpbuqcqaQKArZb
Copilot AI review requested due to automatic review settings August 1, 2026 03:14
@github-actions
github-actions Bot removed the request for review from Copilot August 1, 2026 03:14
@claude

claude Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Code review (round 4, re-verifying round-3 rebuttal)

This round re-checks the one open item from my prior review: the inline finding
on the closing historical note's claim that PR #89's pull_request-triggered
run (30680266785) "stopped at workflow validation instead" of succeeding
normally.

The author's rebuttal in ac50532f is correct, and my prior finding was
wrong.
I independently re-checked both runs on UCD-SERG/ucd-serg.github.io
PR #89:

  • Run 30680266779 (pull_request_target): failed, 401 Invalid OIDC token,
    ~30s — matches the entry.
  • Run 30680266785 (pull_request): concluded success, but the run page
    itself shows the warning "Workflow validation failed. The workflow file
    must exist and have identical content to the version on the repository's
    default branch"
    — the self-mod-skip condition already documented earlier
    in this same file. The job finished in ~11-22s (consistent with a skip, not
    a full review), and PR skills: consolidate iterate→ardi and iterate-all→ardia (genuine duplicates) #89's comment history shows no claude-authored
    review was ever posted from that run — only two unrelated Copilot reviews.

So my previous read (that this run "succeeded" and therefore could not have
"stopped at workflow validation") was based on the check-run conclusion alone
and missed that a skip due to workflow validation also concludes success
without posting a review. That's exactly the mechanism the entry's own
"self-mod skip" section (linked a few lines above) already describes, and
exactly the misreading the entry now calls out as a worked example. The
current text is accurate; I'm withdrawing the finding.

The two round-1 fixes (4017e65) also check out on re-read: the
fully-clean.md cross-reference now quotes a genuinely verbatim phrase
("That duration signature does not run backwards"), the "same repository"
claim is now correctly scoped (3 of 4 failures on
UCD-SERG/ucd-serg.github.io, 1 on d-morrison/qwt), and "Two neighbouring
401s" is now "Three messages ... only the first two are 401s," matching the
three bullets underneath it.

No banned punctuation or multi-sentence added lines found in a fresh scan of
the full diff. No new issues found in this round.

Verdict

Ready for merge.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Claude finished reviewView run


The review is posted. Summary:

Verdict: Ready for merge

I re-verified the one open item from my prior review round — the claim that PR #89's pull_request-triggered run "stopped at workflow validation instead" of succeeding. Independently checking both GitHub Actions runs on UCD-SERG/ucd-serg.github.io#89:

  • Run 30680266779 (pull_request_target) failed with 401 Invalid OIDC token, as previously confirmed.
  • Run 30680266785 (pull_request) concluded success, but its run page shows the "Workflow validation failed... identical content" warning — the self-mod-skip condition documented elsewhere in the same file — and the job finished in ~11-22s with no claude-authored review ever posted to the PR (only unrelated Copilot reviews).

That confirms the author's round-3 rebuttal (ac50532f) was correct and my prior inline finding was itself a false positive — I'd read only the check-run conclusion, not the actual skip condition. I withdrew that finding rather than re-raising it.

I also re-checked the two round-1 fixes (4017e65): the fully-clean.md citation is now genuinely verbatim, the "same repository" claim is correctly scoped, and the "two neighbouring 401s" count now matches its three bullets. No new issues found, and no banned punctuation or multi-sentence lines in the diff.

Note: I accidentally posted a throwaway test comment to the PR while checking write permissions, then immediately overwrote it with the real review via --edit-last — no stray comment was left behind.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

💰 Cost: $5.3288 (review) — run

@d-morrison

Copy link
Copy Markdown
Collaborator Author

Ready for merge

Round 3 verdict is Ready for merge, with the round-2 inline finding withdrawn by the reviewer itself: it had read only the check-run conclusion and not the skip condition, and re-checking run 30680266785 confirmed both the success conclusion and the workflow-validation warning. That thread is now resolved.

Round-by-round:

Round Verdict Outcome
1 Needs minor changes 3 findings, all correct, all Addressed in 4017e65
2 Needs minor changes 1 finding, a false positive; rebutted with the log and the wording fixed in ac50532
3 Ready for merge round-1 fixes re-verified, round-2 finding withdrawn

All eight checks pass. One inline thread total, resolved. Head is ac50532.

Correcting myself once more, since it is in this thread. My round-2 reply closed by claiming the reviewer had checked 4160c105 against the wrong PR. That was false --- 4160c105 is #89's head, #89 has one commit, and this PR's head is a different SHA. Withdrawn in the thread with the queries that disprove it. The rebuttal's substance was unaffected, but I asserted a SHA from recollection while arguing that someone else had misread a value, which is worth leaving on the record rather than quietly dropping.

Not merging --- yours to call.

@d-morrison
d-morrison merged commit b16fe72 into main Aug 1, 2026
9 checks passed
@d-morrison
d-morrison deleted the ums/2026-07-31-oidc-exchange-rejects-pr-target branch August 1, 2026 03:50
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