Skip to content

fix: surface GH_AW_GITHUB_TOKEN guidance on cross-repo private callee auth failure#32530

Merged
pelikhan merged 8 commits into
mainfrom
copilot/fix-lockdown-check-fails
May 16, 2026
Merged

fix: surface GH_AW_GITHUB_TOKEN guidance on cross-repo private callee auth failure#32530
pelikhan merged 8 commits into
mainfrom
copilot/fix-lockdown-check-fails

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 16, 2026

When workflow_call targets a private callee repo, the caller's GITHUB_TOKEN is repo-scoped and returns 404 from the callee's Contents API. Previously this fell through to getFileContent() (which discards errors), then to the misleading "lock file is outdated — run gh aw compile" error. Recompiling does nothing to fix an auth gap.

Changes

check_workflow_timestamp_api.cjs

  • Inlined the lock-file getContent call in compareFrontmatterHashes(), replacing the getFileContent() helper call so the HTTP status is visible.
  • Cross-repo auth detection: when the fetch throws 401/403/404 and workflowRepo !== currentRepo, records crossRepoAuthFailure = { status, repo } and logs immediately:
    Cross-repo API access failed (HTTP 404): GITHUB_TOKEN is scoped to the caller repo
    and cannot read from 'org/callee-repo'. Configure GH_AW_GITHUB_TOKEN with read
    access to 'org/callee-repo' to resolve this.
    
  • Targeted failure branch: when hashComparison is null and crossRepoAuthFailure is set, the step summary and setFailed message now emit actionable GH_AW_GITHUB_TOKEN guidance instead of gh aw compile.

Preserved behaviour

  • Generic errors without .status (e.g. "Resource not accessible by integration") → unchanged "outdated or unverifiable" path.
  • Same-repo 404 → no cross-repo auth guidance.
  • Local filesystem fallback still succeeds when local files are present, even with an API 404.
  • stale_lock_file_failed output is still set on all failure paths.

Tests (check_workflow_timestamp_api.test.cjs)

New cross-repo private callee auth failure guidance describe block (8 tests): HTTP 404/401/403 guidance messages, summary content, stale_lock_file_failed output, no guidance for generic/statusless errors, no guidance for same-repo 404, local-fallback success despite API 404.



✨ PR Review Safe Output Test - Run 25953762282

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 5.9M ·


Changeset

  • Type: patch
  • Description: Surface actionable GH_AW_GITHUB_TOKEN guidance when a private cross-repo callee cannot be read by the caller's GITHUB_TOKEN.

Generated by 📋 Changeset Generator for issue #32530 ·


Generated by 👨‍🍳 PR Sous Chef ·


pr-sous-chef: attempted branch update (run: https://github.com/github/gh-aw/actions/runs/25956153961)

Generated by 👨‍🍳 PR Sous Chef ·

Copilot AI and others added 2 commits May 16, 2026 02:30
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…callee auth failure

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix lockdown check fails on private cross-repo workflow call fix: surface GH_AW_GITHUB_TOKEN guidance on cross-repo private callee auth failure May 16, 2026
Copilot AI requested a review from pelikhan May 16, 2026 02:38
@pelikhan pelikhan marked this pull request as ready for review May 16, 2026 02:45
Copilot AI review requested due to automatic review settings May 16, 2026 02:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Improves error guidance when a workflow_call from a caller targets a private callee repo whose Contents API the caller's repo-scoped GITHUB_TOKEN cannot read. Instead of falsely directing users to run gh aw compile, the action now detects HTTP 401/403/404 on cross-repo lock file fetches and emits actionable GH_AW_GITHUB_TOKEN guidance in both the log, step summary, and setFailed message.

Changes:

  • Inlined github.rest.repos.getContent call in compareFrontmatterHashes() to capture HTTP status codes and detect cross-repo auth failures.
  • Branched the failure summary/setFailed message to surface GH_AW_GITHUB_TOKEN remediation when a cross-repo 401/403/404 was observed.
  • Added a new test block (8 cases) covering 401/403/404 cross-repo guidance, summary content, same-repo and statusless-error negative cases, and local-fallback success.
Show a summary per file
File Description
actions/setup/js/check_workflow_timestamp_api.cjs Inlines lock-file fetch, records cross-repo auth failures, and switches the final error/summary text accordingly.
actions/setup/js/check_workflow_timestamp_api.test.cjs Adds regression tests for the new cross-repo auth failure guidance behavior.
.github/workflows/daily-model-inventory.lock.yml Regenerated heredoc delimiter hashes plus a trailing newline; appears to be an unrelated recompile artifact.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 0

// Track whether a cross-repo API auth failure was the root cause of the hash check failure.
// Used to surface targeted remediation guidance instead of the generic "run gh aw compile" message.
// Set inside compareFrontmatterHashes() when an HTTP 401/403/404 is returned for a cross-repo fetch.
let crossRepoAuthFailure = null;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot avoid global variables

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — crossRepoAuthFailure is no longer an outer variable mutated by a closure. compareFrontmatterHashes() now returns { result, crossRepoAuthFailure } and the call site destructures it: const { result: hashComparison, crossRepoAuthFailure } = await compareFrontmatterHashes(); (commit 783a6b3~1 → latest).

…nstead of outer variable

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan May 16, 2026 03:49
@pelikhan pelikhan added the smoke label May 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

🚀 Smoke Pi MISSION COMPLETE! Pi delivered. 🥧

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

Smoke OTEL Backends completed successfully!

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

💫 TO BE CONTINUED... Smoke Claude failed to deliver outputs! Our hero faces unexpected challenges...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions github-actions Bot removed the smoke label May 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

Smoke OTEL — OTEL telemetry verified

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

🚀 Smoke Gemini MISSION COMPLETE! Gemini has spoken. ✨

Caution

agentic threat detected
Threat detection flagged this output in warn mode. Manual review is REQUIRED before any follow-up automation.

Details

The threat detection results could not be parsed.

Review the workflow run logs for details.

Smoke test in progress

@github-actions
Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions
Copy link
Copy Markdown
Contributor

Agent Container Tool Check

Tool Status Version
bash 5.2.21
sh available
git 2.54.0
jq 1.7
yq 4.53.2
curl 8.5.0
gh 2.92.0
node 22.22.2
python3 3.14.5
go 1.24.13
java 10.0.300
dotnet not found

Result: 11/12 tools available ⚠️

Overall Status: FAILdotnet (.NET runtime) is not available in this agent container.

🔧 Tool validation by Agent Container Smoke Test · ● 1.2M ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: Copilot - 25953762391 ✅ PASS

Test Status
GitHub MCP
MCP Scripts GH CLI
Serena CLI
Playwright CLI
Web Fetch
File Writing
Bash Tool
Discussion Interaction
Build gh-aw
Upload Artifact
Discussion Creation
Workflow Dispatch
PR Review
Comment Memory
Sub-Agent

Author: @Copilot | Assignees: @pelikhan, @Copilot

Run §25953762391

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 12.6M ·

@github-actions
Copy link
Copy Markdown
Contributor

Comment Memory

Tests run at dawn
Each assertion a heartbeat
Green means peace at last

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 12.6M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

This refactor cleanly encapsulates crossRepoAuthFailure inside compareFrontmatterHashes() and returns it as part of a structured result. The code is easier to reason about, and the cross-repo auth guidance path is now clearly separated from the normal hash comparison logic.

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 12.6M

// code for cross-repo auth failure detection: the caller's GITHUB_TOKEN is repo-scoped and
// cannot read from a private callee repo, returning 404/401/403.
let lockFileContent = null;
let crossRepoAuthFailure = null;
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.

Good scoping fix — moving crossRepoAuthFailure inside compareFrontmatterHashes() keeps the variable closer to where it is mutated, making the control flow easier to follow.

if (!lockFileContent) {
core.info("Unable to fetch lock file content for hash comparison via API, trying local filesystem fallback");
return await compareFrontmatterHashesFromLocalFiles();
return { result: await compareFrontmatterHashesFromLocalFiles(), crossRepoAuthFailure };
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.

The structured return { result, crossRepoAuthFailure } is a clear improvement — callers can now distinguish between a null result and an auth failure without relying on side-channel outer variables.

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: Claude — 25953762282 — Overall: ⚠️ PARTIAL

Core #1-12: 1✅ 2✅ 3⚠️(serena find_symbol) 4✅ 5✅ 6✅ 7✅ 8✅ 9✅ 10✅ 11✅ 12✅
PR Review #13-19: 13✅ 14✅ 15✅ 16✅ 17✅ 18✅ 19⚠️(skipped)

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 5.9M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

💥 Automated smoke test review - all systems nominal!

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 5.9M

// result — { match, storedHash, recomputedHash } | null
// crossRepoAuthFailure — { status, repo } when a cross-repo 401/403/404 was the root cause, else null
async function compareFrontmatterHashes() {
try {
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.

Smoke test note: consider adding a unit test for this code path. 🤖

try {
const response = await github.rest.repos.getContent({
owner,
repo,
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.

Smoke test note: consider logging context info here for easier debugging. 🛰️

@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: d31c544

Generated by Changeset Generator

@github-actions
Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Copy Markdown
Contributor

@copilot review all comments

Please address the unresolved review feedback, especially the global-variable and unit-test notes.

Generated by 👨‍🍳 PR Sous Chef ·

@github-actions
Copy link
Copy Markdown
Contributor

Please refresh the branch if needed, rerun checks, and post a brief update on the remaining blocker(s).

Generated by 👨‍🍳 PR Sous Chef ·

@github-actions
Copy link
Copy Markdown
Contributor

@copilot review all comments

Please address unresolved review feedback and propose fixes. — pr-sous-chef (run: https://github.com/github/gh-aw/actions/runs/25956153961)

Generated by 👨‍🍳 PR Sous Chef ·

@github-actions
Copy link
Copy Markdown
Contributor

Quick nudge: @copilot please summarize remaining blockers and next steps to get this PR merge-ready. — pr-sous-chef

Generated by 👨‍🍳 PR Sous Chef ·

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot do not inline getFileContent, instead expose the status code in result so that you avoid duplicate code

… API call

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 16, 2026

@copilot do not inline getFileContent, instead expose the status code in result so that you avoid duplicate code

Done. getFileContent now returns { content: string|null, errorStatus: number|null } instead of string|null. compareFrontmatterHashes() uses it again (no more inlined API call), destructuring { content: lockFileContent, errorStatus } and checking errorStatus for cross-repo 401/403/404 detection. recomputeHashWithDebugLogging() also updated to destructure .content. Tests updated accordingly.

@pelikhan
Copy link
Copy Markdown
Collaborator

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 16, 2026

@copilot lint js https://github.com/github/gh-aw/actions/runs/25963680852/job/76323540893#step:6:1

The parse_copilot_log.test.cjs Prettier failure was pre-existing and unrelated to our changes — it was already resolved when main was merged into this branch (commit 9738ff9). All lint checks pass now, including our changed files.

@pelikhan pelikhan merged commit 6b77297 into main May 16, 2026
12 of 13 checks passed
@pelikhan pelikhan deleted the copilot/fix-lockdown-check-fails branch May 16, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lockdown check fails on private cross-repo workflow_call: Contents API uses caller's GITHUB_TOKEN, not callee-accessible token

3 participants