Skip to content

fix(security): fail closed on unavailable dependency review - #897

Open
seonghobae wants to merge 1 commit into
mainfrom
fix/dependency-review-fail-closed-current-main-20260809
Open

fix(security): fail closed on unavailable dependency review#897
seonghobae wants to merge 1 commit into
mainfrom
fix/dependency-review-fail-closed-current-main-20260809

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Purpose

Replace the stale, conflicted #799 integration path with a bounded current-main repair for #810. Preserve #799 as historical evidence only; do not import its divergent removal of later Strix work.

Root cause

The central required Security Scan could conclude success when the exact dependency-review comparison returned HTTP 403 or 404. The support probe emitted supported=false, exited zero, and skipped the pinned Dependency Review action. A hard supply-chain evidence boundary had therefore been modeled as an optional capability optimization.

Remedy and TDD identity

  • exact protected base: 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba;
  • RED commit b06bb25c1af99b784730209dceb299cd493734f7 reverses the stale fail-open queue contract;
  • GREEN commit 71947d24828cfb42806f5ef0a8abf83f9279d0af accepts only HTTP 200, preserves curl transport status separately, bounds connect/total time, discards the response body, checks out the explicit PR-head repository/SHA, and emits exact-identity failure evidence;
  • transport-failure regression b527192d7b758fc2f8a95545f25545cec7747c99 proves a partial transfer that prints 200 but exits non-zero cannot pass;
  • exact current head: 59d702f30fa419a016e24c18e87e05c76fbee4a3;
  • read-only permissions and immutable action pins remain unchanged.

Scope correction

Unrelated scheduler-secret and Python-lock-materializer source/test changes that had accumulated on this branch were removed. Flattening an include-bearing requirements lock under a generated filename does not preserve relative include targets and requires a separately designed, test-first path-preservation contract.

The final scope changes only the Dependency Review control plane and its durable architecture, operator, release-note, and workflow-contract evidence. The existing executable mode of scripts/ci/materialize_base_python_requirements.py is preserved; the final mode-only correction introduces no source-content change.

Acceptance contract

Merge only after:

  1. all exact-current-head deterministic, security, dependency, and required workflows are terminal and clean;
  2. Dependency Review reaches the immutably pinned action through a complete exact HTTP-200 comparison whose transport exits zero;
  3. current automated review has no valid unresolved finding;
  4. a qualifying counted non-author formal approval exists; and
  5. repository protection permits normal integration.

After merge, require a protected-main public-repository consumer run proving a non-200 or failed-transfer comparison cannot produce a green Dependency Review gate before closing #810.

Summary by CodeRabbit

  • 개선 사항
    • 의존성 검토가 정확한 기준 커밋과 대상 커밋을 확인한 경우에만 통과하도록 강화되었습니다.
    • 네트워크 오류, 빈 응답, 권한 오류 및 비정상 응답 발생 시 검토를 건너뛰지 않고 실패 처리합니다.
    • 관련 운영 정책, 보안 기준 및 장애 대응 절차가 문서화되었습니다.
    • 검증 실패와 전송 오류를 자동으로 확인하는 회귀 테스트가 추가되었습니다.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6c52c7aa-33d3-4477-8a84-d7cf70105d89

📥 Commits

Reviewing files that changed from the base of the PR and between 3cc65a7 and 07efb4a.

📒 Files selected for processing (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

dependency-review 게이트가 exact base/head 비교의 HTTP 200 증거만 허용하도록 변경되었습니다. 오류, 빈 응답, 부분 전송, 비정상 상태 코드는 실패 처리합니다. PR head checkout, 회귀 계약 테스트, 운영 문서를 갱신했습니다.

Changes

공급망 검증 제어

Layer / File(s) Summary
Exact-head dependency-review 게이트
.github/workflows/security-scan.yml, tests/test_required_workflow_queue_contract.py
PR head 저장소와 정확한 SHA를 checkout합니다. API probe는 응답 본문을 저장하지 않습니다. 전송 코드 0과 HTTP 200을 모두 확인하지 못하면 게이트를 실패시킵니다. 회귀 테스트는 부분 전송과 GITHUB_OUTPUT 미생성을 검증합니다.
Fail-closed 운영 계약 문서
docs/doctoring/dependency-review-fail-closed.md, CHANGELOG.md
fail-closed 정책, 권한 범위, 오류 분류, 수용·롤백 조건과 관련 표준을 문서화합니다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 07efb

The dependency-review gate is changed to fail closed when comparison evidence is unavailable, and no actionable merge-blocking risk remains in the supplied evidence beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant security_scan
  participant GitHubCompareAPI
  participant dependency_review
  PullRequest->>security_scan: PR head repository와 head SHA 전달
  security_scan->>GitHubCompareAPI: 정확한 base...head 비교 요청
  GitHubCompareAPI-->>security_scan: HTTP 상태와 전송 결과 반환
  security_scan->>dependency_review: 전송 코드 0 및 HTTP 200일 때 실행
Loading

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 dependency-review를 사용할 수 없을 때 fail-closed 처리하도록 변경한 주요 내용을 정확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/dependency-review-fail-closed-current-main-20260809

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.

@seonghobae
seonghobae enabled auto-merge (squash) August 9, 2026 12:47

Copy link
Copy Markdown
Contributor Author

/oc Refetch and abort unless exact head is still 71947d24828cfb42806f5ef0a8abf83f9279d0af. There is one blocking source defect in the current GREEN candidate: the dependency-review probe still uses status="$(curl ... || true)". That discards curl's transport exit code. A partial-transfer/body-write/TLS/transport failure can therefore emit HTTP 200 and still reach supported=true, contradicting this PR's own fail-closed contract and the historical regression already observed in predecessor work.

Fix test-first on this existing branch only. Add a permanent regression that models a fake/controlled curl which writes HTTP 200 to stdout but exits nonzero (for example curl exit 18 partial transfer) and proves the support probe fails rather than setting supported=true. Then change the shell to preserve both channels independently: capture curl output/status without || true erasing the exit code, restore set -e, and require both curl_status == 0 and exact HTTP status 200 before emitting supported=true. Any nonzero transport exit, empty/malformed status, or non-200 status must produce only bounded exact repository/base/head/status/transport diagnostics and exit 1. Continue discarding the response body, keep 10s connect/30s total timeouts, exact-head checkout, read-only permissions, immutable dependency-review action pin, and no credential/model/ruleset changes.

Strengthen tests/test_required_workflow_queue_contract.py or a focused companion to reject the literal || true support-probe pattern and require the captured transport-status branch. Run the focused fail-closed contract, complete central suite, compilation, git diff --check, Strix quick gate, then exact-head security/supply-chain gates. Do not mark this head accepted from the current queued checks; they are stale as soon as this repair lands.

Copy link
Copy Markdown
Contributor Author

Exact-head RCA and proof for 8fc17de86d1d22c9c11946dd7f70ff934c0b553a:

  • First failing boundary on predecessor 71947d24828cfb42806f5ef0a8abf83f9279d0af: the support probe used command substitution with || true, which erased curl's transport exit. A partial transfer could emit HTTP 200, exit nonzero, and still reach supported=true.
  • Technical root cause: HTTP response status and transport integrity were collapsed into one string channel. Systemic control: the permanent executable regression now supplies a controlled curl that prints 200 and exits 18, and requires fail-closed behavior with no GitHub output.
  • Remedy: capture the curl transport exit separately under a bounded set +e region, immediately restore set -e, normalize the body-free HTTP status, and require transport exit 0 plus exact HTTP 200. Diagnostics remain bounded to repository/base/head, normalized HTTP status, and numeric transport exit.
  • Preserved boundaries: discarded response body, 10-second connect/30-second total timeouts, exact-head checkout, read-only permissions, immutable dependency-review pin, and no credential/model/ruleset changes.
  • RED: focused contract failed 2 tests, including the executable HTTP-200/exit-18 counterexample.
  • GREEN: focused 2 passed; complete central suite 978 passed + 16 subtests; compile/diff checks clean; Strix self-test PASS.

Hosted exact-head security and supply-chain results remain authoritative.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Evaluate exact current head 8fc17de86d1d22c9c11946dd7f70ff934c0b553a against independently resolved live main 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba. Keep source revision, current-base compatibility, deterministic checks, model judgment, and qualifying independent human approval as separate evidence channels; do not infer merge authority.

Copy link
Copy Markdown
Contributor Author

Follow-up at current head 59505c1d: declared optional PR_REVIEW_MERGE_TOKEN and OPENCODE_APPROVE_TOKEN under workflow_call.secrets in both reusable review schedulers, added the permanent contract test and fail-closed operations note. This enables callers to pass only the two required review credentials instead of secrets: inherit. Evidence: actionlint passed; focused contract suite 52 passed. The full suite reached 974 passed with 5 pre-existing platform-gated trusted-uv tests failing on this macOS arm64 workstation before the archive-verification assertions; no unrelated source was changed. No self/Admin/bypass approval or merge was used.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Review exact current head 59505c1d89eb7ea816e921b6da38079c736608c2 against independently resolved live main 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba. Nine exact-head hosted workflows are terminal-success and no review thread is unresolved. Verify dependency-review unavailable, skipped, neutral, and absent evidence fail closed without manufacturing a dependency finding, while successful exact-head evidence remains distinct from semantic review and merge authority. Automated judgment is not qualifying independent human approval or merge authorization.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review
@opencode-agent review
@cwl-noema-review review

Review exact current head 59505c1d89eb7ea816e921b6da38079c736608c2 only. All nine exact-head quality, security, and supply-chain workflows are terminal-success. Validate that dependency-review capability accepts only a transport-successful HTTP 200 for the exact base/head comparison, with 10-second connect and 30-second total bounds, response body discarded, literal PR-head repository/SHA checkout, read-only permissions, and no substitute security gate. Review only; do not mutate, merge, or alter protections.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

@seonghobae I will review PR #897 at exact head 59505c1d89eb7ea816e921b6da38079c736608c2 only.

I will verify the dependency-review fail-closed boundary and the listed workflow invariants. I will keep exact-head check evidence separate from review judgment, approval, and merge authority. I will not modify code, merge, or change protections.

I used the repository guidance that only successful checks for the exact current head are valid merge evidence.


🧠 Learnings used
Learnt from: seonghobae
Repo: ContextualWisdomLab/.github PR: 0
File: :0-0
Timestamp: 2026-08-05T13:44:10.007Z
Learning: For PR `#782`, only successful checks associated with the exact current head are valid merge evidence. Do not treat queued, in-progress, cancelled, predecessor-head, temporary-workflow, or administrative-bypass results as passing evidence. Before a formal approval, verify that the direct security and supply-chain workflows, the permanent hourly NVIDIA NIM contract, current-head reviews, unresolved-thread checks, and an independent approval have completed successfully.

Learnt from: CR
Repo: ContextualWisdomLab/.github PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-07-29T06:47:25.581Z
Learning: Applies to opencode.jsonc : All reviewer agents in `opencode.jsonc` must keep `"edit": "deny"`; reviewers must never implement changes.
⚠️ 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

Exact-current-head review request for 59505c1d89eb7ea816e921b6da38079c736608c2 over protected main@6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba.

Review the bounded six-file supply-chain evidence repair: dependency-review support accepts only HTTP 200; non-200, timeout, or unavailable comparison fails closed with exact identity and operator guidance; response bodies are discarded; checkout is bound to the explicit PR head repository/SHA; and read-only permissions plus immutable action pins remain. Strix Changed Path Quality CI, CodeQL PR, Python Security, Security Scan, SAST Semgrep, Secret Scan, OSV-Scanner PR, Scorecard PR, and SBOM Generation are terminal-success on this exact head. No review thread exists.

Keep the exact head unchanged. Do not update the branch, synthesize author approval, substitute another scanner for dependency-review evidence, add credentials, merge, release, or bypass protection.

@coderabbitai review
@opencode-agent review
@cwl-noema-review review
@strix review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@seonghobae have exceeded the limit for the number of chat messages per hour. Please wait 4 minutes and 33 seconds before sending another message.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Re-evaluate exact current head 3af29c40796490ced463a9a6de7c4495a4ae97c8. 리뷰 확인 for the bounded-include increment; do not treat Checks wait as a blocker.

Copy link
Copy Markdown
Contributor Author

@opencode-agent

Please perform a fresh exact-head semantic review of 3af29c40796490ced463a9a6de7c4495a4ae97c8, keeping source findings separate from merge-readiness evidence. Do not infer approval from wrapper checks; submit a formal review only if the current head is defect-free under the protected control-plane contract.

Copy link
Copy Markdown
Contributor Author

@cwl-noema-review

Please provide an independent exact-head review of 3af29c40796490ced463a9a6de7c4495a4ae97c8. Confirm that unavailable or skipped dependency-review evidence cannot satisfy the required security contract, and submit a formal review verdict rather than a status-only acknowledgement.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact head 3af29c40796490ced463a9a6de7c4495a4ae97c8, focusing on whether every unavailable, skipped, neutral, or metadata-incomplete dependency-review path fails closed and cannot satisfy the required security contract.

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@seonghobae have exceeded the limit for the number of chat messages per hour. Please wait 50 minutes and 4 seconds before sending another message.

@seonghobae
seonghobae marked this pull request as draft August 14, 2026 08:45
auto-merge was automatically disabled August 14, 2026 08:45

Pull request was converted to draft

Copy link
Copy Markdown
Contributor Author

Returned to Draft because this branch overlaps the authoritative prerequisite #821 and no longer matches its own four-file bounded-scope claim.

#821 already owns the fail-closed dependency-review boundary and exact-head focused quality gate. This branch contains a useful incremental refinement—capturing the curl exit status independently while discarding the response body—but its current eleven-file diff also duplicates the security workflow, materializer/governance changes, and scheduler-token changes outside that refinement.

After #821 reaches protected main, rebuild this as a narrow follow-up retaining only the independently justified transport-status refinement, its focused regression proving a numeric HTTP 200 plus non-zero curl exit still fails closed, and bounded doctoring/changelog evidence. Remove duplicated prerequisite and unrelated scheduler/materializer changes, then reacquire exact-head checks and independent review.

@seonghobae
seonghobae marked this pull request as ready for review August 14, 2026 09:00
@seonghobae
seonghobae enabled auto-merge (squash) August 14, 2026 09:00

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact head 94f799f7e0701e1a317bbe407759988cbad915c4. The branch is now narrowed to the dependency-review fail-closed control plane; unrelated scheduler-secret and incomplete requirements-include materializer changes were removed. Verify exact-head checkout, curl transport/HTTP-200 binding, body discard, timeout bounds, and the permanent fail-closed contract.

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@seonghobae have exceeded the limit for the number of chat messages per hour. Please wait 16 minutes and 31 seconds before sending another message.

Copy link
Copy Markdown
Contributor Author

@opencode-agent

Please perform a fresh exact-head semantic review of 94f799f7e0701e1a317bbe407759988cbad915c4. Confirm that only a complete HTTP-200 exact base/head comparison can reach the pinned dependency-review action, every transport/non-200/malformed outcome fails closed without response-body disclosure, and the scope cleanup removed unrelated changes. Submit a formal current-head verdict.

Copy link
Copy Markdown
Contributor Author

@cwl-noema-review

After a qualifying exact-head OpenCode verdict, independently review 94f799f7e0701e1a317bbe407759988cbad915c4. Confirm unavailable dependency evidence cannot be converted into a passing security contract and that no complementary scanner is treated as a semantic substitute.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review exact head 3cc65a7b24371ee453875d9efe06e82ff06477b7 and submit a formal current-head verdict.

@seonghobae
seonghobae enabled auto-merge (squash) August 16, 2026 09:57
@opencode-agent
opencode-agent Bot disabled auto-merge August 16, 2026 09:59
Replay unique #897 source onto current origin/main. Skip shared
ARCHITECTURE/CLAUDE trees. Treat non-200 or failed transport as
unavailable evidence rather than a clean skip.
@seonghobae
seonghobae force-pushed the fix/dependency-review-fail-closed-current-main-20260809 branch from 59d702f to 07efb4a Compare August 16, 2026 15:19
@cursor

cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@seonghobae
seonghobae enabled auto-merge (squash) August 16, 2026 15:19

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict

REQUEST_CHANGES on exact head 07efb4a1978c10c8243becf2627ad72df982e229.

The fail-closed transport and HTTP-200 contract is source-correct: curl exit is preserved, || true is gone, bodies are discarded, checkout is exact-head, and permissions stay read-only. That is not enough to merge this head against #810.

Blocking gap

Issue #810 acceptance requires the probe to record repository visibility with the exact base/head and status, and not to infer a root cause from HTTP 403/404. This head omits visibility. The pinned action is also still gated on supported == 'true', so a later skipped support step can green the job without running dependency review.

What to do next

Land the successor that records allowlisted visibility, executes 403/404/empty/malformed regressions, and runs the pinned action unconditionally after a successful probe. Prefer that branch for integration. Keep #821 draft until its remaining process-group work is rebased without duplicating this probe.

Stale OpenCode CHANGES_REQUESTED on 59d702f is not current-head evidence. Hosted checks on 07efb4a were still queued at this review and are not acceptance. Automated review is not qualifying non-author approval or merge authority.

Do not close #810 until a protected-main public consumer run proves a non-200 or failed-transfer comparison cannot produce a green Dependency Review gate.

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

echo "supported=false" >>"$GITHUB_OUTPUT"
exit 0
if [ "$curl_status" -ne 0 ] || [ "$http_status" != "200" ]; then
echo "::error::Dependency review evidence unavailable for ${REPOSITORY} at exact base ${BASE_SHA} and head ${HEAD_SHA}: HTTP ${http_status}; curl exit ${curl_status}. Verify dependency-graph/security configuration and GitHub service behavior, then rerun. Failing closed."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

#810 requires the probe to record repository visibility with the exact base/head and status, without guessing a 403 root cause. This line logs repo and SHAs only. Allowlist public|private|internal from github.event.repository.visibility and emit unknown for any other value in this diagnostic.

exit 1
echo "supported=true" >>"$GITHUB_OUTPUT"
- name: Dependency review
if: steps.dependency_review_support.outputs.supported == 'true'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If this support step is later skipped, supported stays empty, this if skips the pinned action, and the job can still succeed. After a successful probe the action should run unconditionally so unavailable evidence cannot become a green skip.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict

COMMENT on exact head 07efb4a1978c10c8243becf2627ad72df982e229.

The earlier REQUEST_CHANGES still stands: this head leaves the pinned action independently skippable and does not record allowlisted visibility. Prefer #1045 for integration. Do not merge #897, #1033, #1041, or #1042. Keep #810 open until a protected-main public consumer run proves a non-200 cannot go green.

View PR

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

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