fix(release): harden workflow against supply chain attacks

코드 리뷰에서 발견된 4건의 워크플로우 보안 이슈를 함께 해결:

- 빌드와 attest+release를 별도 job으로 분리. id-token: write가
  npm install이 실행되는 job과 분리돼 postinstall 스크립트가
  Sigstore OIDC token을 발급받을 수 없음
- npm install → npm ci --ignore-scripts
  · ci: lockfile 외 패키지 변동 차단 (provenance와 lock 정합성 유지)
  · --ignore-scripts: 모든 postinstall 훅 차단
- checkout step에 persist-credentials: false 추가.
  npm 단계가 .git/config의 GITHUB_TOKEN을 사용 못 함
- actions/attest-build-provenance를 mutable @v2 → SHA pin
  (e8998f9, v2.4.0). 업스트림 tag 재포인팅 공격 차단
- subject-path에 manifest.json 추가. 다운로드 사용자가
  gh attestation verify로 manifest까지 검증 가능
This commit is contained in:
uppinote 2026-05-28 07:46:20 +09:00
parent 9e99cf043d
commit bf5feec8a4

View file

@ -10,18 +10,21 @@ on:
# bogus published releases under the sync-tag name.
- "[0-9]*"
# Split into two jobs so that npm install (which can run third-party
# postinstall scripts) never executes in the same job as the OIDC
# `id-token: write` permission. Build deps cannot exfiltrate the
# attestation signing identity.
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
# Required by actions/attest-build-provenance to mint a signing
# certificate from Sigstore and publish the attestation to GitHub's
# attestation store.
id-token: write
attestations: write
contents: read
steps:
- uses: actions/checkout@v6
with:
# Don't leave GITHUB_TOKEN in .git/config where postinstall
# scripts could pick it up.
persist-credentials: false
- name: Use Node.js
uses: actions/setup-node@v6
@ -29,16 +32,51 @@ jobs:
node-version: "20.x"
- name: Build plugin
# --ignore-scripts blocks postinstall lifecycle hooks across the
# whole dep tree. esbuild and our other deps do not require them.
# npm ci honors the lockfile exactly (no silent drift).
run: |
npm install
npm ci --ignore-scripts
npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: plugin-build
path: |
main.js
styles.css
retention-days: 1
if-no-files-found: error
release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
# Sigstore OIDC + attestation publishing. Scoped to this job only,
# which runs no npm install and no third-party code beyond the
# pinned attest action.
id-token: write
attestations: write
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: plugin-build
- name: Attest build provenance
uses: actions/attest-build-provenance@v2
# SHA-pinned (v2.4.0). When bumping, update both SHA and comment.
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be
with:
subject-path: |
main.js
styles.css
manifest.json
- name: Create or update release
env: