diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile index b9844a4..862498e 100644 --- a/.clusterfuzzlite/Dockerfile +++ b/.clusterfuzzlite/Dockerfile @@ -1,4 +1,4 @@ -FROM gcr.io/oss-fuzz-base/base-builder-python +FROM gcr.io/oss-fuzz-base/base-builder-python@sha256:e24e8e50612617101dd10038502f68268ab45f31d79a3722c230464277a951b3 # Install minimal build deps RUN apt-get update && apt-get install -y --no-install-recommends \ diff --git a/.github/workflows/paper-review.yml b/.github/workflows/paper-review.yml index 2103394..0b01624 100644 --- a/.github/workflows/paper-review.yml +++ b/.github/workflows/paper-review.yml @@ -29,9 +29,7 @@ on: default: "10" permissions: - contents: write # to commit state.json + pending stubs - issues: write # to file the daily summary issue - pull-requests: write # so the bot can open a PR with the new pending files + contents: read concurrency: group: paper-review @@ -41,6 +39,10 @@ jobs: review: name: Review 10 papers and file pending candidates runs-on: ubuntu-latest + permissions: + contents: write # commit state.json + pending stubs to bot branch + issues: write # file daily summary issue + pull-requests: write # open bot PR with new pending files steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 diff --git a/docs/scorecard-alerts-2026-05-19.html b/docs/scorecard-alerts-2026-05-19.html new file mode 100644 index 0000000..acdf477 --- /dev/null +++ b/docs/scorecard-alerts-2026-05-19.html @@ -0,0 +1,351 @@ + + + + +Code Scanning アラート精査レポート — 2026-05-19 + + + + + +

Code Scanning アラート精査レポート

+
対象: killertcell428/aigis · 取得日 2026-05-19 · 検出元 Scorecard · 件数 9 (High 5 / Medium 3 / Low 1)
+ +

1. エグゼクティブサマリ

+ +
+
5
High
+
3
Medium
+
1
Low
+
3
即時修正推奨
+
3
改善余地あり
+
3
運用判断 / 受容
+
+ +

9件すべて Scorecard が機械的に検出したセキュリティ・ベストプラクティス違反であり、 +実害のある脆弱性ではない。ただし #182 (paper-review.yml の top-level write 権限) +は GITHUB_TOKEN を最小権限化する観点で真の修正が必要。 +他の High 3件は既に job-level スコープを切っており、Scorecard の検出ロジックの粒度の問題で +残っている false-positive 寄りのもの。Medium 3件 (Pinned-Dependencies) は OSS-Fuzz 慣行と +噛み合わない部分があり、コスト対効果の判断が必要。

+ +

推奨対応順

+
    +
  1. 即対応 — #182 paper-review.yml の権限を job-level に移し top-level を contents: read
  2. +
  3. 即対応 — #173 .clusterfuzzlite/Dockerfile の base image を digest pin
  4. +
  5. 近日対応 — #8 master の Branch Protection ルール設定 (docs/scorecard-governance-setup.html の続編)
  6. +
  7. 判断 → ドキュメント化 — #179/#180/#181 (job-level write は許容方針として記録)
  8. +
  9. 判断 → ドキュメント化 — #174/#175 (pip hash pinning は CI 維持コスト次第)
  10. +
  11. 後回し可 — #57 CII Best Practices badge の取得
  12. +
+ +

2. アラート一覧

+ + + + + + + + + + + + + + + + +
#カテゴリSevファイル判定
#182Token-PermissionsHigh.github/workflows/paper-review.yml:32修正必須
#181Token-PermissionsHigh.github/workflows/zenn-deploy-trigger.yml:14運用判断 (受容可)
#180Token-PermissionsHigh.github/workflows/sync-zenn-qiita.yml:16運用判断 (受容可)
#179Token-PermissionsHigh.github/workflows/release.yml:134運用判断 (受容可)
#8Branch-ProtectionHigh(repo settings)設定追加推奨
#175Pinned-DependenciesMedium.clusterfuzzlite/build.sh:8低優先 (OSS-Fuzz 環境)
#174Pinned-DependenciesMediumDockerfile:6判断 (hash pin コスト)
#173Pinned-DependenciesMedium.clusterfuzzlite/Dockerfile:1修正推奨 (low cost)
#57CII-Best-PracticesLow(badge 未登録)後回し可
+ +

3. アラート別の詳細と修正提案

+ + +
+

#182 Token-Permissions 修正必須

+
+
ファイル
.github/workflows/paper-review.yml:31-34
+
原因
top-level で contents: write / issues: write / pull-requests: write を付与している。Scorecard は top-level write 権限を「ワークフロー内のあらゆる action にトークンが流れる」として High 判定。
+
リスク
Anthropic API キー込みのワークフローで、悪意のある依存 (uv / setup-python のサプライチェーン経由) があった場合、トークン奪取によりリポジトリ書き込みまで連鎖し得る。
+
+ + 修正案 — top-level を read に、job-level で必要権限を付与 +
# 31-34行目を以下に置換
+permissions:
+  contents: read
+
+concurrency:
+  group: paper-review
+  cancel-in-progress: false
+
+jobs:
+  review:
+    name: Review 10 papers and file pending candidates
+    runs-on: ubuntu-latest
+    permissions:
+      contents: write       # commit state.json + pending stubs to bot branch
+      issues: write         # file daily summary issue
+      pull-requests: write  # open bot PR
+    steps:
+      ...
+
+ +
+ 確認ポイント + +
+
+ + +
+

#181 Token-Permissions 運用判断 — 受容可

+
+
ファイル
.github/workflows/zenn-deploy-trigger.yml:13-14
+
現状
top-level は既に contents: read。job-level で contents: write を最小限付与済 (push の為に必須)。
+
Scorecard 判定理由
Scorecard は あらゆる write 出現を High カウントするため、job-level でも残る。これはツール側の設計で、現状の構成は GitHub Actions のベストプラクティスに完全準拠している。
+
+ + 対応案 +

3案あり、どれを選ぶかは運用ポリシー次第。

+
    +
  1. 受容してドキュメント化 (推奨): docs/scorecard-governance-setup.html に「job-level write は許容、top-level write は禁止」の方針を追記し、本アラートを Scorecard 側で dismiss する。
  2. +
  3. Deploy Key 化: GITHUB_TOKEN をやめ、専用 SSH デプロイキーで push する。contents: 権限自体を不要にできるが、シークレット管理コストが増える。empty commit を打つだけのワークフローには過剰。
  4. +
  5. 外部 App Token 化: GitHub App を作って actions/create-github-app-token で発行。最小権限を厳密化できるが、運用が重い。
  6. +
+
+ + +
+

#180 Token-Permissions 運用判断 — 受容可

+
+
ファイル
.github/workflows/sync-zenn-qiita.yml:15-16
+
現状
#181 と同様、top-level contents: read + job-level contents: write の正しい構成。
+
用途
Zenn → Qiita 変換後の public/ ディレクトリを bot push し、Qiita CLI で publish。
+
+ 対応案 +

#181 と同じく、受容+ドキュメント化が現実解。Qiita publish 部分は別途 QIITA_TOKEN シークレットを使うので、GITHUB_TOKEN 側を厳しく絞るインセンティブは低い。

+
+ + +
+

#179 Token-Permissions 運用判断 — 受容可 / 一部最適化余地

+
+
ファイル
.github/workflows/release.yml:133-134 (github-release job)
+
現状
top-level contents: read + github-release job のみ contents: write (Release 作成のため必須)。build / publish-pypicontents: read + OIDC id-token: write で正しくスコープ済。
+
Scorecard 判定理由
job-level の contents: write 1箇所を機械的に検出。
+
+ 対応案 + +
+ + +
+

#8 Branch-Protection 設定追加推奨

+
+
対象
repository settings (no file)
+
原因
master ブランチに Branch Protection ルールが未設定 (または Scorecard が読み取れる範囲では未設定)。
+
リスク
direct push / force push / CI 未通過マージが理論上可能。CLAUDE.md の release プロセス (PR マージ → tag) を制度的に強制できない。
+
+ 推奨ルール (Settings → Branches → Add rule) + +

※ 既存の docs/scorecard-governance-setup.html に該当章があるかは要確認。なければ追記。

+
+ + +
+

#175 Pinned-Dependencies 低優先

+
+
ファイル
.clusterfuzzlite/build.sh:8 (pip3 install --no-cache-dir .)
+
原因
aigis 自身 (ローカルパス .) の install で --require-hashes 等のハッシュ検証なし。
+
リスク評価
ローカルソースを install しているため通常意味でのサプライチェーンリスクは低い。Scorecard はチェックロジック上 pip install の出現自体を機械的に検出。
+
+ 対応案 +

このまま受容で良い。ClusterFuzzLite の build はホスト fuzz 環境内で完結し、wheel/sdist を index から取らないため攻撃面が無い。Scorecard 側で dismiss reason = "No PyPI download — installs local source only" として閉じる。

+
+ + +
+

#174 Pinned-Dependencies 判断 — hash pin か受容か

+
+
ファイル
Dockerfile:6 (pip install ... 'pip==26.1.1' 'build==1.5.0')
+
現状
バージョンは pin 済だが、Scorecard が要求するのは --require-hashes + --no-deps による SHA-256 hash pinning。
+
+ 案A — 完全 hash pin (Scorecard を Pass にする) +
COPY requirements-build.txt /tmp/
+RUN pip install --no-cache-dir --require-hashes -r /tmp/requirements-build.txt
+
+

requirements-build.txt:

+
pip==26.1.1 \
+    --hash=sha256:<...>
+build==1.5.0 \
+    --hash=sha256:<...>
+
+

+ pip-compile --generate-hashes でハッシュ生成、依存 update のたびに pin を更新する CI が必要。

+ + 案B — 受容 (推奨) +

build stage の依存は pipbuild の2つだけで、いずれも PyPI 公式パッケージ。hash pin の運用コストの方が高い可能性。Dependabot で version pin を継続管理する方が ROI が高い。

+
+ + +
+

#173 Pinned-Dependencies 修正推奨

+
+
ファイル
.clusterfuzzlite/Dockerfile:1
+
原因
FROM gcr.io/oss-fuzz-base/base-builder-python がタグなし・digest なし (=latest 相当)。
+
リスク
base image が更新されると fuzz harness の build 結果が変わる (再現性無し)。供給元 (Google OSS-Fuzz) は信頼できるが「再現可能ビルド」観点で問題。
+
+ 修正案 +
# 最新 digest を取得して固定
+FROM gcr.io/oss-fuzz-base/base-builder-python@sha256:<digest>
+
+

本体 Dockerfile は既に python:3.14-slim@sha256:7a500125... で pin 済なので、同じ流儀に合わせるだけ。digest 取得は次のいずれか:

+ +

運用: Dependabot は GCR の digest 更新も検知できるよう package-ecosystem: docker.github/dependabot.yml に追加 (まだ無ければ)。

+
+ + +
+

#57 CII-Best-Practices 後回し可

+
+
対象
OpenSSF Best Practices Badge (旧 CII Best Practices)
+
原因
bestpractices.dev での self-certification 未取得。
+
+ 対応案 +

30〜60分の self-assessment フォーム記入で Passing badge は取得可能。README に bestpractices.dev のバッジを貼ると外部信頼度↑。docs/openssf-best-practices.md 既存ドキュメントの内容を踏まえると、すでにかなりの基準を満たしているはず。優先度低だがコストも低いので、空き時間にやれる。

+
+ +

4. 実装プラン (採用された場合のチェックリスト)

+ +
+Phase 1 — 1 PR で完結する低リスク変更 + +
+ +
+Phase 2 — リポジトリ設定 (UI 操作) + +
+ +
+Phase 3 — 判断が必要な改善 + +
+ +

5. 参考

+ + + + diff --git a/docs/scorecard-governance-setup.html b/docs/scorecard-governance-setup.html index 353d20c..b1a4bb3 100644 --- a/docs/scorecard-governance-setup.html +++ b/docs/scorecard-governance-setup.html @@ -69,6 +69,8 @@

サマリ

CodeReviewinfo運用変更BranchProtection と一緒に解決 CIIBestPracticesinfo30分〜数時間OSS 公開ならやる価値あり Fuzzinginfo数日後回しでOK +Token-Permissions (job-level)info—受容 (§6) +Pinned-Dependencies (local install)info—受容 (§6) @@ -124,6 +126,30 @@

手順(GitHub UI)

注意: 1 人開発のリポでも approval=1 を要求するとマージできなくなる場合があります。その場合は approval を 0 にしつつ status checks のみ必須化する、または GitHub の "Allow specified actors to bypass required pull requests" を使ってください。 +

現状(2026-05-19 時点)と Scorecard alert #8 の扱い

+ +

本リポは既に以下の Branch Protection を有効化済(gh api repos/killertcell428/aigis/branches/master/protection で確認):

+ + + +

Scorecard alert #8 Branch-Protection (High) が残っているのは、最後の required_approving_review_count = 0 に起因する。これは「自分の PR を自分でマージできる必要がある」というソロ開発の現実的制約で、外部コントリビュータが現れたら approval=1 に上げる方針。Won't fix として dismiss する

+ +

dismiss 文言テンプレ:

+
Won't fix — solo developer repo. Branch protection enforces status
+checks, signed commits, linear history, and admin enforcement; only
+required_approving_review_count is 0 (would block all merges otherwise).
+Will raise to 1 once a second maintainer joins.
+See docs/scorecard-governance-setup.html §1.
+

2. Maintained — リポジトリ作成から90日未満

Scorecard 指摘: Repository was created within the last 90 days

@@ -196,6 +222,104 @@

推奨アプローチ: Atheris (Python ネイティブ)

後回しでOK。先に他の項目を片付けてから検討。

+

6. 受容方針 — Token-Permissions (job-level) と Pinned-Dependencies (local install)

+ +

+Scorecard が High / Medium で機械的に検出するが、構成上「これ以上絞れない/絞ると別のリスクが増える」種類のアラートを明示的に受容する方針を以下に定める。新しいアラートが同じカテゴリで上がった場合、本セクションに照らして dismiss 可否を判断する。 +

+ +

6.1 Token-Permissions: job-level contents: write は許容、top-level は禁止

+ +

方針:

+ + +

根拠:

+ + +

対応済アラート:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Alertファイル用途判断
#179.github/workflows/release.yml:134github-release job — GitHub Release 作成のため contents: write 必須受容 (build/publish-pypi job は OIDC 化済で contents: read)
#180.github/workflows/sync-zenn-qiita.yml:16Zenn→Qiita 変換後の public/ commit + push受容
#181.github/workflows/zenn-deploy-trigger.yml:14Zenn deploy トリガーの empty commit push受容
+ +

dismiss 文言テンプレ(Code scanning UI で使用):

+
Won't fix — job-level permissions are correctly scoped per
+docs/scorecard-governance-setup.html §6.1.
+Top-level is contents:read; this job's write scope is the
+minimum required for its function.
+ +

6.2 Pinned-Dependencies: ローカルソースの pip install は許容

+ +

方針:

+ + +

根拠:

+ + +

対応済アラート:

+ + + + + + + + + + + + + +
Alertファイル内容判断
#175.clusterfuzzlite/build.sh:8pip3 install --no-cache-dir . — ローカル aigis ソースの install受容 (ネットワーク取得なし)
+ +

dismiss 文言テンプレ:

+
Won't fix — installs local source only (no PyPI download),
+no supply-chain surface. See docs/scorecard-governance-setup.html §6.2.
+ +

6.3 判断保留

+ +

以下は受容も修正もせず、運用コストとのトレードオフを継続検討する:

+ +

完了確認

すべて設定後、Scorecard を再実行して結果を確認できます: