Skip to content

Harden Scorecard artifact extraction#200

Merged
seonghobae merged 6 commits into
developfrom
fix/download-artifact-buffer-warning
May 1, 2026
Merged

Harden Scorecard artifact extraction#200
seonghobae merged 6 commits into
developfrom
fix/download-artifact-buffer-warning

Conversation

@seonghobae
Copy link
Copy Markdown
Owner

Summary

  • Avoid the actions/download-artifact legacy ZIP decompression path for OSSF Scorecard SARIF by downloading the artifact archive with skip-decompress: true.
  • Add a repo-owned safe extractor for results.sarif and supply-chain guards that reject missing extraction, comment spoofing, and echo/non-executing command spoofing.
  • Add regression tests for malformed ZIP members, traversal, symlink-like entries, missing SARIF, and workflow guard bypasses.

Verification

  • uv run --project services/analysis-engine ruff check services/analysis-engine/tests/test_supply_chain_policy.py scripts/checks/verify_supply_chain.py scripts/checks/extract_scorecard_artifact.py
  • uv run --project services/analysis-engine pytest services/analysis-engine/tests/test_supply_chain_policy.py -q
  • python3 scripts/checks/verify_supply_chain.py
  • python3 scripts/checks/security_gates.py
  • python3 /Users/seonghobae/.agents/skills/skill-creator/scripts/quick_validate.py skills/ci-warning-root-cause-remediation
  • git diff --check

Security Notes

  • Treats the downloaded Scorecard artifact archive as untrusted input and fails closed unless it contains exactly one results.sarif member.
  • Rejects traversal, absolute/non-matching member names, directories, and Unix symlink-like ZIP entries; writes bytes directly instead of using generic archive extraction.
  • Preserves SHA-pinned Actions and CodeQL SARIF upload controls while avoiding the action-owned decompression path that emits the Buffer deprecation warning.

Closes #199.
Refs #194.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

릴리스 노트

  • Chores

    • GitHub Actions 워크플로우의 OSSF Scorecard 아티팩트 처리 안전성 강화 및 검증 프로세스 개선
  • Documentation

    • CI 경고 근본 원인 분석 및 체계적 수정 방법론 가이드 추가
  • Tests

    • 공급망 정책 검증 및 아티팩트 추출 기능에 대한 포괄적 테스트 커버리지 확대

Walkthrough

OSSF Scorecard SARIF 아티팩트를 skip-decompress: true로 다운로드하고, 저장소 소유의 안전한 추출기(extract_scorecard_artifact.py)로 단일 results.sarif만 엄격히 검증·추출하도록 워크플로우, 검증 로직 및 테스트를 추가·확장함.

Changes

Cohort / File(s) Summary
워크플로우 구성
\.github/workflows/ossf-scorecard.yml
actions/download-artifactskip-decompress: true 적용 후, 저장소 추출기 실행으로 압축 해제 책임 이동.
안전한 추출 유틸리티
scripts/checks/extract_scorecard_artifact.py
새 CLI 스크립트 추가: 입력(파일 또는 디렉터리) 해석, ZIP 멤버 검증(단일 results.sarif만 허용, 절대경로/경로순회/디렉터리/심볼릭 유사 항목 차단, 크기 제한), 출력 경로의 심볼릭 링크 방지 및 안전한 파일 생성(O_EXCL/O_NOFOLLOW 등).
공급망 검증 스크립트
scripts/checks/verify_supply_chain.py
워크플로우 단계 파서(workflow_step_blocks, workflow_job_content_for_step, step_run_command_from_block) 추가 및 scorecard_artifact_download_decompression_violations 검사 도입: skip-decompress 누락, 저장소 추출기 호출 부재/순서 오류(정규화 이전 호출 필요) 검증.
테스트 커버리지
services/analysis-engine/tests/test_supply_chain_policy.py
추출기 및 워크플로우 정책에 대한 광범위한 단위테스트 추가(정상 케이스 및 심볼릭 경로, 경로순회, 심볼릭 메타, 누락/중복/초과 크기 등 실패 케이스 포함).
문서화(수정 방안 스킬)
skills/ci-warning-root-cause-remediation/SKILL.md
CI 경고 원인 분석 및 수리 흐름 문서 추가(증거 수집, 소유권 분류, 수정 전략, 에이전트/보안 결함 처리 등).

Sequence Diagram(s)

sequenceDiagram
    participant WF as "Workflow (GitHub Actions)"
    participant DL as "actions/download-artifact\n(skip-decompress: true)"
    participant EX as "extract_scorecard_artifact.py"
    participant NORM as "normalize_scorecard_sarif.py"
    participant UP as "actions/upload-sarif-results"

    WF->>DL: 요청: ossf-scorecard-results (skip-decompress: true)
    DL-->>WF: `scorecard-artifact` (zip 파일)
    WF->>EX: 실행: extractor(scorecard-artifact → scorecard-sarif)
    EX->>EX: ZIP 검증\n(단일 `results.sarif`, 절대경로/경로순회/심볼릭 차단, 크기 제한)
    EX-->>WF: `scorecard-sarif/results.sarif`
    WF->>NORM: normalize_scorecard_sarif.py 처리
    NORM-->>WF: normalized `results.sarif`
    WF->>UP: 업로드 SARIF
    UP-->>WF: 업로드 완료
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰
ZIP 속 숨결 하나만 살피네,
탈출길은 닫고 안전문만 열네.
한 장의 results.sarif를 꺼내어,
검증 끝나면 당당히 깡총깡총!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 주요 변경 사항을 명확하게 요약합니다: Scorecard 아티팩트 추출 강화(보안 개선).
Description check ✅ Passed 설명이 변경 사항과 관련이 있으며 요약, 검증 단계, 보안 노트를 포함합니다.
Linked Issues check ✅ Passed PR이 연결된 이슈 #199의 수용 기준을 충족합니다: skip-decompress 사용, repo-owned 안전 추출기, traversal/symlink 거부, supply-chain 검증 추가.
Out of Scope Changes check ✅ Passed 모든 변경 사항이 이슈 #199와 #194 범위 내입니다: workflow 수정, 추출기 추가, 검증 로직 추가, 테스트 추가, 문서화.
Docstring Coverage ✅ Passed Docstring coverage is 88.24% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/download-artifact-buffer-warning

Review rate limit: 4/5 reviews remaining, refill in 12 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/checks/extract_scorecard_artifact.py`:
- Around line 51-53: The code currently calls output_dir.mkdir(...) and
target.write_bytes(...), which can follow repository symlinks and overwrite
arbitrary files; change it to refuse symlinked paths and create the target
atomically and only if it does not already exist: verify each component of
output_dir is not a symlink (use os.lstat on each ancestor and on output_dir)
before creating directories, and when writing EXPECTED_MEMBER use low-level
os.open with flags O_CREAT|O_EXCL|O_WRONLY (and O_NOFOLLOW where available) to
get a fresh file descriptor, then write archive.read(member) to that FD and
close it (instead of target.write_bytes), raising on existence or symlink to
avoid following links. Ensure you reference output_dir, target and
EXPECTED_MEMBER in the changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c1bf2b40-a702-4214-a1f0-ad91387a365a

📥 Commits

Reviewing files that changed from the base of the PR and between e47e684 and 05818c8.

📒 Files selected for processing (5)
  • .github/workflows/ossf-scorecard.yml
  • scripts/checks/extract_scorecard_artifact.py
  • scripts/checks/verify_supply_chain.py
  • services/analysis-engine/tests/test_supply_chain_policy.py
  • skills/ci-warning-root-cause-remediation/SKILL.md

Comment thread scripts/checks/extract_scorecard_artifact.py Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/checks/extract_scorecard_artifact.py`:
- Around line 14-25: resolve_artifact_zip trusts source and discovered .zip
candidates without symlink checks; call the existing ensure_non_symlink_path
validation for the input path and for each candidate before accepting them.
Specifically, when source is a file, run ensure_non_symlink_path(source) before
returning; when source is a directory, filter/validate candidate paths by
calling ensure_non_symlink_path(candidate) (or skip if it raises) so you only
accept a single non-symlink .zip; raise the same ValueError if no valid
non-symlink candidate remains.

In `@services/analysis-engine/tests/test_supply_chain_policy.py`:
- Around line 1205-1218: The test only covers passing a zip file path directly
to extract_scorecard_artifact and misses the real-world directory-input branch
in resolve_artifact_zip; add three cases in
test_scorecard_artifact_extractor_extracts_expected_sarif: (1) a directory input
that contains exactly one results.sarif.zip (or a single .zip) and assert
extraction succeeds and content matches, (2) a directory containing zero zip
files and assert the function raises the expected error/returns failure, and (3)
a directory containing two zip files and assert the “exactly one zip allowed”
guard triggers the expected exception/failure; reference the
extract_scorecard_artifact helper and resolve_artifact_zip behavior so the new
assertions exercise both the directory-resolution path and the multi-zip
rejection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: dac29018-ffa1-43c6-b935-ba84bc7fe3a0

📥 Commits

Reviewing files that changed from the base of the PR and between 05818c8 and f2d4f10.

📒 Files selected for processing (2)
  • scripts/checks/extract_scorecard_artifact.py
  • services/analysis-engine/tests/test_supply_chain_policy.py

Comment thread scripts/checks/extract_scorecard_artifact.py
Comment thread services/analysis-engine/tests/test_supply_chain_policy.py
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/checks/extract_scorecard_artifact.py`:
- Around line 61-69: The code currently calls archive.read(member) which loads
the entire uncompressed member into memory; change the extraction to stream via
archive.open(member) and read/write in fixed-size chunks (e.g., 64KB) to write
to write_new_file_without_following_symlinks so memory stays bounded, and while
streaming enforce a maximum uncompressed size per-member and optionally a total
extraction cap (track bytes read and raise an error if it exceeds the limit).
Also update validate_member (or the extraction flow that calls it) to check the
ZipInfo.uncompressed_size when available and reject members that advertise sizes
above the allowed threshold before streaming starts; keep existing path/symlink
checks. Use the ZipFile.open(...) file-like object, loop reading chunks and
increment a counter, and raise a specific exception on size overrun instead of
using archive.read(member).

In `@services/analysis-engine/tests/test_supply_chain_policy.py`:
- Around line 1036-1393: The file fails ruff formatting checks; run the
formatter and commit the changes to satisfy `ruff format --check`. Reformat this
test module (functions such as
test_supply_chain_check_requires_scorecard_download_without_action_decompression,
test_supply_chain_check_rejects_commented_scorecard_decompression_tokens,
test_scorecard_artifact_extractor_extracts_expected_sarif, etc.) by running
`ruff format services/analysis-engine/tests/test_supply_chain_policy.py` (or
`ruff format .` for the repo), review the updated whitespace/line-wrapping
changes, and add/commit the modified file so CI passes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 087263b7-e204-4c88-aeed-cc1a60addbe7

📥 Commits

Reviewing files that changed from the base of the PR and between f2d4f10 and 97e7e58.

📒 Files selected for processing (2)
  • scripts/checks/extract_scorecard_artifact.py
  • services/analysis-engine/tests/test_supply_chain_policy.py

Comment thread scripts/checks/extract_scorecard_artifact.py Outdated
Comment thread services/analysis-engine/tests/test_supply_chain_policy.py
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/checks/verify_supply_chain.py (1)

459-486: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

스텝 블록 파싱 로직을 공용 헬퍼로 단일화하세요.

현재 동일 파싱 로직이 두 함수에 복제되어 있어, 우회 케이스 보완 시 한쪽만 수정되는 드리프트 리스크가 큽니다. 보안 정책 경로이므로 공용 함수로 통합하는 편이 안전합니다.

Also applies to: 550-577

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/checks/verify_supply_chain.py` around lines 459 - 486, The step block
parsing loop (building step_blocks via step_indent, has_steps_parent, step_lines
and appending (index, step_indent, step_lines)) is duplicated; extract it into a
single helper function (e.g., parse_step_blocks or extract_step_blocks) that
takes lines: list[str] and returns list[tuple[int,int,list[str]]], move the
logic from both locations (the shown block and the one around lines 550-577)
into that helper, and replace both original inline loops with calls to the new
helper to ensure a single source of truth for parsing.
♻️ Duplicate comments (1)
scripts/checks/extract_scorecard_artifact.py (1)

87-87: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

비신뢰 ZIP 멤버를 한 번에 읽어 메모리 고갈을 유발할 수 있습니다.

Line 87의 archive.read(member)는 압축 해제 결과를 통째로 메모리에 올립니다. 비신뢰 아티팩트 입력에서는 스트리밍 복사 + 최대 허용 크기 검증으로 fail-closed 해야 합니다.

🔧 제안 수정
@@
 EXPECTED_MEMBER = "results.sarif"
+MAX_SARIF_BYTES = 10 * 1024 * 1024  # 10 MiB

@@
-def write_new_file_without_following_symlinks(target: Path, data: bytes) -> None:
-    """Write ``data`` to a new file without following an existing symlink."""
+def write_new_file_without_following_symlinks(target: Path, source_file: zipfile.ZipExtFile) -> None:
+    """Stream-write to a new file without following an existing symlink."""
@@
-    with os.fdopen(fd, "wb") as target_file:
-        target_file.write(data)
+    written = 0
+    with os.fdopen(fd, "wb") as target_file:
+        while True:
+            chunk = source_file.read(64 * 1024)
+            if not chunk:
+                break
+            written += len(chunk)
+            if written > MAX_SARIF_BYTES:
+                raise ValueError("artifact member too large")
+            target_file.write(chunk)

@@
-        write_new_file_without_following_symlinks(target, archive.read(member))
+        if member.file_size > MAX_SARIF_BYTES:
+            raise ValueError("artifact member too large")
+        with archive.open(member) as source_file:
+            write_new_file_without_following_symlinks(target, source_file)
         return target
#!/bin/bash
# Verify current implementation still performs full in-memory ZIP reads
rg -n "archive\.read\(member\)|def write_new_file_without_following_symlinks|MAX_SARIF_BYTES|file_size" \
  scripts/checks/extract_scorecard_artifact.py -C2

# Verify regression tests for oversized ZIP member are present/absent
rg -n "too large|MAX_SARIF_BYTES|zip bomb|artifact member" \
  services/analysis-engine/tests/test_supply_chain_policy.py -C2

As per coding guidelines, "Treat files, URLs, metadata, model artifacts, and project files as untrusted input".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/checks/extract_scorecard_artifact.py` at line 87, The code currently
calls archive.read(member) which loads a ZIP member fully into memory; change
this to stream the member via archive.open(member) or .extractfile and write to
disk in fixed-size chunks while tracking cumulative bytes against a configured
MAX_SARIF_BYTES limit and aborting (fail-closed) if exceeded; update the caller
path that invokes write_new_file_without_following_symlinks to accept a
file-like stream or first stream-validate+save to a temp file before calling
write_new_file_without_following_symlinks, and ensure you close the archive
stream on errors and log/raise a clear exception when the size limit is hit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@scripts/checks/verify_supply_chain.py`:
- Around line 459-486: The step block parsing loop (building step_blocks via
step_indent, has_steps_parent, step_lines and appending (index, step_indent,
step_lines)) is duplicated; extract it into a single helper function (e.g.,
parse_step_blocks or extract_step_blocks) that takes lines: list[str] and
returns list[tuple[int,int,list[str]]], move the logic from both locations (the
shown block and the one around lines 550-577) into that helper, and replace both
original inline loops with calls to the new helper to ensure a single source of
truth for parsing.

---

Duplicate comments:
In `@scripts/checks/extract_scorecard_artifact.py`:
- Line 87: The code currently calls archive.read(member) which loads a ZIP
member fully into memory; change this to stream the member via
archive.open(member) or .extractfile and write to disk in fixed-size chunks
while tracking cumulative bytes against a configured MAX_SARIF_BYTES limit and
aborting (fail-closed) if exceeded; update the caller path that invokes
write_new_file_without_following_symlinks to accept a file-like stream or first
stream-validate+save to a temp file before calling
write_new_file_without_following_symlinks, and ensure you close the archive
stream on errors and log/raise a clear exception when the size limit is hit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 05b5914f-4b8d-46b8-b34c-b0509708b5af

📥 Commits

Reviewing files that changed from the base of the PR and between 97e7e58 and c0a9eec.

📒 Files selected for processing (3)
  • scripts/checks/extract_scorecard_artifact.py
  • scripts/checks/verify_supply_chain.py
  • services/analysis-engine/tests/test_supply_chain_policy.py

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/checks/verify_supply_chain.py`:
- Around line 560-601: Duplicate logic exists in workflow_job_content and
step_run_command and is also copied into
scorecard_sarif_upload_normalization_violations; extract the shared behavior
into two module-level helpers (e.g., workflow_job_content_for_step(lines:
list[str], line_index: int) -> str and step_run_command_from_block(step_lines:
list[str], step_indent: int) -> str) implementing the same logic currently in
workflow_job_content and step_run_command, then replace the bodies of
workflow_job_content and step_run_command to call these helpers and update
scorecard_sarif_upload_normalization_violations to use them as well; keep the
same parameter names and return types, preserve comment-stripping, indent checks
and return values, and run existing tests or add a small unit test ensuring
identical outputs before/after refactor.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 284c26cd-ca38-4ab6-940e-bba10d54fe0a

📥 Commits

Reviewing files that changed from the base of the PR and between c0a9eec and 3732216.

📒 Files selected for processing (3)
  • scripts/checks/extract_scorecard_artifact.py
  • scripts/checks/verify_supply_chain.py
  • services/analysis-engine/tests/test_supply_chain_policy.py

Comment thread scripts/checks/verify_supply_chain.py Outdated
@seonghobae seonghobae enabled auto-merge (squash) May 1, 2026 15:24
@seonghobae
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

✅ Actions performed

Review triggered.

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/checks/extract_scorecard_artifact.py`:
- Around line 25-35: The candidate selection currently only checks suffix and
symlinks via ensure_non_symlink_path but can still accept directories or special
files like "results.zip/" or device nodes; update the selection to require a
regular file: when iterating candidates from source.iterdir() (the variable
candidate/path in this block), after calling ensure_non_symlink_path(path,
path_kind="artifact path") also verify path.is_file() (or equivalent S_ISREG
check) and skip/ignore non-regular entries so only true regular .zip files are
appended to candidates before the len(candidates) check and subsequent call to
zipfile.ZipFile().

In `@scripts/checks/verify_supply_chain.py`:
- Around line 129-136: The loop that searches for a parent "steps:" wrongly
breaks on a blank line and thus can miss a "steps:" ancestor; update the search
in verify_supply_chain.py to skip empty or comment-only lines instead of
breaking: inside the loop that uses
previous_line/previous_stripped/previous_indent/step_indent, add a check like
"if previous_stripped == '': continue" (or treat comment-only lines as empty)
before the existing indent/steps checks so the loop only breaks once a
non-empty, less-indented line is found; this will fix how
scorecard_sarif_upload_normalization_violations() and
scorecard_artifact_download_decompression_violations() detect step blocks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 51535d55-c8e9-4d6c-a926-1e71cad9e163

📥 Commits

Reviewing files that changed from the base of the PR and between c0a9eec and 5da2b24.

📒 Files selected for processing (3)
  • scripts/checks/extract_scorecard_artifact.py
  • scripts/checks/verify_supply_chain.py
  • services/analysis-engine/tests/test_supply_chain_policy.py

Comment thread scripts/checks/extract_scorecard_artifact.py
Comment thread scripts/checks/verify_supply_chain.py
@seonghobae
Copy link
Copy Markdown
Owner Author

@coderabbitai resolve

@seonghobae seonghobae merged commit 18a6c31 into develop May 1, 2026
28 of 29 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

✅ Actions performed

Comments resolved and changes approved.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] Remove actions/download-artifact Buffer deprecation warning

1 participant