# 個人開発のセキュリティ・チェックリスト — リリース前に最低限これだけ（全部無料）

> 時間も予算もない個人開発者向けのリリース前セキュリティ・チェックリスト。秘密情報・依存脆弱性・認可（RLS）・入力検証を、Secret scanning・Dependabot・npx @aegiskit/cli scan・/aegis/rls-checker など全部無料のツールで機械的に潰す手順を解説します。

- 公開日: 2026-07-07
- 著者: 友田 陽大
- タグ: セキュリティ, バイブコーディング, AI駆動開発, Next.js, Supabase
- URL: https://tomodahinata.com/blog/personal-project-security-checklist-solo-dev-guide
- カテゴリ: バイブコーディング
- 総合ガイド: https://tomodahinata.com/blog/vibe-coding-what-is-tools-risks-production-guide

## 要点

- 個人開発の勝ち筋は『水平の統制（アプリ横断で一律に効く）を全部無料ツールに機械化させ、自分は縦のリスク（認可・RLS設計）だけに集中する』こと。ここを分けないと1人では守り切れない
- リリース前チェックは5項目——(1)秘密情報を漏らさない (2)依存の既知脆弱性を放置しない (3)認可を『画面のif文』で済ませない (4)入力を境界で検証する (5)CIで再発を止める。全部無料で、初回1時間・以後は自動で回る
- 秘密情報と依存脆弱性は完全に機械の仕事——`.env` を絶対コミットしない＋GitHub Secret scanning（公開リポジトリは無料・自動）＋Dependabot（無料）＋`npx @aegiskit/cli scan` で形（パターン）だけで拾える
- 唯一ツールが直せないのが認可（縦のリスク）。『認証はするが行を所有者に絞らない』RLSが典型で、USING(true) は公開テーブルなら正しいがそれ以外は事故。/aegis/rls-checker が migrations を読んで疑わしい箇所を警告する
- 正直なスコープ：無料ツールは水平統制を自動化し、縦のリスクは『検出して警告』するだけ。完全な防護は謳えない。業務ロジック・テナント分離の最終判断は人間の設計に残る

---

最初に結論を述べます。**個人開発でセキュリティを守り切る鍵は「水平の統制（アプリ横断で一律に効く対策）を全部無料ツールに機械化させ、自分は縦のリスク（認可・RLS設計）だけに集中する」ことです。** 予算も時間もレビュアーもいない1人開発では、注意力に頼った対策は必ず穴が開きます。だから、機械に任せられるところは1コマンドで機械に番をさせ、人間にしか判断できない設計だけに自分の時間を割く——これが唯一スケールする戦い方です。

私は一人 × 生成AI（Claude Code）で、経済産業大臣賞を受賞したB2B SaaSや本番二重課金0件の決済基盤を作ってきました。だから断言できます——**AIで速く作れるようになったぶん、放っておくと脆弱性も同じ速さで増えます。** でも安心してください。個人開発でリリース前に潰すべき穴は、ほとんどが「決まった場所」に出るので、**全部無料のツールで、初回1時間・以後は自動で回せます。** 本記事はその実務チェックリストです。

---

## 1. 個人開発こそ「機械に番をさせる」——水平と縦を分ける

セキュリティ対策は、性質の違う2種類に分かれます。この線引きが個人開発の全戦略です。

| | 水平の統制 | 縦のリスク |
|---|---|---|
| 何か | アプリ横断で一律に効く対策 | アプリ固有の「誰が何を所有するか」に依存 |
| 例 | 秘密情報・依存脆弱性・ヘッダー・入力検証 | 認可 / IDOR・RLS設計・テナント分離・業務ロジック |
| 直せるのは | **ツール（無料で機械化できる）** | **あなた（設計とレビューでしか閉じない）** |
| 個人開発の方針 | 1コマンドで自動化し、以後は考えない | ここに時間を集中投下する |

個人開発の失敗は、この2つを混ぜて「全部を気合いで見る」ことから起きます。水平の統制まで手動でやろうとすると疲弊して漏らし、本当に頭を使うべき縦のリスク（認可）に集中力が残らない。**機械に任せられるものは機械に、人間にしか無理なものだけ人間に。** 発注者視点での全体像は[AI生成コードの脆弱性診断【4層で潰す】](/blog/ai-generated-code-vulnerability-assessment-vibe-coding-security-guide)と[AIで作ったコードの本番化（ハードニング）](/blog/vibe-coding-ai-generated-code-production-hardening-guide)にまとめています。本記事は、その考え方を**作り手の1人開発者向けに、無料ツールだけの実務手順**へ落とし込んだものです。

---

## 2. リリース前チェックリスト（優先順位順・全部無料）

まず全体像です。上から順に、被害の大きさ × 機械化のしやすさで並べています。

| # | 項目 | 何を防ぐ | 無料ツール | 初回 |
|---|---|---|---|---|
| 1 | 秘密情報を漏らさない | 鍵・トークンの全世界公開 | `.gitignore` / GitHub Secret scanning / `npx @aegiskit/cli scan` | 15分 |
| 2 | 依存の既知脆弱性 | 既知CVEの放置 | Dependabot / `npm audit` | 10分 |
| 3 | 認可（縦のリスク） | 他人のデータ読み書き（IDOR） | `/aegis/rls-checker` / `npx @aegiskit/cli scan` | 20分 |
| 4 | 入力を境界で検証 | 注入・不正データ | Zod / `npx @aegiskit/cli init` | 10分 |
| 5 | CIで再発を止める | 一度直した穴の再発 | GitHub Actions（Aegis / Dependabot） | 10分 |

1・2・4は完全に水平（機械の仕事）。3が唯一の縦（あなたの仕事）で、ここだけツールは「検出して警告」までしかできません。以下、1つずつ潰していきます。

---

## 3. 秘密情報を漏らさない（最頻・最悪）

被害が最も大きく、しかも一番よく起きるのがこれです。秘密キーがリポジトリに入った瞬間、それは全世界に配布されたと考えるべきです（履歴に残るので、消しても遅い＝**必ずローテーション**）。

やることは3つ。

1. **`.env*` を絶対にコミットしない。** `.gitignore` に `.env*` を入れる。これだけで大半の事故は防げます。
2. **`NEXT_PUBLIC_` の罠を理解する。** Next.js では `NEXT_PUBLIC_` 接頭辞付きの値がビルド時にクライアントバンドルへ平文で焼き込まれます。ここに `service_role` キーやAPI秘密を置くと公開されます。仕組み・型付きenv境界・`server-only` の使い方は[Next.jsの環境変数と秘密漏洩対策 — NEXT_PUBLIC_ の罠](/blog/nextjs-env-secret-leak-prevention-public-vars-guide)で実コードごと解説しているので、ここでは繰り返しません。個人開発でも**必読の一本**です。
3. **機械に見張らせる。** GitHub の Secret scanning は**公開リポジトリなら無料で自動的に**動き、混入した認証情報を検知して警告します（[GitHub Docs](https://docs.github.com/en/code-security/secret-scanning/introduction/about-secret-scanning)）。加えて `npx @aegiskit/cli scan` が、ハードコードされた鍵・トークンと「`NEXT_PUBLIC_` × 秘密鍵」の組み合わせを**形（パターン）だけで**拾います。

```bash
# インストール不要。いまのプロジェクトを静的解析する
npx @aegiskit/cli scan
```

正直なスコープを1つ。ツールが機械化できるのは「秘密が**混入したこと**」の検出です。「その値を公開してよいか」の判断はアプリの意味に依存する人間の設計で、ここは自動化できません。つまり**混入は止められても、公開可否は決められない**。

---

## 4. 依存関係の既知脆弱性を放置しない

自分の書いたコードが完璧でも、依存ライブラリに既知の穴があれば刺されます。ここも完全に機械の仕事です。

- **Dependabot を有効化する（無料）。** リポジトリ設定から Dependabot alerts を有効にすると、GitHub Advisory Database に照らして脆弱な依存を通知し、修正版へのPRを自動で出してくれます（[GitHub Docs](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts)）。個人開発で「依存を最新に保つ」を人力でやるのは非現実的なので、まず入れる。設定と運用の実務は[Dependabot 実践導入ガイド](/blog/dependabot-production-guide)と[Dependabotで脆弱性を管理する](/blog/dependabot-security-updates-alerts-vulnerability-management-guide)にまとめています。
- **ローカルの即席チェックは `npm audit`。** コミット前に一度回すだけでも、既知CVEの持ち込みを減らせます。

```bash
# 既知脆弱性のある依存を即席で確認
npm audit --omit=dev
```

さらにAI時代固有の罠として、生成AIが**実在しないパッケージ名**を提案し、攻撃者がその名を先回り登録する「slopsquatting」があります。`npm install` する前にパッケージの実在とダウンロード実績を確認する癖をつけてください（仕組みと対策は[AI生成コードの脆弱性診断](/blog/ai-generated-code-vulnerability-assessment-vibe-coding-security-guide)で詳述）。

---

## 5. 認可を「画面のif文」で済ませない — 唯一の縦のリスク

ここが本丸で、**無料ツールが直してくれない唯一の項目**です。AIも人間も、認可を「画面のボタンを出す／出さない」で済ませがちですが、APIやDBを直接叩かれれば画面のif文は無意味です。オブジェクト単位の認可欠陥（IDOR / BOLA）は、OWASP API Security Top 10 で長年**第1位**の最頻出リスクであり続けています（[OWASP](https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/)）。

### 5-1. 「認証はするが認可しない」を疑う

最頻の事故パターンが、**ログインは要求するのに「その行を誰が所有するか」を絞っていない**RLSです。Supabase なら、こういうポリシは危険信号です。

```sql
-- 危険：ログインさえしていれば「全ユーザーの全行」が読める
create policy "read" on notes
  for select to authenticated
  using ( true );

-- 正しい：自分が所有する行だけに絞る
create policy "read own" on notes
  for select to authenticated
  using ( auth.uid() = user_id );
```

`USING (true)` は**そのテーブルが本当に公開前提（誰でも読んでよい）なら正しい**選択です。問題は、非公開データのテーブルにこれを書いてしまうこと。「認証」と「認可」は別物だという整理は[Supabase RLS：authenticated と authorized は違う](/blog/supabase-rls-authenticated-vs-authorized-owner-scope-guide)で詳しく解説しています。

これは机上の心配ではありません。公開Supabaseアプリ1,000件の一次調査で、RLSを持つアプリのうち約9.2%が「認証はするが行を所有者に絞らない」ポリシを持っていました（公開リポジトリ標本ゆえ下限値。所有者非スコープ＝即脆弱ではなく要確認）。手法と実データは[Supabase RLS セキュリティ実地調査](/blog/supabase-rls-security-field-study)にあります。そしてRLS未設定のまま公開して未認証で他人のデータを読み書きされた事例は、実際に CVE（[CVE-2025-48757](https://nvd.nist.gov/vuln/detail/CVE-2025-48757)、CVSS 9.3 CRITICAL）として登録されています。

### 5-2. 無料で「形」の間違いを機械検出する

意味の正しさは人間にしか判定できませんが、**「形」の間違いは無料で機械検出できます。** [/aegis/rls-checker](/aegis/rls-checker) と `npx @aegiskit/cli scan` は Supabase の `migrations/**.sql` を読み、次を警告します。

- RLSが**未設定**のテーブル
- 無条件の `USING (true)`（公開意図なら可、それ以外は要修正）
- `WITH CHECK` 欠落（読めるが書き込み側の所有権チェックが抜けている）
- `search_path` を固定しない `SECURITY DEFINER` 関数（権限昇格の温床）

```sql
-- SECURITY DEFINER 関数は search_path を必ず固定する
create function public.get_my_data()
returns setof notes
language sql
security definer
set search_path = ''          -- ← これが無いと path 経由で乗っ取られうる
as $$ select * from public.notes where user_id = auth.uid() $$;
```

### 5-3. `service_role` の置き場所が「守りの境界」になる

Supabase の `service_role` キーは PostgreSQL の `BYPASSRLS` で動き、**RLSを完全に無視します**（[Supabase Docs](https://supabase.com/docs/guides/database/postgres/row-level-security)）。つまりこのキーをクライアントやエッジに漏らした瞬間、どれだけ丁寧にRLSを書いても全部無効。**守りの境界は「鍵の置き場所」に移る**ということです。`service_role` はサーバー専用の秘密として扱い、第3節の秘密情報衛生とセットで守ってください。

ここが唯一「ツールでは閉じない」ところなので、個人開発者が最も頭を使うべきポイントです。`/aegis/rls-checker` は疑わしい箇所を**警告するところまで**——閉じるのはあなたの設計判断です。

---

## 6. 入力を境界で検証する

外部から来るデータ（フォーム・API・クエリ）は、すべて「敵対的入力かもしれない」前提で境界で検証します。ここは水平（機械化できる）に戻ります。

- **Zod で境界の型検証。** Route Handler や Server Action の入口で、外部入力を必ず Zod でパースしてから使う。「動いたから」で素通しにしない。
- **ランタイム強化を1コマンドで。** `npx @aegiskit/cli init` は、セキュリティヘッダー / CSP・レート制限・CSRF・型付きenv境界を、ミドルウェア1枚として一括で足します。個人開発で毎回手書きするより、まず入れて土台を固めるのが速い。

```bash
# ヘッダー/CSP・レート制限・CSRF・型付きenv境界をミドルウェアで導入
npx @aegiskit/cli init
```

---

## 7. CIで再発を止める（チェックリストを「1回」で終わらせない）

ここまでの対策は、**1回やって満足すると必ず腐ります。** AIに機能を足すたびに新しい穴が入るので、チェックを「毎push自動」にして初めて価値が出ます。個人開発でもここは省略しないでください。

- GitHub Actions に Aegis の CI ステップ（`aegis ci`）を足すと、高信頼の検出だけがビルドを止め、SARIF が GitHub code scanning に残ります（誤検知でビルドを壊さない設計）。
- Dependabot・Secret scanning は、有効化した時点で毎pushに効き続けます。

「毎回同じ品質ゲートを機械に通す」考え方そのものは[AI駆動開発の品質ゲート（CI・型・テスト・セキュリティ）](/blog/ai-driven-development-quality-gates-ci-type-safety-test-security)に、そもそもAIに大規模実装を任せても壊れない進め方は[Spec駆動開発 × Claude Code](/blog/spec-driven-development-claude-code-ai-agent-production-workflow)にまとめています。**生成の速さは落とさず、出荷の前に検証を1枚挟む**——これが1人でも品質を保つ唯一の型です。

---

## 8. 正直なスコープ — 無料ツールで「閉じない」残り

最後に、いちばん大事な但し書きです。**「無料ツールを全部入れたから安全」は最悪の油断です。** そう謳う製品はむしろ危険で、`npx @aegiskit/cli scan` も含め、正直なツールは自分の限界を先に言います。

- 無料ツールが**自動化するのは水平の統制**（秘密情報・依存・ヘッダー・入力検証）。
- 縦のリスク（認可 / IDOR・RLS設計・テナント分離・業務ロジック）は**検出して警告するだけ**。閉じるのはあなたの設計です。
- クリーンな結果が意味するのは「よくある罠は踏んでいない」であって「このコードは安全だ」ではありません。

それでも、**最頻出の穴を機械的に潰せる価値は個人開発ほど大きい**。1人ぶんの注意力を、機械にできる作業から解放して、本当に難しい判断（認可の設計）に集中できるからです。

---

## まとめ：リリース前1時間のチェックリスト

- [ ] `.env*` を `.gitignore` に入れ、秘密は絶対コミットしない（漏れたら**ローテーション**）
- [ ] GitHub Secret scanning を有効化（公開リポジトリは無料・自動）
- [ ] Dependabot を有効化 ＋ コミット前に `npm audit`
- [ ] `npx @aegiskit/cli scan` を回して水平統制の欠落と縦リスクの疑いを一覧化
- [ ] `/aegis/rls-checker` で RLS の「形」を確認し、`USING(true)` の意図を1つずつ検証
- [ ] `service_role` キーはサーバー専用に閉じ込める
- [ ] Zod で境界検証 ＋ `npx @aegiskit/cli init` でランタイム強化
- [ ] CI（`aegis ci` / Dependabot）で毎push自動チェックにする

全部無料です。**水平は機械に、縦は自分に。** この分担さえ守れば、1人でも「デモは動く」を「本番で漏れない」に引き上げられます。検出された縦のリスク（認可・RLS設計）を実際に塞ぐ設計レビューが必要になったら、そのときは[Aegis](/aegis)の無料スキャンから始めて、手が足りなければ相談してください。
