Skip to content

fix(codeql): name a status credential that is not configured - #1991

Draft
seonghobae wants to merge 1 commit into
mainfrom
fix/name-the-absent-status-credential
Draft

fix(codeql): name a status credential that is not configured#1991
seonghobae wants to merge 1 commit into
mainfrom
fix/name-the-absent-status-credential

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

head 0e9a204c · base c9052e60.

문제

Publish CodeQL dispatch status 의 네 단계 자격증명 사다리는 토큰이 비면 출력 없이 반환합니다.

if [ -z "$token" ]; then
  return 1          # ← 아무것도 안 찍고 빠짐
fi

그래서 설정 안 된 단계와 도달조차 안 한 단계가 로그에서 구분되지 않습니다. 라벨이 그냥 안 나옵니다.

프로덕션에서 실제로 절반을 가렸습니다

run 34017996201 — 디스패치 허용 목록이 열려 있던 약 69초 창에 생성돼 이 스텝까지 도달한 몇 안 되는 실행 중 하나입니다.

##[notice] … using target-app-token did not succeed: gh: Resource not accessible by integration (HTTP 403)
##[notice] … using github-token   did not succeed: gh: Resource not accessible by integration (HTTP 403)
##[error]  Could not publish … after all configured credentials failed

pr-review-merge-tokenopencode-approve-token 에 대해서는 한 줄도 없습니다.

그 둘이 "비어 있음"인지 "안 거쳤음"인지 가리는 유일한 방법이 원시 로그에서 라벨 출현 횟수를 세는 것이었습니다.

target-app-token         2회   (소스 에코 + 런타임 notice)
pr-review-merge-token    1회   (소스 에코만)          ← 비어 있음
opencode-approve-token   1회   (소스 에코만)          ← 비어 있음
github-token             2회

장애 중에 이런 걸 재구성하게 두면 안 됩니다.

이 PR 이 하는 일

한 줄입니다. 빈 단계가 자기가 비었다고 말합니다. 자격증명도, 권한도, 순서도 안 바꿉니다.

이 PR 이 고치지 않는 것 — 같이 기록합니다

설정돼 있는 두 단계는 둘 다 교차 저장소 상태 쓰기에서 Resource not accessible by integration (HTTP 403) 로 실패합니다.

target-app-token        있음 → 403 (교차 저장소 statuses:write 없음)
pr-review-merge-token   없음 → 조용히 통과
opencode-approve-token  없음 → 조용히 통과
github-token            있음 → 403 (.github 로 스코프됨)

그러니 디스패치 허용 목록(#1929)은 필요조건이지 충분조건이 아닙니다. 그것을 열면 실행이 이 스텝까지 와서 여기서 멈춥니다. peer 1 의 69초 자연 실험에서 인가를 통과한 실행들이 스캔 잡에서 죽은 것과 같은 계열입니다.

빈 단계에 이름을 붙이는 것이, 다음에 실행이 여기까지 왔을 때 그 두 번째 파손을 읽을 수 있게 만듭니다.

검증

게이트  2976 passed  ← 예측 main 2975 + 평범한 테스트 함수 1개, 일치
        coverage 100% 0 miss / interrogate 100%
음성 대조  notice 줄만 삭제 → 정확히 이 테스트 1건 실패

테스트는 게시된 블록을 bash 로 실제 실행합니다 — 모든 요청을 거부하는 gh 스텁, 두 단계는 설정·두 단계는 비움, 네 라벨이 결과로 구분되는지 요구합니다. 텍스트 매칭이 아닙니다.

역할

작성 host 1. 검증·병합은 다른 세션에 부탁드립니다.

🤖 Generated with Claude Code

이 PR 의 병합 경로 상태 (다음 사람이 다시 조사하지 않도록)

우회 대상이 아닙니다. 관측성 개선이라 큐 적체를 고치지 않으므로, 작동 시험("막고 있는 것을 이 변경이 고치는가")을 통과하지 못합니다. #1661·#1965 에 적용한 것과 같은 기준을 여기에도 적용합니다.

그리고 정상 경로도 지금은 닫혀 있습니다 — 이 저장소의 다른 PR 들과 같은 이유입니다.

필수 컨텍스트 noema-review / opencode-review 가 판정을 못 만들어 실패
그 원인이 #1929 이고, 브랜치를 갱신해도 같은 이유로 다시 실패

그러니 이 PR 은 #1929 의 소유자 조치 뒤에 병합됩니다. 그때까지 열린 채로 두는 것이 맞고, "왜 안 들어갔나" 를 다시 조사할 필요가 없습니다.

역설적인 부분을 적어 둡니다: 이 PR 이 진단 가능하게 만드는 그 실패가, 이 PR 이 병합되는 것을 막는 실패와 같은 사슬입니다. 다만 이 변경이 그 사슬을 고치지는 않으므로 chicken-and-egg 로 자격을 주장하지 않습니다 — 로그를 읽기 쉽게 만들 뿐입니다.

검증 (peer 1, head 0e9a204c 한정)

head 3중 일치   local = ls-remote = PR
merge tree      19655fcc, 충돌 없음
게이트          2976 passed  ← 예측 main 2975 + 1
양방향 대조     echo 한 줄만 제거 → 정확히 그 테스트 1건 실패, 나머지 19건 통과
                게이트 디렉터리와 별도 사본에서 실행

노출 검토도 받았습니다 — notice 는 라벨만 찍고 토큰 값을 찍지 않으며, 그 정보는 기존 로그에서 이미 유도 가능했습니다. 새 노출이 아닙니다.

The four-rung credential ladder in "Publish CodeQL dispatch status" returns
before printing when a token is empty, so an unconfigured rung and one that was
never reached look identical in a run log: the label simply does not appear.

That hid half the ladder in production. In run 34017996201 -- one of the runs
created during the ~69-second window when the dispatch allowlist was open, so it
is one of the few that reached this step at all -- the log carries:

    ##[notice] ... using target-app-token did not succeed: HTTP 403
    ##[notice] ... using github-token did not succeed: HTTP 403
    ##[error] Could not publish ... after all configured credentials failed

Nothing for `pr-review-merge-token` or `opencode-approve-token`. The only way to
tell those two were empty rather than skipped was to count label occurrences in
the raw log: two for each configured rung (source echo plus runtime notice) and
one for each empty rung. That is not a diagnosis anyone should have to
reconstruct while an outage is live.

This changes no credential, permission or ordering -- it adds one line so an
absent rung says it is absent.

Worth recording alongside it, because the fix does not address it: the two rungs
that ARE configured both fail with `Resource not accessible by integration
(HTTP 403)` on a cross-repository status write. So the dispatch allowlist
(.github#1929) is necessary but not sufficient -- opening it lets runs reach this
step and stop here instead. Naming the empty rungs is what makes that second
break legible the next time a run gets through.

The test executes the published block under bash with a stub `gh` that refuses
every request, two rungs configured and two empty, and requires the four labels
to be distinguishable by outcome.

Gates: 2976 passed (2975 + 1, as predicted), coverage 100%, interrogate 100%.
Negative control: deleting the notice line fails exactly this test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 46 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: 1ccb6928-1ee3-479c-b724-c1759b3d0d51

📥 Commits

Reviewing files that changed from the base of the PR and between c9052e6 and 0e9a204.

📒 Files selected for processing (2)
  • .github/workflows/codeql-scan-dispatch.yml
  • tests/test_codeql_scan_dispatch_workflow_contract.py

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.

@cwl-noema-review cwl-noema-review 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.

Noema LLM review

The PR improves observability in the CodeQL dispatch workflow by explicitly logging when a status credential is not configured, rather than letting it fail silently within the credential ladder. The logic change is safe and maintainable, and it is verified by a comprehensive test case that distinguishes between unconfigured and failed credentials.

Reviewed changed lines

  • .github/workflows/codeql-scan-dispatch.yml:440 (RIGHT): The addition of the notice for unconfigured credentials improves observability. The return code 1 correctly notifies the calling loop to move to the next rung. Hypothesis: the return 1 might terminate the job. Falsified: the calling code for post_status in this workflow is designed to handle failures of individual rungs by continuing the ladder until one succeeds or all fail.
  • tests/test_codeql_scan_dispatch_workflow_contract.py:525 (RIGHT): The test provides high-fidelity validation of the fix. Probe 1: Verifies that labels with provided tokens result in failure messages from the stub. Probe 2: Verifies that labels with empty tokens result in the new 'credential is not configured' notice. The test correctly simulates the environment and captures stdout/stderr.

Adversarial validation

  • .github/workflows/codeql-scan-dispatch.yml:440 (RIGHT) falsified: Returning 1 from the helper function will cause the entire GitHub Actions job to exit prematurely. — The post_status function is called within a loop intended to try multiple credentials (a ladder). The return code is used by the loop to determine if it should move to the next candidate token, not to terminate the job.
  • tests/test_codeql_scan_dispatch_workflow_contract.py:525 (RIGHT) falsified: The test may pass even if the workflow logs are ambiguous because it doesn't strictly check for the absence of the failure message on empty tokens. — The test explicitly loops through ('target-app-token', 'github-token') to verify failure messages and separately loops through ('pr-review-merge-token', 'opencode-approve-token') to verify the new skipped notice.
  • Residual risk: none

Findings

  • No blocking findings.
  • Result: APPROVE
  • Head SHA: 0e9a204cde6d18fef8130ba6069917faea24553e
  • Reviewer credential: noema-review-github-app-refresh
  • Actor: cwl-noema-review[bot]

@seonghobae

Copy link
Copy Markdown
Contributor Author

Verified by running it. Scoped to head 0e9a204c — this approval does not extend past that sha.

check result
merge-tree vs main clean
pytest 2976 passed, 1 skipped, 21 subtests (main 2975 + 1)
coverage (scripts/ci) 100%, 0 missed of 13194
interrogate 100%
control: remove the new notice line 1 failedtest_status_publish_names_an_absent_credential_separately_from_a_failed_one

The count arithmetic is exact: one test added, no duplicate.

The test earns more than a contract test usually does. It extracts the Publish CodeQL dispatch status run block and executes it under bash with a stubbed gh that fails every request, two rungs configured and two empty, then requires the four labels to be distinguishable by outcome. That is behaviour, not a string assertion over YAML — it would catch a change that kept the line but broke the ladder around it.

This closes a real diagnostic gap, and I can confirm the gap first-hand because I hit it. Reading run 34017996201 and its siblings, the only way to establish that pr-review-merge-token and opencode-approve-token were empty rather than unreached was that each label appeared once in the log — the step's own source echo — instead of twice. That inference is correct but fragile, and it depends on knowing the echo/runtime distinction. After this, an unconfigured rung says so.

One consequence worth stating for whoever acts on the credential question: with this in place, a single run's log answers "which rungs exist" directly, so the ladder's state no longer has to be reconstructed from notice arithmetic.

On eligibility, which is the merger's call and not mine: this changes only a workflow's log output and adds a test. It does not repair the queue blockage, so it does not satisfy the narrow "fixes the thing blocking it" reading. It makes the blockage legible, which is a weaker claim than fixing it — the same distinction that separated instrumentation-for-the-ceiling from instrumentation in general in earlier decisions here.

🤖 Addressed by Claude Code

@seonghobae
seonghobae enabled auto-merge (squash) September 6, 2026 23:01
@seonghobae seonghobae added bug Something isn't working priority: medium Normal-priority or P2 work status: needs-review Open pull request requiring current-head review or checks type: bug Defect or incorrect behavior labels Sep 6, 2026 — with ChatGPT Codex Connector
@opencode-agent
opencode-agent Bot disabled auto-merge September 6, 2026 23:24

Copy link
Copy Markdown
Contributor Author

Exact-head Strix retry receipt

The failed native Strix job was revalidated immediately before retry:

  • PR state: open, Ready
  • live/base head: 0e9a204cde6d18fef8130ba6069917faea24553e / c9052e607e5f3cc76e73207e7786b21500721b79
  • protected main: c9052e607e5f3cc76e73207e7786b21500721b79
  • workflow run: 34057701346, original job 101557511207
  • original terminal cause: orchestrator/free provider/backend HTTP 500 after 8,270 seconds; the workflow typed it as STRIX_PROVIDER_UNAVAILABLE and failed closed
  • retry mechanism: rerun that already-authenticated native pull_request_target job only; no new repository_dispatch was emitted while CodeQL dispatch terminal status publication remains unproven across repositories #1929's actor allowlist remains broken

GitHub accepted attempt 2. The same run is now queued with replacement Strix job 101581481308; both live-head admission jobs are already GREEN. This retry is evidence generation only and does not resolve the separate CodeQL dispatch identity/status-publication defects.

Copy link
Copy Markdown
Contributor Author

Exact-head CodeQL recovery receipt for 0e9a204cde6d18fef8130ba6069917faea24553e:

  • run 34057700835 had terminal compatibility jobs whose log ended with DISPATCH_OUTCOME=success, VERDICT_STATE=pending; this was the intentional first-pass runner-release protocol, not an analysis failure;
  • after the repository dispatch-actor authorization repair, only the failed jobs were rerun without changing the PR head;
  • new jobs: 101610592215, 101610592333;
  • both jobs currently have steps=null and are queued before runner execution.

No GREEN, approval, merge readiness, predecessor-evidence transfer, bypass, or synthetic status is claimed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority: medium Normal-priority or P2 work status: needs-review Open pull request requiring current-head review or checks type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant