세 개의 required dispatch 워크플로가 모든 디스패치를 인가 거부하고 있습니다. 원인은 4a5dfd82(2026-08-31)가 디스패치 신원을 바꿨는데 allowlist 변수가 그대로 남은 것입니다.
인가 경계라 제가 고치지 않고 근거만 올립니다. 지금 디스패치하는 신원에 맞춰 변수를 넓히는 건 자물쇠를 열쇠에 맞추는 방향이라, 신원 변경이 정당했는지 판단이 먼저입니다.
증상
opencode-review-dispatch.yml success=466 failure=9609 last_success=2026-08-26
pr-review-fix-scheduler.yml success=405 failure=10 last_success=2026-08-16
codeql-scan-dispatch.yml success=0 failure=136 last_success=never
repository_dispatch authorization rejected actor=opencode-agent[bot] sender=opencode-agent[bot]
because both must match the configured scheduler identity.
vars.OPENCODE_REPOSITORY_DISPATCH_ACTOR = "github-actions[bot]" (2026-07-16 설정, 이후 미변경)
원인 — 커밋으로 특정됩니다
GH_TOKEN="$app_token" gh api -X POST .../dispatches 형태를 도입한 커밋은 하나뿐입니다.
4a5dfd82 2026-08-31 fix(review): require substantive agent verdicts (#1497)
opencode-review.yml이 OIDC로 exchange_github_app_token을 호출해 얻은 OpenCode App 토큰으로 디스패치하게 됐고, App 토큰은 앱 신원(opencode-agent[bot])으로 디스패치합니다.
타임라인이 정확히 맞습니다.
2026-07-16 변수를 "github-actions[bot]"로 설정
2026-08-26 마지막 성공 — 실측 actor=github-actions[bot]
2026-08-31 4a5dfd82 가 디스패치를 App 토큰으로 전환
이후 actor=opencode-agent[bot], 전량 거부
마지막 성공 run의 actor가 github-actions[bot]이고 이후 전부 opencode-agent[bot]이라는 건 API로 확인했습니다.
판단이 필요한 지점
4a5dfd82의 커밋 메시지는 신원 변경을 전혀 언급하지 않습니다. 제목과 본문 모두 "require substantive agent verdicts"뿐이고, 토큰 전환은 그 PR에 딸려 들어간 변경입니다. 그래서 의도된 보안 개선인지, 부수적으로 섞여 들어간 것인지가 커밋만으로는 갈리지 않습니다.
변수를 갱신하는 쪽에 유리한 정황:
- ambient
GITHUB_TOKEN 대신 OIDC 기반 저장소 스코프 App 토큰을 쓰는 건 권한 경계상 더 좁고 나은 방향입니다.
- 같은 저장소
pr-review-merge-scheduler.yml:387-388이 이미 opencode-agent[bot]을 정상 리뷰 작성자로 취급합니다.
디스패치 측을 되돌리는 쪽에 유리한 정황:
- 변경이 문서화되지 않았습니다. 그래서 아무도 allowlist를 갱신하지 않았고 9,609건이 조용히 거부됐습니다.
범위 — opencode 전용이 아닙니다
변수를 소비하는 곳이 셋입니다.
opencode-review-dispatch.yml:116 ALLOWED_DISPATCH_ACTOR: ${{ vars.OPENCODE_REPOSITORY_DISPATCH_ACTOR }}
codeql-scan-dispatch.yml:142 (동일)
pr-review-fix-scheduler.yml:115 (동일)
codeql-pr.yml:258도 같은 App 토큰 패턴으로 디스패치하고, 최근 codeql-scan-dispatch run 8건이 **전부 actor=opencode-agent[bot]**입니다.
중요한 귀결: codeql-scan-dispatch.yml은 지금 149행 SUPPLIED_MATRIX 템플릿 오류(#1925)로 인가 검사에 도달조차 못 합니다. 인가 검사(155~157행)는 149행과 같은 env: 블록이 붙은 같은 run: 스크립트 안에 있어서, env 평가가 실패하면 스크립트가 한 줄도 실행되지 않습니다. 실제 로그에도 성공 시 찍히는 Authorized repository_dispatch actor=... 줄이 없습니다.
따라서 #1925의 toJSON() 수정이 들어가면 149행을 통과하고 155행에 도달하는데, 이 변수가 그대로면 실패 지점이 한 칸 이동할 뿐 초록이 되지 않습니다. 두 이슈는 순서 의존이라 함께 봐야 합니다.
확인 방법
gh api "repos/ContextualWisdomLab/.github/actions/workflows/opencode-review-dispatch.yml/runs?status=success&per_page=1" \
--jq '.workflow_runs[0] | "actor=\(.actor.login) created=\(.created_at)"'
# -> actor=github-actions[bot] created=2026-08-26T18:22:23Z
gh api "repos/ContextualWisdomLab/.github/actions/workflows/opencode-review-dispatch.yml/runs?per_page=10" \
--jq '.workflow_runs[] | .actor.login' | sort -u
# -> opencode-agent[bot]
git log --format='%h %ad %s' --date=short -S'GH_TOKEN="$app_token" gh api -X POST' -- .github/workflows/opencode-review.yml
# -> 4a5dfd82 2026-08-31 fix(review): require substantive agent verdicts (#1497)
관련: #1925 (같은 워크플로의 선행 템플릿 오류)
세 개의 required dispatch 워크플로가 모든 디스패치를 인가 거부하고 있습니다. 원인은
4a5dfd82(2026-08-31)가 디스패치 신원을 바꿨는데 allowlist 변수가 그대로 남은 것입니다.인가 경계라 제가 고치지 않고 근거만 올립니다. 지금 디스패치하는 신원에 맞춰 변수를 넓히는 건 자물쇠를 열쇠에 맞추는 방향이라, 신원 변경이 정당했는지 판단이 먼저입니다.
증상
원인 — 커밋으로 특정됩니다
GH_TOKEN="$app_token" gh api -X POST .../dispatches형태를 도입한 커밋은 하나뿐입니다.opencode-review.yml이 OIDC로exchange_github_app_token을 호출해 얻은 OpenCode App 토큰으로 디스패치하게 됐고, App 토큰은 앱 신원(opencode-agent[bot])으로 디스패치합니다.타임라인이 정확히 맞습니다.
마지막 성공 run의 actor가
github-actions[bot]이고 이후 전부opencode-agent[bot]이라는 건 API로 확인했습니다.판단이 필요한 지점
4a5dfd82의 커밋 메시지는 신원 변경을 전혀 언급하지 않습니다. 제목과 본문 모두 "require substantive agent verdicts"뿐이고, 토큰 전환은 그 PR에 딸려 들어간 변경입니다. 그래서 의도된 보안 개선인지, 부수적으로 섞여 들어간 것인지가 커밋만으로는 갈리지 않습니다.변수를 갱신하는 쪽에 유리한 정황:
GITHUB_TOKEN대신 OIDC 기반 저장소 스코프 App 토큰을 쓰는 건 권한 경계상 더 좁고 나은 방향입니다.pr-review-merge-scheduler.yml:387-388이 이미opencode-agent[bot]을 정상 리뷰 작성자로 취급합니다.디스패치 측을 되돌리는 쪽에 유리한 정황:
범위 — opencode 전용이 아닙니다
변수를 소비하는 곳이 셋입니다.
codeql-pr.yml:258도 같은 App 토큰 패턴으로 디스패치하고, 최근codeql-scan-dispatchrun 8건이 **전부actor=opencode-agent[bot]**입니다.중요한 귀결:
codeql-scan-dispatch.yml은 지금 149행SUPPLIED_MATRIX템플릿 오류(#1925)로 인가 검사에 도달조차 못 합니다. 인가 검사(155~157행)는 149행과 같은env:블록이 붙은 같은run:스크립트 안에 있어서, env 평가가 실패하면 스크립트가 한 줄도 실행되지 않습니다. 실제 로그에도 성공 시 찍히는Authorized repository_dispatch actor=...줄이 없습니다.따라서 #1925의
toJSON()수정이 들어가면 149행을 통과하고 155행에 도달하는데, 이 변수가 그대로면 실패 지점이 한 칸 이동할 뿐 초록이 되지 않습니다. 두 이슈는 순서 의존이라 함께 봐야 합니다.확인 방법
관련: #1925 (같은 워크플로의 선행 템플릿 오류)