Skip to content

fix(attestation): bind reusable workflow source to OIDC identity - #2164

Draft
seonghobae wants to merge 10 commits into
mainfrom
fix/reusable-attestation-workflow-identity
Draft

seonghobae wants to merge 10 commits into
mainfrom
fix/reusable-attestation-workflow-identity

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Scope

Repairs the cross-repository reusable-workflow identity defect tracked by #1228 and establishes the prerequisite trust boundary for #2162. The canonical exact-artifact attestation workflow resolves its own called-workflow identity from GitHub OIDC job_workflow_ref + job_workflow_sha before trusted verifier checkout; caller github.workflow_sha is not used as callee authority.

Current authority

  • Exact head: b5966eaa6237c9260823969cbae6f64000cb08d7.
  • Protected/base main: 91be6442906c7b6b4f600272c953699708394327.
  • State: open · Draft · mechanically mergeable; current protected main is a direct merge parent and the branch is 0-behind by construction.
  • Fresh exact-head runs: Python Security 34966986415, SAST 34966986628, Security Scan 34966986455, Agent Review Runtime Quality 34966986465, CodeQL PR 34966986712; all are non-terminal at this receipt. No predecessor verdict transfers to this SHA.
  • No qualifying independent current-head APPROVED review is claimed.

Reconciliation lineage

Protected main advanced from 828eaaefb0cc97bba4da63eb9270447476d26710 to 91be6442906c7b6b4f600272c953699708394327. Fresh compare showed 27 main-side commits since the former owner head and no path overlap between the intervening main files and this PR's six owned attestation-identity files. Commit b5966eaa6237c9260823969cbae6f64000cb08d7 therefore adopts current protected main by an ordinary two-parent merge, preserving both histories without force push or destructive rebase. #2166 was then separately advanced onto this new parent rather than leaving the descendant on stale authority.

Trust boundary

Both verifier and signer jobs request a fresh runner OIDC token using a fixed audience, require GitHub issuer and github-hosted runner identity, require the exact central reusable-workflow path, require full 40-hex job_workflow_sha, require the same SHA suffix in job_workflow_ref, and checkout the trusted verifier only at that resolved SHA. Mutable refs, wrong issuer/audience/path/runner, malformed SHA, or disagreement between the OIDC claims fail before trusted source is materialized.

The verifier job keeps only the permissions required to read caller artifacts and identify its own called workflow; the signer independently repeats identity resolution before attestation authority is used.

Integration boundary

#2166 is non-force stacked on this exact head and must not be treated as immutable authority until this prerequisite normally integrates. Keep Draft until current-head gates and then-live review governance are admissible. No self-approval, force push, destructive rebase, protection bypass, synthetic status, mutable-ref dependency, or gate weakening is authorized.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact head 874f44f9cf7047a18d9815d1677e625f5c7a8c67, focusing on the reusable-workflow OIDC trust boundary: whether job_workflow_ref/job_workflow_sha are correctly distinguished from caller github.workflow_sha, whether any caller-controlled value can influence the trusted verifier checkout, whether the inline JWT-claim handling fails closed, and whether the new intake id-token: write privilege is narrowly justified. Please treat predecessor-head findings as historical.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

@seonghobae I will review exact head 874f44f9cf7047a18d9815d1677e625f5c7a8c67.

The review will check the callee identity claims, trusted checkout inputs, fail-closed JWT validation, and the scope of id-token: write. It will not transfer predecessor-head findings.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact prerequisite head 874f44f9cf7047a18d9815d1677e625f5c7a8c67. Focus on reusable-workflow OIDC identity (job_workflow_ref/job_workflow_sha), pre-checkout trust, GitHub-hosted runner restriction, issuer/audience validation, caller-vs-callee confusion, and any false-GREEN path that could let a caller select trusted verifier source. This is the prerequisite trust boundary for #2166/#2162.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== HEAD =='
git rev-parse HEAD
git status --short
printf '%s\n' '== requested commit object =='
git cat-file -t 874f44f9cf7047a18d9815d1677e625f5c7a8c67
printf '%s\n' '== workflow candidates =='
fd -t f 'exact-artifact-sbom-attestation\.yml$' .
printf '%s\n' '== YAML workflow outline =='
fd -t f 'exact-artifact-sbom-attestation\.yml$' . -x ast-grep outline {} --items all
printf '%s\n' '== identity-sensitive references =='
rg -n -i -C 4 '(job_workflow_(ref|sha)|ACTIONS_ID_TOKEN_REQUEST_(URL|TOKEN)|id-token\s*:|github\.workflow_sha|actions/checkout|github-hosted|issuer|audience|jwt|oidc)' -g '*.yml' -g '*.yaml' -g '*.md' .
printf '%s\n' '== tests and documentation candidates =='
fd -t f . . | rg -i '(exact.artifact|attestation|oidc|workflow).*\.(py|sh|yml|yaml|md|json)$' | head -200

Length of output: 151741


🏁 Script executed:

#!/bin/bash
set -euo pipefail

workflow=$(fd --hidden --type f '^exact-artifact-sbom-attestation\.yml$' . | head -n1)
test_identity="tests/test_reusable_attestation_workflow_identity.py"
test_contract="tests/test_exact_artifact_sbom_attestation_contract.py"
test_regressions="tests/test_exact_artifact_sbom_review_regressions.py"

printf 'workflow=%s\n' "$workflow"
printf '%s\n' '== workflow outline =='
ast-grep outline "$workflow" --items all
printf '%s\n' '== workflow numbered source =='
nl -ba "$workflow" | sed -n '1,520p'
printf '%s\n' '== targeted test outlines =='
ast-grep outline "$test_identity" --items all
ast-grep outline "$test_contract" --items all
ast-grep outline "$test_regressions" --items all
printf '%s\n' '== OIDC identity test source =='
nl -ba "$test_identity" | sed -n '1,520p'
printf '%s\n' '== attestation contract identity-related assertions =='
rg -n -C 5 '(oidc|OIDC|workflow_sha|workflow_ref|checkout|permissions|github-hosted|audience|issuer|JWT|token)' \
  "$test_contract" "$test_regressions"
printf '%s\n' '== exact workflow source references in tests =='
rg -n -C 3 'exact-artifact-sbom-attestation\.yml' tests

Length of output: 43248


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== exact-head diff from stated protected base =='
git diff --no-ext-diff --unified=80 d6cf5726cebfd031d0d11989b6fa34aab43452d0..874f44f9cf7047a18d9815d1677e625f5c7a8c67 -- \
  .github/workflows/exact-artifact-sbom-attestation.yml \
  tests/test_reusable_attestation_workflow_identity.py \
  tests/test_exact_artifact_sbom_attestation_contract.py \
  docs/doctoring/exact-artifact-sbom-attestation.md \
  ARCHITECTURE.md \
  CHANGELOG.d/20260913-reusable-attestation-workflow-identity.md
printf '%s\n' '== every checkout/ref source in attestation workflow =='
rg -n -C 5 '(uses:\s*actions/checkout|^\s*repository:|^\s*ref:|workflow_sha|workflow_ref|github\.workflow_sha|inputs\.source_sha)' \
  .github/workflows/exact-artifact-sbom-attestation.yml
printf '%s\n' '== full attestation permission contract section =='
nl -ba tests/test_exact_artifact_sbom_attestation_contract.py | sed -n '115,185p'
printf '%s\n' '== all direct source-execution surfaces before verifier checkout =='
nl -ba .github/workflows/exact-artifact-sbom-attestation.yml | sed -n '64,170p'
nl -ba .github/workflows/exact-artifact-sbom-attestation.yml | sed -n '234,340p'
printf '%s\n' '== all occurrences of resolver or trusted verifier directories =='
rg -n -C 2 '(trusted-intake|trusted-signer|workflow-identity|verify_exact_artifact_sbom_handoff)' \
  .github/workflows/exact-artifact-sbom-attestation.yml tests

Length of output: 99900


🤖 web_search executed:

site:docs.github.com GitHub Actions OIDC reference job_workflow_ref job_workflow_sha reusable workflow runner_environment audience issuer

Length of output: 18513


@seonghobae I reviewed exact head 874f44f9cf7047a18d9815d1677e625f5c7a8c67.

I found no blocking issue in the requested trust boundary.

  • The workflow does not use caller-oriented github.workflow_sha for the trusted verifier checkout.
  • Each job resolves job_workflow_ref and job_workflow_sha before checkout.
  • Each resolver requires the GitHub issuer, the fixed audience, runner_environment == "github-hosted", the exact central workflow path, lowercase 40-hex SHAs, and equality between the ref suffix and SHA claim.
  • Each trusted checkout fixes repository to ContextualWisdomLab/.github. It uses only steps.workflow-identity.outputs.workflow_sha as ref. Caller inputs cannot select the repository or ref.
  • The intake job has the narrow added privilege: actions: read, contents: read, and id-token: write. It has no attestations: write or artifact-metadata: write.
  • The signer independently repeats the called-workflow identity resolution before its own trusted checkout.
  • The workflow uses pinned actions and disables persisted checkout credentials.

The implementation matches GitHub’s reusable-workflow claim model. workflow_ref and workflow_sha describe the caller context. job_workflow_ref and job_workflow_sha identify the called reusable workflow. See the GitHub OIDC reference and OIDC with reusable workflows.

I completed static inspection only. I did not execute repository code or tests. Hosted checks remain the required runtime evidence.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact head 73f5b9d3b2664521faf9033743d94d2746ddb12f. This is an ordinary two-parent reconciliation with protected main@78393ea901efc0d57b35dd1e383e473425b7c1da; no predecessor review is being transferred.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='73f5b9d3b2664521faf9033743d94d2746ddb12f'
base='78393ea901efc0d57b35dd1e383e473425b7c1da'

printf '%s\n' '== exact objects and topology =='
git cat-file -t "$head"
git cat-file -t "$base"
git show -s --format='head=%H%nparents=%P%nsubject=%s' "$head"
printf 'merge-base=%s\n' "$(git merge-base "$head" "$base")"
printf '%s\n' '== head changes relative to protected main =='
git diff-tree --no-commit-id --name-status -r "$base" "$head"
printf '%s\n' '== merge-only resolution changes relative to each parent =='
git diff-tree --cc --no-commit-id --name-status -r "$head"
printf '%s\n' '== workflow candidate =='
fd --hidden --type f '^exact-artifact-sbom-attestation\.yml$' .
printf '%s\n' '== workflow identity-sensitive source at exact head =='
git show "$head:.github/workflows/exact-artifact-sbom-attestation.yml" | nl -ba | \
  sed -n '1,380p'
printf '%s\n' '== workflow checkout and claim reference inventory =='
git show "$head:.github/workflows/exact-artifact-sbom-attestation.yml" | \
  rg -n -C 4 '(job_workflow_(ref|sha)|github\.workflow_sha|ACTIONS_ID_TOKEN_REQUEST_(URL|TOKEN)|id-token:|actions/checkout|repository:|ref:|github-hosted|issuer|audience|jwt|JWT|curl|jq)'
printf '%s\n' '== focused test source candidates =='
for f in \
  tests/test_reusable_attestation_workflow_identity.py \
  tests/test_exact_artifact_sbom_attestation_contract.py \
  tests/test_exact_artifact_sbom_review_regressions.py; do
  if git cat-file -e "$head:$f" 2>/dev/null; then
    printf '%s\n' "-- $f --"
    git show "$head:$f" | rg -n -C 4 '(job_workflow_(ref|sha)|workflow_sha|workflow_ref|id-token|checkout|github-hosted|issuer|audience|OIDC|oidc)' || true
  fi
done
printf '%s\n' '== differences from predecessor in owned trust-boundary files =='
git diff --no-ext-diff --unified=30 \
  874f44f9cf7047a18d9815d1677e625f5c7a8c67 "$head" -- \
  .github/workflows/exact-artifact-sbom-attestation.yml \
  tests/test_reusable_attestation_workflow_identity.py \
  tests/test_exact_artifact_sbom_attestation_contract.py \
  tests/test_exact_artifact_sbom_review_regressions.py \
  docs/doctoring/exact-artifact-sbom-attestation.md \
  ARCHITECTURE.md \
  CHANGELOG.d/20260913-reusable-attestation-workflow-identity.md

Length of output: 37835


🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='73f5b9d3b2664521faf9033743d94d2746ddb12f'
first_parent='874f44f9cf7047a18d9815d1677e625f5c7a8c67'
second_parent='78393ea901efc0d57b35dd1e383e473425b7c1da'

printf '%s\n' '== adopted protected-main delta: first parent to merge head =='
git diff-tree --no-commit-id --name-status -r "$first_parent" "$head"
printf '%s\n' '== merge head patch against first parent =='
git diff --no-ext-diff --unified=40 "$first_parent" "$head" -- \
  .github/workflows/exact-artifact-sbom-attestation.yml \
  tests/test_reusable_attestation_workflow_identity.py \
  tests/test_exact_artifact_sbom_attestation_contract.py \
  tests/test_exact_artifact_sbom_review_regressions.py \
  CHANGELOG.d \
  docs \
  ARCHITECTURE.md
printf '%s\n' '== exact first-parent vs merge workflow identity semantic diff =='
git diff --no-ext-diff --word-diff=plain "$first_parent" "$head" -- \
  .github/workflows/exact-artifact-sbom-attestation.yml
printf '%s\n' '== parent file differences that touch workflow or OIDC terms =='
git diff --no-ext-diff --name-only "$first_parent" "$second_parent" | \
  while IFS= read -r f; do
    case "$f" in
      *.yml|*.yaml|*.py|*.md)
        if git show "$second_parent:$f" 2>/dev/null | rg -q '(exact-artifact|job_workflow|OIDC|oidc|checkout)'; then
          printf '%s\n' "$f"
        fi
        ;;
    esac
  done

Length of output: 13067


@seonghobae I reviewed exact head 73f5b9d3b2664521faf9033743d94d2746ddb12f.

I found no blocking issue.

The commit has these two parents:

  • 874f44f9cf7047a18d9815d1677e625f5c7a8c67
  • 78393ea901efc0d57b35dd1e383e473425b7c1da

Its merge base with protected main is 78393ea901efc0d57b35dd1e383e473425b7c1da.

Git reports no merge-resolution delta. The exact head does not alter .github/workflows/exact-artifact-sbom-attestation.yml relative to its predecessor parent. It therefore preserves the reviewed OIDC trust boundary.

The reconciliation adopts protected-main changes only in the contextual-orchestrator sidecar files, its ADR, and its changelog entry. Those changes do not modify the reusable-workflow verifier identity, trusted checkout repository or ref, OIDC claim checks, or intake permissions.

This review is limited to static source and Git topology inspection. I did not execute repository code or tests. Exact-head CI and independent approval remain required before merge authorization.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Exact head changed to 834d5163cb306a540a9064931a2694a730b9cd3f after ordinary reconciliation with protected main@828eaaefb0cc97bba4da63eb9270447476d26710. Please review the current exact head only; predecessor verdicts do not transfer.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='834d5163cb306a540a9064931a2694a730b9cd3f'
base='828eaaefb0cc97bba4da63eb9270447476d26710'
previous='73f5b9d3b2664521faf9033743d94d2746ddb12f'

printf '%s\n' '== exact objects and checked-out HEAD =='
printf 'checked_out=%s\n' "$(git rev-parse HEAD)"
git cat-file -t "$head"
git cat-file -t "$base"
git show -s --format='head=%H%nparents=%P%nsubject=%s' "$head"
printf 'merge_base=%s\n' "$(git merge-base "$head" "$base")"

printf '%s\n' '== delta from stated protected base =='
git diff-tree --no-commit-id --name-status -r "$base" "$head"

printf '%s\n' '== merge resolution delta =='
git diff-tree --cc --no-commit-id --name-status -r "$head"

printf '%s\n' '== exact base diff for owned identity files =='
git diff --no-ext-diff --unified=60 "$base" "$head" -- \
  .github/workflows/exact-artifact-sbom-attestation.yml \
  tests/test_reusable_attestation_workflow_identity.py \
  tests/test_exact_artifact_sbom_attestation_contract.py \
  tests/test_exact_artifact_sbom_review_regressions.py \
  docs/doctoring/exact-artifact-sbom-attestation.md \
  ARCHITECTURE.md \
  CHANGELOG.d/20260913-reusable-attestation-workflow-identity.md

printf '%s\n' '== semantic delta from immediate predecessor in trust-boundary workflow =='
git diff --no-ext-diff --word-diff=plain "$previous" "$head" -- \
  .github/workflows/exact-artifact-sbom-attestation.yml

printf '%s\n' '== reusable workflow source at exact head =='
git show "$head:.github/workflows/exact-artifact-sbom-attestation.yml" | nl -ba | sed -n '1,420p'

printf '%s\n' '== identity-sensitive workflow inventory =='
git show "$head:.github/workflows/exact-artifact-sbom-attestation.yml" | \
  rg -n -C 5 '(job_workflow_(ref|sha)|github\.workflow_sha|ACTIONS_ID_TOKEN_REQUEST_(URL|TOKEN)|id-token:|actions/checkout|repository:|ref:|github-hosted|issuer|audience|jwt|JWT|curl|jq|persist-credentials)'

printf '%s\n' '== focused static test assertions at exact head =='
for f in \
  tests/test_reusable_attestation_workflow_identity.py \
  tests/test_exact_artifact_sbom_attestation_contract.py \
  tests/test_exact_artifact_sbom_review_regressions.py; do
  if git cat-file -e "$head:$f" 2>/dev/null; then
    printf '%s\n' "-- $f --"
    git show "$head:$f" | rg -n -C 4 '(job_workflow_(ref|sha)|github\.workflow_sha|id-token|checkout|github-hosted|issuer|audience|OIDC|oidc|permissions)' || true
  fi
done

Length of output: 105171


@seonghobae I reviewed only exact head 834d5163cb306a540a9064931a2694a730b9cd3f.

I found one blocking trust-boundary issue.

JWT signature validation is missing. In .github/workflows/exact-artifact-sbom-attestation.yml, both Resolve exact called reusable workflow identity steps split the JWT and base64-decode its payload. They then trust iss, aud, runner_environment, job_workflow_ref, and job_workflow_sha. The resolver does not validate the JWS signature against GitHub’s OIDC JWKS. It also does not validate the token time claims.

The checks fail on malformed JSON and mismatched decoded fields. They do not fail on a syntactically valid JWT payload with an invalid or absent signature. The trusted checkout ref derives from that unverified job_workflow_sha.

Validate the token signature, issuer, audience, and applicable time claims with GitHub’s published OIDC keys before writing workflow_sha to GITHUB_OUTPUT. Do this in both jobs, or place the shared resolver in a separately pinned and trusted action or script.

The remaining reviewed controls are correct:

  • The exact head is checked out and has the stated protected main commit as its merge base.
  • The ordinary merge has no merge-resolution delta.
  • The workflow does not use caller-oriented github.workflow_sha for the verifier checkout.
  • The checkout repository is fixed to ContextualWisdomLab/.github.
  • The checkout ref derives only from the resolved workflow-identity output.
  • The resolver runs before each trusted checkout.
  • The intake job adds only id-token: write beyond its existing read permissions. It has no attestation or artifact-metadata write permission.
  • Both jobs require the expected central workflow path, a lowercase 40-hex SHA, and equality between the job_workflow_ref suffix and job_workflow_sha.
  • Both checkouts disable persisted credentials.

This was a static review. I did not execute repository code or tests.

You are interacting with an AI system.

Adopt protected main@91be6442906c7b6b4f600272c953699708394327 without force-push while preserving the reusable-attestation workflow identity owner delta. The intervening main files do not overlap the six owner files.
seonghobae added a commit that referenced this pull request Sep 15, 2026
Ordinary-forward adoption of #2164 current head b5966ea after protected main advanced. Preserve the product-performance attestation owner delta and quality-manifest repair without force-push or destructive rebase.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact current head b5966eaa6237c9260823969cbae6f64000cb08d7 only. Focus on the ordinary-forward protected-main adoption: verify the six reusable-attestation identity owner files preserve the OIDC job_workflow_ref/job_workflow_sha trust boundary, no intervening main@91be6442906c7b6b4f600272c953699708394327 security/runtime delta was lost, and the stack remains 0-behind without force/rebase. Do not transfer predecessor verdicts.

@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='b5966eaa6237c9260823969cbae6f64000cb08d7'
base='91be6442906c7b6b4f600272c953699708394327'
pr='2164'
repo='ContextualWisdomLab/.github'

printf '%s\n' '== exact objects and topology =='
printf 'checked_out=%s\n' "$(git rev-parse HEAD)"
git cat-file -t "$head"
git cat-file -t "$base"
git show -s --format='head=%H%nparents=%P%nsubject=%s' "$head"
printf 'merge_base=%s\n' "$(git merge-base "$head" "$base")"
printf 'base_is_ancestor=%s\n' "$(git merge-base --is-ancestor "$base" "$head" && echo yes || echo no)"
printf 'head_is_ancestor_of_base=%s\n' "$(git merge-base --is-ancestor "$head" "$base" && echo yes || echo no)"

printf '%s\n' '== merge-resolution delta =='
git diff-tree --cc --no-commit-id --name-status -r "$head"

printf '%s\n' '== exact head delta from protected main =='
git diff-tree --no-commit-id --name-status -r "$base" "$head"

printf '%s\n' '== first-parent and protected-main relation =='
first_parent=$(git show -s --format='%P' "$head" | awk '{print $1}')
second_parent=$(git show -s --format='%P' "$head" | awk '{print $2}')
printf 'first_parent=%s\nsecond_parent=%s\n' "$first_parent" "$second_parent"
printf 'base_is_second_parent=%s\n' "$([ "$second_parent" = "$base" ] && echo yes || echo no)"
printf '%s\n' '== protected-main changes adopted by merge head =='
git diff-tree --no-commit-id --name-status -r "$first_parent" "$head"
printf '%s\n' '== first-parent changes retained by merge head =='
git diff-tree --no-commit-id --name-status -r "$base" "$head"

printf '%s\n' '== identity owner file candidates in exact-head delta =='
git diff --no-ext-diff --name-only "$base" "$head" | rg -i '(exact-artifact|attestation|reusable.*identity|workflow.*identity|20260913-reusable)' || true

printf '%s\n' '== exact owner-file delta relative to first parent =='
git diff --no-ext-diff --name-status "$first_parent" "$head" -- \
  .github/workflows/exact-artifact-sbom-attestation.yml \
  tests/test_reusable_attestation_workflow_identity.py \
  tests/test_exact_artifact_sbom_attestation_contract.py \
  tests/test_exact_artifact_sbom_review_regressions.py \
  docs/doctoring/exact-artifact-sbom-attestation.md \
  ARCHITECTURE.md \
  CHANGELOG.d/20260913-reusable-attestation-workflow-identity.md

printf '%s\n' '== reusable workflow trust-boundary inventory at exact head =='
git show "$head:.github/workflows/exact-artifact-sbom-attestation.yml" | \
  rg -n -C 4 '(job_workflow_(ref|sha)|github\.workflow_sha|ACTIONS_ID_TOKEN_REQUEST_(URL|TOKEN)|id-token:|actions/checkout|repository:|ref:|github-hosted|issuer|audience|jwt|JWT|persist-credentials)'

printf '%s\n' '== identity test assertions at exact head =='
for f in \
  tests/test_reusable_attestation_workflow_identity.py \
  tests/test_exact_artifact_sbom_attestation_contract.py \
  tests/test_exact_artifact_sbom_review_regressions.py; do
  if git cat-file -e "$head:$f" 2>/dev/null; then
    printf '%s\n' "-- $f --"
    git show "$head:$f" | rg -n -C 3 '(job_workflow_(ref|sha)|github\.workflow_sha|id-token|checkout|github-hosted|issuer|audience|OIDC|oidc|permissions)' || true
  fi
done

printf '%s\n' '== GitHub PR state and commit list =='
gh pr view "$pr" --repo "$repo" --json number,state,isDraft,headRefName,headRefOid,baseRefName,baseRefOid,mergeStateStatus,mergeable,commits \
  --jq '{number,state,isDraft,headRefName,headRefOid,baseRefName,baseRefOid,mergeStateStatus,mergeable,commits:[.commits[]|{oid:.oid,parents:[.parents[].oid],messageHeadline:.messageHeadline}]}' || true

Length of output: 20506


@seonghobae I reviewed only exact head b5966eaa6237c9260823969cbae6f64000cb08d7.

I found one blocking issue in the current exact head.

The OIDC resolver still does not validate the JWT signature or time claims. Both Resolve exact called reusable workflow identity steps decode the JWT payload and trust job_workflow_ref and job_workflow_sha. The steps do not verify the JWS signature against GitHub’s JWKS. The steps also do not validate applicable time claims, such as exp and nbf.

The trusted checkout uses steps.workflow-identity.outputs.workflow_sha. Therefore, an unverified token payload can select the trusted verifier ref. This finding is based on the current exact-head workflow content, not on a predecessor verdict.

Validate the token signature with GitHub’s published OIDC keys before using any claim. Validate the issuer, audience, and applicable time claims as part of that verification. Apply the control in both resolver steps.

The protected-main adoption has the expected current topology:

  • b5966eaa6237c9260823969cbae6f64000cb08d7 is a two-parent merge.
  • Its parents are 834d5163cb306a540a9064931a2694a730b9cd3f and protected main@91be6442906c7b6b4f600272c953699708394327.
  • Protected main is the direct second parent and the merge base.
  • The merge has no merge-resolution delta.
  • The merge head retains the six identity owner-file changes relative to protected main.
  • The merge head adopts the intervening protected-main security and runtime changes, including the SAST, security-scan, OpenCode, CodeQL gate, Pingora policy, and related test changes.

The six owner files have no delta relative to the first parent. They preserve the current static controls:

  • The workflow does not use github.workflow_sha for the trusted checkout.
  • Both resolvers require job_workflow_ref and job_workflow_sha.
  • Both resolvers require the GitHub issuer, the fixed audience, github-hosted, the exact workflow path, full lowercase 40-hex SHAs, and matching SHA values.
  • Both checkouts use the fixed ContextualWisdomLab/.github repository and the resolved workflow_sha.
  • Both checkouts set persist-credentials: false.
  • The intake job has actions: read, contents: read, and the required id-token: write. It does not have attestation-write permissions.

The commit graph confirms an ordinary forward merge and 0-behind ancestry at the inspected commits. The GitHub PR metadata query did not return commit data, so I could not independently verify remote push history or GitHub’s live mergeability state.

You are interacting with an AI system.

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