Skip to content

fix(security-scan): name Git's initial branch for every exact-head checkout - #2154

Open
seonghobae wants to merge 10 commits into
mainfrom
fix/security-scan-checkout-default-branch-2101
Open

fix(security-scan): name Git's initial branch for every exact-head checkout#2154
seonghobae wants to merge 10 commits into
mainfrom
fix/security-scan-checkout-default-branch-2101

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Closes #2101.

Production change

.github/workflows/security-scan.yml adds one workflow-level process-local Git configuration block between permissions: and jobs::

env:
  GIT_CONFIG_COUNT: "1"
  GIT_CONFIG_KEY_0: init.defaultBranch
  GIT_CONFIG_VALUE_0: main

All six actions/checkout steps in the central Security Scan initialise a fresh repository before fetching their exact SHA. Git 2.28+ otherwise emits the implicit-master / Git-3.0 default-branch warning. The three process-local variables reach checkout's internal git init without writing global user configuration and without suppressing stderr. No job, step, checkout identity, ref/sha, or security-gate semantics changed.

Permanent contract

tests/test_security_scan_checkout_default_branch_contract.py now requires the three reviewed settings as unique direct workflow-level env: scalar entries, rejects job/step shadowing of GIT_CONFIG_COUNT, GIT_CONFIG_KEY_0, or GIT_CONFIG_VALUE_0, rejects git config --global / downstream init.defaultBranch writes, rejects indented block-scalar payload text impersonating workflow env authority, and requires the six exact-head checkouts to remain present.

The test remains separate from #2143's tests/test_required_workflow_queue_contract.py lane; the original branch verified those branches have no merge-tree conflict.

RED → GREEN evidence

The initial implementation head fa06536652edf707e961f3e6ff950340b2c41315 had PR-triggered Security Scan, SAST Semgrep, CodeQL PR, and Python Security terminal SUCCESS. Its local full-suite evidence was coverage run -m pytest tests: 3058 passed, 1 skipped, 7 failed; coverage 100%; interrogate 100%; YAML load clean. The seven failures were timing/process-smoke cases reported as unrelated to this diff and reran 31/31 green in isolation under a heavily loaded host. They are predecessor evidence, not current-head authority.

A first contract review found GIT_CONFIG_VALUE_0 shadowing was not rejected. Regression-only exact df7b8564fc6042858cc232371f823cf9d5440bcd added a hostile job-level GIT_CONFIG_VALUE_0: master; repair exact af7a068772204d9bde0518510d80733bd5a5206d rejects all three COUNT/KEY/VALUE shadowing paths. That exact later reacquired Security Scan 34753620111, SAST Semgrep 34753620117, CodeQL PR 34753620110, and Python Security 34753620169 terminal SUCCESS. Production security-scan.yml did not change in this contract-only repair.

A second fresh review found the workflow-level helper still used substring search inside the captured env: text, so valid YAML could place the reviewed strings inside DECOY: | rather than as direct environment keys. The first hostile-fixture attempt at exact 184d348e7ad65ce4258781c4d4d72deff8c307a4 was ineffective because its final scalar line met the regex capture boundary; its 4/4 GREEN verifier is therefore a harness-fixture defect, not RED evidence.

Corrected regression-only exact 7d8fe3b250bf8edac654ae5e7e18b826badcbb8e keeps all three impersonating strings inside the captured scalar payload. Purpose run 34756214540 / 103720904858 completed FAILURE in the focused test, proving the old validator accepted non-authoritative scalar text.

Minimal repair exact 287b0c1c5cf4031ca091f5000c01580ad8766db3 requires exactly one direct two-space scalar entry for each reviewed workflow-level Git config key/value. Purpose run 34756286194 / 103721090370 completed SUCCESS on Ubuntu 24.04: exact checkout, pinned Python dependencies, all four focused cases including the hostile block-scalar regression, and clean working-tree verification passed. The temporary verifier was removed immediately by ordinary descendant 77a4eacb64014650d2818ced739c30e334185ddc. The second hardening slice is test-contract-only; production security-scan.yml remains unchanged.

Current exact-head gates

Current exact head is 77a4eacb64014650d2818ced739c30e334185ddc, base main@64f483db9d052322c65bcdf1675d66138156f306.

Normal PR-triggered lanes on this exact cleanup head are now terminal:

  • Security Scan 34756326070: SUCCESS.
  • SAST Semgrep 34756326039: SUCCESS.
  • Python Security 34756325935: SUCCESS.
  • CodeQL PR 34756325904: initial attempt FAILURE only because current-head dispatch verdicts were still pending; language detection and dispatch itself succeeded. The compatibility jobs failed at Release runner or enforce current-head CodeQL verdict with the explicit message that the dispatch workflow must publish the terminal verdict and rerun the exact failed job. This is the still-open canonical .github#1929 terminal-status-publication lane, not a fix(security-scan): name Git's initial branch for every exact-head checkout #2154 source failure to suppress or bypass.

Commit statuses currently show CodeRabbit and Devin Review success, but there is still no independent submitted current-head APPROVED. Status checks or bot quota state are not substituted for review authority.

Promotion boundary

Keep the normal protected merge path. #2154 may merge only when current-head applicable required checks satisfy repository rules and an independent approval exists. Do not self-approve, bypass, weaken CodeQL, force-push, or reuse predecessor checks as current-head authority.

After normal protected integration, run an unchanged LifeOS consumer canary against the central Security Scan from .github/main; require the implicit-master / Git-3.0 warning to be absent while the same security jobs retain their prior semantics. That downstream proof is the completion boundary for #2101.

No warning suppression, global gitconfig mutation, force-push, destructive rebase, self-approval, administrator bypass, or gate weakening.

…eckout

Closes #2101. Each actions/checkout step initialises a fresh repository
before fetching the exact SHA, and Git 2.28+ prints the "Using 'master' as
the name for the initial branch" hint plus the Git 3.0 rename warning on
every hosted job. Workflow-level GIT_CONFIG_COUNT/KEY_0/VALUE_0 sets
init.defaultBranch=main process-locally -- no global gitconfig write, no
stderr suppression -- which the issue's hosted probe verified removes both
lines. A dedicated contract test pins the three variables at workflow level
and rejects per-job overrides or global writes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 3 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: Advanced

Run ID: 2de8b107-eeb8-40a9-9115-516ae21ac74f

📥 Commits

Reviewing files that changed from the base of the PR and between 828eaae and c393e3a.

📒 Files selected for processing (2)
  • .github/workflows/security-scan.yml
  • tests/test_security_scan_checkout_default_branch_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.

Copy link
Copy Markdown
Contributor Author

추가 contract finding을 확인해 current head에서 수리했습니다.

기존 test_no_step_overrides_or_globalises_the_initial_branch_settingGIT_CONFIG_COUNTGIT_CONFIG_KEY_0 shadowing은 막았지만 GIT_CONFIG_VALUE_0의 job/step override는 검사하지 않았습니다. 따라서 workflow-level GIT_CONFIG_VALUE_0: main을 유지한 채 job-level GIT_CONFIG_VALUE_0: master를 추가하면 실제 checkout의 process-local Git config 값은 다시 master로 바뀌는데도 계약이 통과할 수 있었습니다.

Regression-only exact df7b8564fc6042858cc232371f823cf9d5440bcd에서 production workflow는 건드리지 않고 hostile job-level value override fixture를 추가했습니다. 기존 validator가 이 fixture를 수용하는 RED를 재현했습니다. Minimal repair exact af7a068772204d9bde0518510d80733bd5a5206d는 jobs body에서 GIT_CONFIG_VALUE_0 shadowing도 fail closed하고 동일 hostile fixture를 permanent regression으로 유지합니다. 기존 COUNT/KEY/global gitconfig/init.defaultBranch/checkout-count 경계는 그대로입니다.

Current-head PR-triggered Security Scan, SAST Semgrep, CodeQL PR, Python Security runs are currently queued, so hosted GREEN으로는 아직 승격하지 않습니다. 이 finding은 #2101의 exact acceptance를 강화하는 test-contract repair이며 production .github/workflows/security-scan.yml의 causal fix는 변경하지 않았습니다.

@coderabbitai review
Please review exact head af7a068772204d9bde0518510d80733bd5a5206d, especially whether the permanent regression now closes all three GIT_CONFIG_COUNT / GIT_CONFIG_KEY_0 / GIT_CONFIG_VALUE_0 job-or-step shadowing paths without weakening the workflow-level repair.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

target='af7a068772204d9bde0518510d80733bd5a5206d'

git cat-file -e "${target}^{commit}"
printf '%s\n' '=== exact commit summary ==='
git show --no-ext-diff --format=fuller --stat "$target"
printf '%s\n' '=== exact commit patch ==='
git diff --no-ext-diff "${target}^" "$target" -- \
  .github/workflows/security-scan.yml \
  tests/test_security_scan_checkout_default_branch_contract.py

printf '%s\n' '=== relevant test outline ==='
ast-grep outline tests/test_security_scan_checkout_default_branch_contract.py --items all || true
printf '%s\n' '=== relevant test content ==='
cat -n tests/test_security_scan_checkout_default_branch_contract.py

printf '%s\n' '=== production workflow header and checkout locations ==='
sed -n '1,100p' .github/workflows/security-scan.yml
rg -n -C 5 'uses:\s*actions/checkout@|GIT_CONFIG_(COUNT|KEY_0|VALUE_0)|^\s*jobs:' .github/workflows/security-scan.yml

printf '%s\n' '=== target-parent versions of the test (for exact-head comparison) ==='
git show "${target}^:tests/test_security_scan_checkout_default_branch_contract.py" | cat -n
printf '%s\n' '=== all tracked test references to initial branch contract ==='
rg -n -C 3 'GIT_CONFIG_(COUNT|KEY_0|VALUE_0)|init\.defaultBranch' tests/test_security_scan_checkout_default_branch_contract.py .github/workflows/security-scan.yml

Length of output: 23523


@seonghobae 정적 검토에서 blocking finding은 없습니다.

_assert_jobs_do_not_override_initial_branch()jobs: 이후의 전체 body를 검사합니다. 따라서 job-level과 step-level env:는 모두 검사 범위에 포함됩니다.

이제 validator는 세 정확한 환경 변수 이름을 모두 거부합니다.

  • GIT_CONFIG_COUNT
  • GIT_CONFIG_KEY_0
  • GIT_CONFIG_VALUE_0

새 hostile fixture는 이전에 누락된 GIT_CONFIG_VALUE_0: master job-level shadowing이 AssertionError를 발생시키는지 확인합니다. 공통 validator를 사용하므로 동일한 금지 조건은 step-level value override에도 적용됩니다.

workflow-level repair도 유지됩니다. .github/workflows/security-scan.yml에는 GIT_CONFIG_COUNT: "1", GIT_CONFIG_KEY_0: init.defaultBranch, GIT_CONFIG_VALUE_0: mainjobs: 전에 남아 있습니다. 여섯 actions/checkout 단계도 유지됩니다. 이 commit은 production workflow를 변경하지 않습니다.

Hosted check은 아직 queued 상태이므로, 이 결론은 exact head의 정적 계약 검토에 한정됩니다.


✏️ Learnings added
Learnt from: seonghobae
URL: https://github.com/ContextualWisdomLab/.github/pull/2154

Timestamp: 2026-09-13T11:08:45.350Z
Learning: In `.github/workflows/security-scan.yml`, the workflow-level process-local Git configuration requires all three exact variables: `GIT_CONFIG_COUNT: "1"`, `GIT_CONFIG_KEY_0: init.defaultBranch`, and `GIT_CONFIG_VALUE_0: main`. Any occurrence of these variables in the `jobs:` body can shadow the workflow-level setting and must fail the checkout default-branch contract.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

⚠️ 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

Protected main advanced independently to 78393ea901efc0d57b35dd1e383e473425b7c1da (#2163). I adopted that intervening delta with an ordinary non-force merge-forward instead of rebasing or copying source.

Current exact #2154 head is 64444d34953244c0f72f9a1ff62c2083bd547fad, with parents prior owner head 77a4eacb64014650d2818ced739c30e334185ddc and protected main@78393ea901efc0d57b35dd1e383e473425b7c1da. Fresh comparison from protected main to this head still contains exactly the two owner paths only:

  • .github/workflows/security-scan.yml
  • tests/test_security_scan_checkout_default_branch_contract.py

So the contextual-orchestrator sidecar advance and current-head coalescer changes from protected main are preserved, while #2154's production/test delta is unchanged. No force push, destructive rebase, gate weakening, or predecessor-check transfer occurred.

Fresh PR-triggered runs on 64444d3495... are now queued: Security Scan 34760485217, SAST Semgrep 34760485179, Python Security 34760485204, CodeQL PR 34760485380. Treat predecessor GREENs as historical only; promotion still requires terminal current-head applicable gates and an independent submitted current-head approval. The CodeQL bootstrap/settlement dependency remains #1929/#2106; exact self-bootstrap evidence was added to #1929 rather than bypassed here.

Copy link
Copy Markdown
Contributor Author

Fresh protected-main adoption completed without rebase or force-push. .github/main advanced from the prior merge base 78393ea901efc0d57b35dd1e383e473425b7c1da to 828eaaefb0cc97bba4da63eb9270447476d26710; compare showed #2154 was behind by 2 commits, and those protected-main commits touched only Noema document-review/runtime files, not .github/workflows/security-scan.yml or tests/test_security_scan_checkout_default_branch_contract.py.

I constructed an ordinary two-parent descendant using protected main@828eaaef... as the base tree plus the exact two #2154-owned blobs, then moved fix/security-scan-checkout-default-branch-2101 with force=false. New exact head: c393e3af1d73cafd87002eb8037b7854eac1173a; parents are prior #2154 head 64444d34953244c0f72f9a1ff62c2083bd547fad and protected main 828eaaefb0cc97bba4da63eb9270447476d26710. Fresh compare 828eaaef... -> c393e3af... is behind_by=0 and retains exactly the two intended #2154 paths. Predecessor hosted results are not promoted to this head; current-head checks/review must reacquire normally.

@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 introduces workflow-level process-local Git configuration (GIT_CONFIG_COUNT/KEY_0/VALUE_0) to suppress Git 2.28+ initial-branch hints during exact-head checkouts, paired with contract tests that enforce presence, prevent shadowing, and reject hostile overrides. Verified probes confirm the configuration suppresses the hint without leaking into downstream jobs, the contract tests pass, and the checkout count assertion is accurate.

Reviewed changed lines

  • .github/workflows/security-scan.yml:63 (RIGHT): GIT_CONFIG_COUNT=1 scopes the process-local Git configuration correctly, suppressing initial-branch hints during actions/checkout.
  • .github/workflows/security-scan.yml:64 (RIGHT): GIT_CONFIG_KEY_0 defines init.defaultBranch; simulation confirms downstream jobs are not adversely affected.
  • .github/workflows/security-scan.yml:65 (RIGHT): GIT_CONFIG_VALUE_0=main names the initial branch, matching the intended behavior.
  • tests/test_security_scan_checkout_default_branch_contract.py:37 (RIGHT): The helper correctly extracts the workflow-level env block; executable pytest run passes.
  • tests/test_security_scan_checkout_default_branch_contract.py:51 (RIGHT): The checkout count assertion matches exactly six actual checkout steps, providing an accurate lower bound.

Adversarial validation

  • .github/workflows/security-scan.yml:63 (RIGHT) falsified: GIT_CONFIG_COUNT=1 plus KEY_0/VALUE_0 does not suppress Git 2.28+ hints during actions/checkout. — Checkout succeeded with initial branch 'main' and no hint in stderr.
  • .github/workflows/security-scan.yml:64 (RIGHT) falsified: Process-local Git config leaks into downstream jobs, changing expected init.defaultBranch behavior. — No downstream job performs a fresh git init expecting a non-main default branch; the setting is benign.
  • Residual risk: No concrete regression identified; future changes to the workflow env block or checkout steps could require updating the contract tests.

Findings

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

Copy link
Copy Markdown
Contributor Author

Fresh protected-base repair finding: this PR is now stale against protected main@7f07029381a9ca770d0a68b7f3938dd652799d4d (PR head c393e3af1d73cafd87002eb8037b7854eac1173a, merge base 828eaaef...). The intervening protected delta modifies .github/workflows/security-scan.yml itself, alongside queue/security contracts, so a blind two-parent tree carryover or old-file overlay would discard current protected Security Scan behavior.

Current protected security-scan.yml still lacks the workflow-level GIT_CONFIG_COUNT/GIT_CONFIG_KEY_0/GIT_CONFIG_VALUE_0 block, so #2101 is not already superseded. The valid repair remains necessary, but it must be rebuilt semantically on the current protected Security Scan: preserve all current-main changed-scope/checkout/scanner behavior, add only the process-local initial-branch authority and the permanent hostile contract, then reacquire exact-head hosted checks/review. Do not close #2154, force-push, or reuse predecessor GREEN.

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.

security-scan: make exact-head checkout initialize main explicitly

1 participant