サプライチェーン セキュリティ
SSoT: 本書は Parky のサプライチェーン (依存 / build / artifact / 配信) に対する セキュリティ多層防御の SSoT。SLSA Level 3 達成を目標に、SBOM / provenance attestation / dependency review / secret scanning の 4 層で守る。
関連: incident-response.html(CVE 緊急対応)/ github-environments.html(required reviewer / protected secret)/ deployment-rollback.html(攻撃検知後のロールバック)。
採用している層 (4 層 + α)
| 層 | ツール | 対象 | 状態 | workflow |
|---|---|---|---|---|
| 1. SBOM 生成 | CycloneDX (@cyclonedx/cyclonedx-npm) |
api / web/packages / portal-{admin,owner,marketing} / web-home | 運用中 | sbom.yml |
| 2. SLSA Provenance | actions/attest-build-provenance + Sigstore (Fulcio + Rekor) |
api/dist/**/*.js (Worker bundle) |
運用中 (loose pin) | provenance-attest.yml + 各 deploy-api-*.yml |
| 3. Dependency Review | actions/dependency-review-action |
全 PR の package-lock.json 差分 | 運用中 | dependency-review.yml |
| 4. Secret Scanning | GitHub Push Protection + (将来) TruffleHog | 全 commit / push | Push Protection のみ | TODO: trufflehog.yml 追加予定 |
| +α. Dependabot | GitHub Native | npm / GitHub Actions / Dart | 運用中 | dependabot.yml |
+α. npm audit |
npm CLI | local + CI (api-ci.yml) |
運用中 | ― |
| +α. CodeQL | GitHub Native | JS/TS | 未導入 | follow-up |
SLSA Level 達成度(自己評価)
SLSA = Supply-chain Levels for Software Artifacts。公式 v1.0 Levels の Build track を基準に、Parky の達成度を Worker bundle (
api/dist/) について評価する。
| Level | 要件 | Parky の状態 | 判定 |
|---|---|---|---|
| L1 | Provenance が存在する (中身は信用しなくてよい) | build は GitHub Actions で完結し、commit SHA + workflow run 単位で artifact が紐づく | 達成 |
| L2 | Provenance が build platform 側で署名される | actions/attest-build-provenance が GitHub OIDC + Sigstore Fulcio で署名済 |
達成 |
| L3 | Provenance が build platform 側で 非偽造可能に署名される (developer 側から偽造不可) | Sigstore Rekor transparency log に記録 + Fulcio が GitHub OIDC token 経由で X.509 証明書を発行。 developer 個人の credential では署名不可。 build runner は GitHub-hosted ubuntu-22.04 (self-hosted runner 不使用) で OS / toolchain が GitHub による管理下にある。 | 達成 (Worker bundle) |
| L4(草案) | Source 監査 + Hermetic build + 2 人 review 必須 | main branch protection は dev/stg → main フローで検討中。hermetic は npm registry 依存のため未達。 | 対象外 (1 人開発期) |
結論: Worker bundle (api/dist/) について SLSA L3 達成。
Pages 配信 artifact (portal-*, web-home) は CF 側 build のため L0〜L1
相当に留まる (詳細は §既知の限界)。
検証手順 (consumer 側)
GitHub CLI で attestation を verify (推奨)
Worker bundle が「正しい repo + commit + workflow から作られたか」を検証する。CI 内で生成された attestation を直接 GitHub から引いてくるので、ローカルに artifact があれば即実行可能。
# 1. deploy 済 worker bundle を取得 (例: dev)
gh run download --name api-dist-dev-<sha> -D /tmp/parky-dist
# 2. attestation verify (issuer / repo / commit を check)
gh attestation verify /tmp/parky-dist/index.js \
--owner high-field \
--repo high-field/parky
# 期待出力 (抜粋):
# ✓ Verification succeeded!
# - subject: /tmp/parky-dist/index.js
# - workflow: https://github.com/high-field/parky/.github/workflows/deploy-api-prod.yml@refs/heads/main
# - signer: https://token.actions.githubusercontent.com
# - cert issuer: https://fulcio.sigstore.dev
cosign で Sigstore transparency log を直接 verify
gh attestation verify が GitHub Native API 経由なのに対し、こちらは Sigstore (Rekor) を
直接叩く。GitHub の rate limit / API 障害時の代替手段。
# cosign 1.x 系 (https://github.com/sigstore/cosign)
COSIGN_EXPERIMENTAL=1 cosign verify-attestation \
--type slsaprovenance1 \
--certificate-identity-regexp 'https://github.com/high-field/parky/.+' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
--bundle attestation.bundle \
/tmp/parky-dist/index.js
SBOM の中身 inspect
# 直近の SBOM artifact を取得
gh run download --name sbom-api-<sha> -D /tmp/parky-sbom
# CycloneDX JSON の component 数 / license 一覧
jq '.components | length' /tmp/parky-sbom/sbom-api.cdx.json
jq -r '.components[] | "\(.name)@\(.version)\t\(.licenses[0].license.id // "?")"' \
/tmp/parky-sbom/sbom-api.cdx.json | sort -u | head -50
# CVE スキャン (grype を使う場合)
grype sbom:/tmp/parky-sbom/sbom-api.cdx.json --fail-on high
SHA pin 状態
| action | pin 形式 | 備考 |
|---|---|---|
actions/checkout@93cb6efe... (v5.0.1) | commit SHA | repo 全体で統一済 |
1password/load-secrets-action@92467eb2... (v4.0.0) | commit SHA | ― |
actions/attest-build-provenance@v1 | loose | TODO(supply-chain): 公式 release SHA に pin。releases 確認後置換 |
actions/dependency-review-action@v4 | loose | TODO(supply-chain): 公式 release SHA に pin。releases 確認後置換 |
actions/setup-node@v4 等 | loose | repo 横断 cleanup (別 PR) |
既知の限界
1. Cloudflare Pages 配信は attestation 非対応
Parky の portal-{admin,owner,marketing} と web-home は Cloudflare Pages で配信している。 Pages は CF 側で build を実行するため、GitHub Actions runner の OIDC token 経由で attestation を発行できない (build artifact が GHA から見えない)。
代替策:
- Pages の deploy log + commit SHA を「監査ログ」として扱う (CF dashboard > Deployments > Build log を保管 90 日)。
- SBOM は repo 視点 (source code dependencies) で取得済 (
sbom-web-portal-*)。 build time の transitive までは追えないが CVE 監査の一次フィルタとしては十分。 - 将来 Pages を Cloudflare Workers Sites or 自前 build → wrangler deploy に切替えれば attestation 化可能。 現状は予定なし。
2. Mobile (Flutter) artifact は対象外
Flutter アプリ (mobileapp/) は App Store / Play Store の signing chain が別系統 (Apple / Google の key chain) なので、SLSA provenance とは別レイヤーの保証になる。本書のスコープ外。
3. wrangler bundle は npm registry に hermetic 依存していない
SLSA L4 の hermetic 要件 (build inputs が完全に固定 / 外部 fetch 禁止) は、
wrangler deploy が npm registry / esbuild / wrangler binary を CI 内で fetch する以上
未達。npm cache + lockfile pin で実用上の固定性は確保しているが、L4 認定には別途 sandboxed builder
への移行が必要。優先度低。
運用
新規 deploy 対象を追加するとき
sbom.ymlのmatrix.targetに追加。 label / workspace / out 3 フィールドだけ書けば SBOM artifact が自動生成される。- 新 deploy workflow に
- job レベル
permissions:にid-token: write+attestations: write - build step の後に
actions/attest-build-provenance@v1withsubject-path
- job レベル
- 本書の §SLSA Level 達成度 / §SHA pin 状態 を更新。
CVE が出たとき (緊急対応)
- Dependabot Alerts で影響範囲を確認。
- 直近の SBOM artifact (90 日保管) を
gh run download --name sbom-bundle-<sha>で取得し、grype sbom:...で本番 build に乗っているか scan。 - 該当する場合、Dependabot PR を merge → deployment-rollback.html の hotfix 経路で deploy。
- 事後: postmortem template に従い AI を起こす。
許可 license の追加
dependency-review.yml の
allow-licenses リストを編集。GPL/AGPL/SSPL 等の copyleft は 個別 PR で議論
してから追加すること。「うっかり混入」を防ぐため、CI fail を一次フィルタとして必ず通す。
follow-up
- TODO attest-build-provenance / dependency-review-action の SHA pin 確定 (loose pin 解消)
- TODO TruffleHog workflow 追加 (commit history full scan / 週次)
- TODO CodeQL 有効化 (JS/TS の SAST)
- TODO SBOM の release tag attach(GH Release 作成時に sbom-bundle を release asset として上げる)
- TODO
cosign verify-attestationの検証手順をscripts/audit/verify-attestation.shとして用意