個人開発のリポジトリは、セキュリティ設定が後回しになりがちです。動いているうちは問題が見えないためです。
この検証では、Claude Codeで gh api を使ってリポジトリ設定を監査し、ブランチ保護・Dependabot・CIの設定を一通り適用しました。Dependabotを有効にした直後、11件の脆弱性(high 5件・moderate 6件)が検出されました。
この検証の概要
検証日 | 2026年4月7日(1日で完結) |
|---|---|
対象 | GitHub Repository Settings(Rulesets / Dependabot / Branch Protection) |
やりたかったこと | 個人開発リポジトリにセキュリティ・運用設定のベストプラクティスを適用する |
設定コスト | 約30分 |
最大の発見 | Dependabot有効化直後に11件の脆弱性(high 5件・moderate 6件)を検出 |
状況 | 完了 |
結論:気づいていなかっただけで、脆弱性は存在していた
この検証で最も直接的な成果はこれです。
Dependabotを有効化した直後に11件の脆弱性(high 5件、moderate 6件)が検出されました。
重要なのは、この11件がこの日に発生したわけではないという点です。以前から存在していたものが、検知の仕組みを入れた瞬間に見えるようになっただけです。
脆弱性の有無と、脆弱性に気づけるかどうかは別問題です。設定コストは約30分ですが、放置している間はリスクが可視化されません。
設定前の状態(監査結果)
Claude Codeで gh api を使い、リポジトリの全設定を監査しました。
カテゴリ | 項目 | 設定前 | リスク |
|---|---|---|---|
ブランチ保護 | mainブランチルール | 未設定 | 高 |
ブランチ保護 | CIステータスチェック必須 | 未設定 | 高 |
依存管理 | Dependabotセキュリティ更新 | 無効 | 高 |
依存管理 | dependabot.yml | 未作成 | 中 |
CI/CD | テスト実行 | CIに含まれていない | 高 |
CI/CD | Node.jsバージョン | ワークフロー間で不一致 | 中 |
リポジトリ | マージ戦略 | 3種全て有効 | 低 |
リポジトリ | Auto delete branches | 無効 | 低 |
セキュリティ | Secret scanning / Push protection | 有効(OK) | — |
ブランチ保護:Enforcement を Active にしないと効かない
最初につまずいた点です。
Enforcement status を Active にしないとルールが一切効きません。最初 Disabled で作成してしまい、設定したのに機能していませんでした。
設定したRulesetの構成は次のとおりです。
Ruleset: main
├── Enforcement: active ← 最重要。これがdisabledだと全て無効
├── Target: refs/heads/main
├── Rules:
│ ├── deletion(ブランチ削除禁止)
│ ├── non_fast_forward(force push禁止)
│ ├── pull_request(PR必須、required approvals: 0)
│ └── required_status_checks(CIのbuildジョブ必須)
└── strict_required_status_checks_policy: true(マージ前にブランチ最新化必須)また、GitHub UIが「Branch protection rules(旧)」から「Rulesets(新)」に移行中です。どちらでも同等の保護は可能ですが、ネット記事は旧UIの情報が多いため注意が必要です。
「マージ前にブランチ最新化必須」が防ぐ事故
strict_required_status_checks_policy(Require branches to be up to date before merging)が何を防ぐのかを整理しておきます。
main: A ─── B ─── C (他のPRマージ) ← 今のmain
\
feat: └── D (自分の変更) ← Cの変更を知らない
→ DだけでCIが通っても、C+Dの組み合わせで壊れる可能性がある
→ 「Update branch」でCを取り込み → CIが再実行 → 組み合わせでもOKを保証これがないと「PRのCIは通ったけどマージ後に壊れる」事故が起きます。複数人で開発する場合はもちろん、自分ひとりでも並行してPRを進めていれば発生します。
CIにテストを入れる
監査で見つかった問題のひとつが、テストがCIで実行されていなかったことです。
- run: npm ci
- run: npm run test # ← 追加
- run: npm run check
- run: npm run buildnpm run check(astro check)と npm run build はありましたが、vitestが実行されていませんでした。
テストを書いてもCIで実行しなければ意味がありません。ブランチ保護でこのCIジョブを必須にしているため、テスト失敗=マージ不可になります。
Dependabot:2つの設定が必要
Dependabotは、UIでの有効化と設定ファイルの両方が必要です。
A. GitHub UIでの有効化(Settings → Code security)
- Dependabot alerts → Enable
- Dependabot security updates → Enable
これで脆弱性発見時に自動アラート+修正PRが作られます。
B. 設定ファイル(.github/dependabot.yml)
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
labels:
- "dependencies"
commit-message:
prefix: "chore"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependencies"
commit-message:
prefix: "chore"ここで押さえておきたい構造理解があります。
dependabot.yml はGitHub Actionsのワークフローではありません。.github/ フォルダには2種類のものが入ります。
workflows/→ GitHub Actionsランナーが実行dependabot.yml、PRテンプレート等 → GitHubプラットフォーム本体が読み取って実行
設定ファイルをリポジトリに置くだけで、GitHub側が自動で週次チェックを実行します。npm依存だけでなく github-actions のバージョンも監視対象にすべきです。
Node.jsバージョンをワークフロー間で統一する
CIのワークフローはNode 22に更新済みでしたが、他のワークフローがNode 20のままでした。3ファイルともNode 22に統一しています。
ワークフロー間でランタイムバージョンが異なると、CIは通るが別のActionで失敗するという事故が起きます。Astro 6は >=22.12.0 を要求するため、古い指定が残っていると動きません。
.nvmrc をリポジトリに置いてバージョンを一元管理する方法もあります。
マージ戦略はSquash mergeのみに絞る
方法 | 設定 | 理由 |
|---|---|---|
Merge commit | OFF | 履歴が複雑になる |
Squash merge | ON | 1PR=1コミットで履歴がクリーン |
Rebase merge | OFF | コンフリクト時にややこしい |
Squash mergeにするとPRタイトルがそのままコミットメッセージになります。Conventional Commits形式(feat:、fix: 等)でPRタイトルを付ければ、mainの履歴が自然と整います。
個人開発ではSquash merge一択が最もシンプルです。
再利用できる監査コマンド
他のリポジトリでもそのまま使えます。
# リポジトリ設定の確認
gh api repos/OWNER/REPO --jq '{
default_branch,
allow_merge_commit,
allow_squash_merge,
allow_rebase_merge,
delete_branch_on_merge
}'
# セキュリティ設定の確認
gh api repos/OWNER/REPO --jq '.security_and_analysis'
# ブランチ保護ルールの確認
gh api repos/OWNER/REPO/branches/main/protection
# Rulesets の確認
gh api repos/OWNER/REPO/rulesets
gh api repos/OWNER/REPO/rulesets/RULESET_ID | jq '{name, enforcement, rules}'
# Secrets の確認(値は見えない)
gh api repos/OWNER/REPO/actions/secrets --jq '.total_count'.gitignoreの補完
カテゴリ | パターン | 理由 |
|---|---|---|
macOS |
| Finderが全ディレクトリに生成 |
macOS |
| 外部ドライブで特に発生しやすい |
macOS |
| 外部ドライブのメタデータ |
エディタ |
| 個人設定の混入防止 |
テスト |
| vitest --coverage の出力 |
ログ |
| デバッグログ |
ホスティング |
| 将来の移行に備え |
よくある質問
個人開発でもブランチ保護は必要ですか?
必要です。設定コストは約30分程度ですが、mainへの直push・CIスキップ・脆弱性の未検知といったリスクを防げます。
Rulesetを作ったのに効きません
Enforcement status が Active になっているか確認してください。Disabled のままだとルールは一切効きません。
dependabot.yml を置くだけで動きますか?
設定ファイルに加えて、GitHub UIでの有効化(Settings → Code security)も必要です。なお dependabot.yml はGitHub Actionsのワークフローではなく、GitHubプラットフォーム本体が読み取って実行します。
「マージ前にブランチ最新化必須」は何を防ぎますか?
「PRのCIは通ったけどマージ後に壊れる」事故です。自分の変更だけでCIが通っても、その間にマージされた他の変更との組み合わせで壊れる可能性があります。
まとめ
- Dependabot有効化の直後に11件の脆弱性(high 5件・moderate 6件)を検出。気づいていなかっただけで存在していた
- RulesetはEnforcement を Active にしないと一切効かない。GitHub UIは旧「Branch protection rules」から「Rulesets」へ移行中
- strict_required_status_checks_policy で「CIは通ったがマージ後に壊れる」事故を防ぐ
- テストを書いてもCIで実行しなければ意味がない。ブランチ保護でCI必須にすればテスト失敗=マージ不可
.github/にはActionsが実行するもの(workflows/)とGitHub本体が読むもの(dependabot.yml等)の2種類がある- マージ戦略はSquash mergeのみに絞ると履歴が整う。設定コストは全体で約30分
セキュリティ設定は、問題が起きてから入れると被害の確認から始まります。検知の仕組みだけでも先に入れておくと、判断できる状態を保てます。
株式会社AI棒では、こうしたAI活用の検証を日々行い、企業の開発体制の整備を支援しています。ご相談はお問い合わせフォームから、継続的な伴走支援についてはAI参謀をご覧ください。
