株式会社Good Labでエンジニアをしている コータロー です。
日々、Java・SQL・Gitなどの技術情報や、新人エンジニア向けの学習ノウハウ、
AI活用についての情報を発信しています。
Good Labについて気になった方は、コーポレートサイトもぜひご覧ください。
▶コーポレートサイト
※本記事はそのまま社内マニュアルとして転用しやすいよう、本文は「である調」で統一しています。
はじめに
Claude CodeやCursorなどのAIエージェントを使い、自然言語の指示だけでアプリを組み上げる「バイブコーディング」が急速に普及している。プロトタイプの作成速度は劇的に向上したが、その一方でセキュリティリスクも加速している。AIが自律的にファイルを読み書きし、外部パッケージを導入し、コマンドを実行する以上、従来の手動コーディングとは異なるリスクへの備えが必要である。
特にバイブコーディングでは「動けばOK」の精神でレビューが省略されがちであり、APIキーの漏洩やサプライチェーン攻撃といった脅威が見過ごされやすい。GitHubにAWSキーをpushした結果、ボットが数分以内にそれを検出し、不正利用によって数十万円の請求が発生した報告もある。AIが関わるからこそ、人間が意識的にセキュリティの防壁を構築しなければならない。
この記事は読み物としてセキュリティの勘所を学ぶだけでなく、チェックリスト部分を切り取ってそのまま社内マニュアルとして運用できるように設計している。NotionやGitHubにそのまま貼り付けて、プロジェクトごとにカスタマイズしてご自由にご活用いただきたい。
用語定義
本記事では以下の用語を統一して使用する。
- シークレット:APIキー、トークン、パスワード、秘密鍵など、漏洩時に不正利用される可能性のある値の総称
- バイブコーディング:AIエージェントに自然言語で指示し、コードの大部分をAIに生成させる開発スタイル
個人開発編:セキュリティチェックリスト
⚠️ 1. シークレットのハードコード
バイブコーディングではプロンプトにAPIキーを含めて指示しがちである。AIはその値をそのままソースコードに埋め込むため、Gitにpushした瞬間に全世界に公開されるリスクがある。手動コーディングであれば.envから読む実装を自分で書くが、バイブコーディングではプロンプト自体が汚染源になる。「このAPIキーを使って実装して」と書いた瞬間、AIはそれをコードにベタ書きする。
被害例:GitHubにAWSのアクセスキーをpushした場合、自動スキャンボットが数分以内に検出し、暗号通貨マイニングなどに悪用されて数十万円の請求が発生した事例が複数報告されている。
❌ 悪い例:
let apiKey = "sk-ant-api03-xxxxxxxxxxxxxxxx"
let client = APIClient(key: apiKey)
✅ 良い例(Bundle.main.infoDictionary経由で取得する例):
import Foundation
guard let apiKey = Bundle.main.infoDictionary?["API_KEY"] as? String, !apiKey.isEmpty else {
// 本番ビルドではビルド設定(xcconfig等)から注入する
// デバッグ時はスキームの環境変数で設定する
preconditionFailure("API_KEY is not configured in build settings")
}
let client = APIClient(key: apiKey)
📋 チェックリスト:
- ソースコード内にAPIキー・トークンが直書きされていないか
-
.envファイルが.gitignoreに含まれているか -
.env.example(値なしテンプレート)をリポジトリに用意しているか - プロンプトにシークレットの実値を含めていないか(環境変数名で指示しているか)
⚠️ 2. CLAUDE.mdへのシークレット混入
CLAUDE.mdはGitで管理されるファイルであり、プロジェクトのルートに配置してAIへの指示を記述する。ここにDBパスワードや内部APIのエンドポイントを書くと、リポジトリ経由で第三者に漏洩する。CLAUDE.mdは指示ファイルであり、シークレットの保管場所ではない。
バイブコーディングでは「AIに正確な情報を伝えたい」という動機から、接続情報をCLAUDE.mdに直書きしてしまうケースが特に多い。手動コーディングなら設定ファイルに書く内容を、バイブコーディングではAIへの指示書に書いてしまうという構造的な罠がある。
❌ 悪い例:
<!-- CLAUDE.md に以下を記載 -->
DBパスワードは「prod_Pass!789」を使用すること
本番APIは https://internal-api.company.com/v2
✅ 良い例:
<!-- CLAUDE.md に以下を記載 -->
DB接続情報は環境変数 DATABASE_URL から取得すること
API エンドポイントは .env の API_BASE_URL を参照すること
シークレットをソースコードにハードコードしてはならない
📋 チェックリスト:
- CLAUDE.mdにパスワード・トークン・内部URLが含まれていないか
- シークレットは環境変数名のみ記載し、実値を書いていないか
- CLAUDE.mdをコミットする前にdiffを目視確認しているか
⚠️ 3. 依存パッケージのサプライチェーン攻撃
AIは指示に応じて外部パッケージを自動追加する。ここには2つの脅威がある。
1つ目は typosquatting(タイポスクワッティング)である。正規パッケージに酷似した名前の悪意あるパッケージを登録し、タイプミスを狙う攻撃である。
2つ目は slopsquatting(スロップスクワッティング)である。これはバイブコーディング特有のリスクで、AIが実在しないパッケージ名を幻覚(ハルシネーション)し、攻撃者がその名前で悪意あるパッケージを事前に登録しておく攻撃である。2025年のUSENIX Securityの研究では、16モデル・576,000コードサンプルの調査で、AIが幻覚したパッケージ名の58%以上が複数回の実行で再出現し、43%が同一プロンプトの10回の試行で一貫して出現したと報告されている。この予測可能性が攻撃を実行可能にしている。
手動コーディングなら開発者がパッケージを自分で検索して選ぶが、バイブコーディングではAIが提案したパッケージ名をそのまま受け入れてしまいやすい。AIの提案を無条件に信頼せず、パッケージ追加前に必ずレジストリで実在と正当性を確認すること。
❌ 悪い例:
# AIが提案したパッケージをそのまま追加
swift package add SwiftCrytpoUtils
# → 正規の「CryptoKit」ではなく、typoした偽パッケージ
# → またはAIが幻覚した実在しないパッケージ名
✅ 良い例:
# パッケージ追加前に公式リポジトリとスター数を確認
# 公式: https://github.com/apple/swift-crypto
swift package add swift-crypto --from 3.0.0
📋 チェックリスト:
- AIが追加したパッケージの名前とリポジトリURLを確認したか
- パッケージがレジストリに実在し、正規のものであることを確認したか(AIが幻覚した偽パッケージへの対策)
- パッケージのスター数・最終更新日・メンテナンス状況を確認したか
- バージョンを固定(ピン留め)しているか
⚠️ 4. AIコードのレビューなしリリース
バイブコーディングの速さに慣れると、AIが生成したコードをレビューせずにリリースしがちである。SQL組み立てやユーザー入力の処理に脆弱性が潜む可能性がある。
AIが大量のコードを短時間で生成するため、diffが膨大になりレビューが追いつかないという構造的な問題がある。手動コーディングなら自分が書いたコードなので内容を把握しているが、バイブコーディングでは自分が書いていないコードが大量にコミットされる。だからこそ、セキュリティ関連箇所に絞った重点レビューが不可欠である。
❌ 悪い例(SQLite.swift使用時):
import SQLite
// AIが生成したコードをそのままリリース
// → SQLインジェクションの脆弱性
let query = "SELECT * FROM users WHERE name = '\(userInput)'"
✅ 良い例(SQLite.swift使用時):
import SQLite
// パラメータバインディングでSQLインジェクションを防止
let users = Table("users")
let name = SQLite.Expression<String>("name")
let result = try db.prepare(users.filter(name == userInput))
📋 チェックリスト:
- ユーザー入力を直接クエリやコマンドに埋め込んでいないか
- セキュリティ関連箇所(認証・暗号化・入力検証・権限設定)を中心にdiffを確認してからコミットしているか
- 認証・暗号化・入力検証の変更に対し、意図した動作であることを確認したか
上級編:そもそもローカルにシークレットを置かない
ここまでの対策は「.envをGitに載せない」「Claude Codeに読ませない」といった守りのアプローチである。しかし根本的な問題は、ローカルPCに本物のシークレットが存在していること自体にある。
Claude Codeは .env を読める。パーミッション設定やHooksで「読ませない」制御はできるが、それは鍵のかかったドアの向こうに金庫があるのと同じである。設定ミス、Claude Codeのアップデートによる挙動変化、あるいは悪意あるnpmパッケージが fs.readFile('.env') を実行するなど、突破されるシナリオは常に存在する。
根本解決は、ローカルにシークレットを置かないことである。金庫そのものが存在しなければ、ドアの鍵が壊れても何も盗まれない。
考え方:ローカル=モック、クラウド=実通信
【ローカル(開発者のPC)】
├── シークレット → 存在しない
├── 外部API通信 → モック(固定データを返す)
└── やること → UI開発、ロジックのテスト
【クラウド(AWS ECS / Cloud Run 等)】
├── シークレット → Secrets Managerから自動取得
├── 外部API通信 → 本物のAPIと通信
└── やること → 結合テスト、本番運用
ローカルではAPIの「フリをする」だけである。本物のシークレットはクラウドにしか存在せず、開発者のPCには一度も保存されない。
なぜ .env すら危険なのか
.gitignore に .env を入れていても、以下のリスクは残る。
| リスク | 具体例 |
|---|---|
| 悪意あるパッケージが読む | npm/pipの偽パッケージが .env のパスを直接読み取って外部に送信する事例がある |
| PC紛失・盗難 | ディスクにアクセスすれば .env の中身は平文で読める |
| Claude Codeが読む | AIがデバッグ目的で .env を参照し、その内容をログやコードに出力してしまう |
| 誤操作 |
.gitignore の記述ミスや git add -A で .env ごとコミットしてしまう |
実装方法:プロトコル(インターフェース)でモックと本番を切り替える
外部APIとの通信層をプロトコルで抽象化し、ローカルではモック実装、本番では実API実装を使う設計にする。
import Foundation
// 通信層のプロトコル(インターフェース)
protocol WeatherService {
func fetchForecast(city: String) async throws -> Forecast
}
struct Forecast {
let temperature: Double
let condition: String
}
モック実装(ローカル開発用):シークレット不要
// ローカル開発ではこちらを使う
// APIキーは一切不要。固定データを返すだけ
final class MockWeatherService: WeatherService {
func fetchForecast(city: String) async throws -> Forecast {
// ローカルのJSONやハードコードした固定値を返す
return Forecast(temperature: 25.0, condition: "晴れ")
}
}
本番実装(クラウド環境用):Secrets Managerからキーを取得
import Foundation
// 本番・ステージング環境ではこちらを使う
// シークレットは環境変数から取得(ECSが起動時にSecrets Managerから注入)
final class RealWeatherService: WeatherService {
func fetchForecast(city: String) async throws -> Forecast {
guard let apiKey = ProcessInfo.processInfo.environment["WEATHER_API_KEY"] else {
throw ServiceError.missingAPIKey
}
let url = URL(string: "https://api.weather.com/v1/forecast?city=\(city)")!
var request = URLRequest(url: url)
request.setValue(apiKey, forHTTPHeaderField: "X-API-Key")
let (data, _) = try await URLSession.shared.data(for: request)
return try JSONDecoder().decode(Forecast.self, from: data)
}
}
切り替え:ビルド設定や環境変数で判定
// 環境に応じて実装を切り替える
func createWeatherService() -> WeatherService {
#if DEBUG
return MockWeatherService()
#else
return RealWeatherService()
#endif
}
この設計なら、ローカルの DEBUG ビルドでは MockWeatherService が使われるため、APIキーがPCに存在する必要がない。
クラウド側のシークレット管理:AWS Secrets Manager
本番環境ではシークレットをどこに保管するか。AWSの場合、Secrets Managerが標準的な選択肢である。
| サービス | 役割 | コスト目安 |
|---|---|---|
| Secrets Manager | シークレットを暗号化して保管。自動ローテーション対応 | $0.40/シークレット/月 |
| Parameter Store | 設定値の一元管理。シークレットにも対応。Secrets Managerより安価 | 標準パラメータは無料 |
| ECS | コンテナを実行するサービス。起動時にSecrets Managerからシークレットを環境変数に注入 | コンテナ利用分 |
設定の流れ(AWS ECS + Secrets Manager):
# 1. Secrets Managerにシークレットを登録(管理者が1回だけ実行)
aws secretsmanager create-secret \
--name "myapp/weather-api-key" \
--secret-string "sk-xxxxxxxxxxxxxxxx"
// 2. ECSタスク定義でSecrets Managerを参照
{
"containerDefinitions": [
{
"name": "myapp",
"secrets": [
{
"name": "WEATHER_API_KEY",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789:secret:myapp/weather-api-key"
}
]
}
]
}
// 3. アプリ側のコードは環境変数から読むだけ(従来と同じ)
let apiKey = ProcessInfo.processInfo.environment["WEATHER_API_KEY"]
開発者はSecrets Managerの登録権限だけ持ち、シークレットの実値を自分のPCにダウンロードする必要がない。ECSが起動時に自動で取得し、コンテナの環境変数に注入する。
バイブコーディングとの相性
この設計がバイブコーディングと特に相性が良い理由は、プロンプトにシークレットを書く必要が完全になくなることである。
❌ 従来のプロンプト(シークレットを含む):
天気予報機能を実装して。
APIキーは sk-xxxxxxxxxxxxxxxx を使って。
✅ モック方式のプロンプト(シークレットを含まない):
天気予報機能を実装して。
WeatherServiceプロトコルに準拠し、ローカルではモック実装、
本番ではRealWeatherServiceに差し替える設計にして。
モックは固定データ(気温25度、晴れ)を返すようにして。
AIにシークレットの実値を渡さないので、AIが何をしても漏洩しない。コードにベタ書きされる心配も、プロンプト履歴から漏れる心配もない。これがバイブコーディングにおける最も根本的なセキュリティ対策である。
いつモック方式を採用すべきか
| 判断基準 | モック方式を推奨 |
.env方式で十分 |
|---|---|---|
| チーム規模 | 複数人開発 | 個人の趣味開発 |
| 扱うシークレット | 課金API、決済、認証 | 公開APIのみ |
| 環境 | 本番サービスがある | ローカルで完結 |
| バイブコーディング | 積極的に使用 | 部分的に使用 |
個人開発でも「課金が発生するAPIキー」や「ユーザーデータにアクセスできる認証キー」を扱う場合は、モック方式の導入を強く推奨する。
📋 チェックリスト:
- 外部APIとの通信層をプロトコル(インターフェース)で抽象化しているか
- ローカル開発用のモック実装を用意しているか
- 本番のシークレットはSecrets Manager等のクラウドサービスで管理しているか
- プロンプトにシークレットの実値を含めずに開発できる設計になっているか
チーム開発編:セキュリティチェックリスト
個人開発編の項目はチーム開発でもすべて適用される。チーム開発編はそれに加えて、組織的に対応すべき項目を記載している。チーム開発では個人開発編のチェックリストも併せて運用すること。
⚠️ 1. 最小権限の原則の崩壊
AIに「このエラーを直して」と指示すると、権限設定を緩和する方向で解決しようとする場合がある。IAMポリシーやファイル権限を過剰に開放すると、攻撃対象面が広がる。
バイブコーディングでは、AIが「とにかく動かす」ことを最優先にするため、権限を最大に開放する解決策を提示しやすい。手動コーディングなら権限エラーの原因を調べて最小限の変更で対応するが、AIは最も単純な(=最も危険な)方法を選びがちである。
被害例:chmod 777にした設定ファイルから認証情報を抜き取られた事例がある。同一サーバー上の他ユーザーやプロセスから読み取り可能になるため、多層防御が崩壊する。
❌ 悪い例:
# AIが提案した「動く」修正
chmod 777 /var/app/config
# → 全ユーザーに読み書き実行を許可
✅ 良い例:
# 必要最小限の権限のみ付与
chmod 640 /var/app/config
chown appuser:appgroup /var/app/config
📋 チェックリスト:
- AIが変更した権限設定(IAM・ファイル・DB)をレビューしたか
-
chmod 777や*ワイルドカード権限が含まれていないか - 本番環境の権限変更にはダブルチェック体制があるか
⚠️ 2. CI/CDへのシークレット漏洩
AIにCI/CDの設定ファイルを書かせると、動作を優先してシークレットをYAMLに直書きしたり、デバッグ用にログに出力するステップを生成することがある。CI/CDのログは開発メンバー全員が閲覧できるため、漏洩の影響範囲が広い。
バイブコーディングでは「GitHub Actionsのワークフローを書いて」と指示するだけでCI/CD設定が生成されるため、シークレット管理の設計を飛ばしてしまいやすい。手動で書くならSecrets設定を調べるところから始めるが、AIは手っ取り早くベタ書きする傾向がある。
❌ 悪い例:
# GitHub Actions のワークフロー
env:
API_KEY: sk-ant-api03-xxxxxxxxxxxxxxxx
DB_PASSWORD: prod_password_123
✅ 良い例:
# GitHub Secrets を参照
env:
API_KEY: ${{ secrets.API_KEY }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
📋 チェックリスト:
- CI/CD設定ファイルにシークレットが直書きされていないか
- GitHub Secrets等のシークレット管理機能を使用しているか
- ビルドログにシークレットが出力されない設定になっているか
⚠️ 3. プロンプト履歴・ログからの情報漏洩
Claude Codeのセッション履歴やプロンプトログには、コードベースの構造・ビジネスロジック・データベース設計といった機密性の高い情報が含まれる。共有端末やスクリーンキャストでこれらが第三者に見られるリスクがある。
セッション履歴は~/.claude/配下に保存されるためリポジトリには通常含まれないが、共有端末では定期的にセッションデータを削除すること。リポジトリ内で管理すべきでないファイルとしては.claude/settings.local.json(個人設定)がある。
❌ 悪い例:
# 個人設定ファイルを共有リポジトリにコミット
git add .claude/settings.local.json
git commit -m "Claude Codeの設定を共有"
✅ 良い例:
# .gitignore で個人設定を除外
echo ".claude/settings.local.json" >> .gitignore
# 共有するのはチーム共通の設定のみ
git add .claude/settings.json
📋 チェックリスト:
-
.claude/settings.local.jsonが.gitignoreに含まれているか -
共有端末のセッションデータ(
~/.claude/配下)を定期削除しているか - 画面共有・録画時にプロンプト履歴が映り込まない運用があるか
- 退職者のセッションデータ削除手順が定められているか
⚠️ 4. レビュープロセスの形骸化
AIが大量のコードを短時間で生成するため、レビュアーが「AIが書いたなら大丈夫だろう」と流してしまう心理が働きやすい。特にバイブコーディングでは生成量が多く、差分が膨大になるため、レビューの質が低下しやすい。
手動コーディングのPRなら差分が数十行〜数百行で済むことが多いが、バイブコーディングでは一度の指示で数百〜数千行の差分が生まれることがある。これに対して「全行レビュー」は非現実的であり、セキュリティ関連箇所への重点レビューとツールによる自動チェックの併用が不可欠である。
❌ 悪い例:
<!-- PRの説明 -->
Claude Codeで生成。テスト通過済み。LGTM
<!-- → セキュリティ観点のレビューがゼロ -->
✅ 良い例:
<!-- PRテンプレートにセキュリティチェック項目を必須化 -->
## セキュリティレビュー
- [ ] 認証・認可の変更はないか
- [ ] ユーザー入力の検証は適切か
- [ ] 新規パッケージのセキュリティ確認済みか
- [ ] AI生成コードであることを明示しているか
📋 チェックリスト:
- PRテンプレートにセキュリティチェック項目が含まれているか
- AI生成コードであることを明示するラベル運用があるか
- 認証・暗号化・入力検証の変更に対し、レビューコメントを残したか
- セキュリティ関連の変更は専任レビュアーを必須にしているか
Claude Codeのセキュリティ機能を活用する
Claude Code自体に備わっているセキュリティ機能を適切に設定することで、バイブコーディングの安全性を大幅に高められる。
サンドボックス
サンドボックスはBashコマンドのファイルシステムアクセスとネットワークアクセスをOS レベルで制限する機能である。macOSではSeatbelt、LinuxではBubblewrapを利用して強制される。
Claude Code上で/sandboxコマンドを実行すると有効化できる。
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["~/.kube", "/tmp/build"]
}
}
}
-
ファイルシステム隔離:デフォルトではカレントディレクトリとそのサブディレクトリにのみ書き込みが許可される。
sandbox.filesystem.allowWriteで追加パスを指定可能 - ネットワーク隔離:許可されたドメインのみにアクセスが制限される。未許可ドメインへのアクセスはブロックされ、通知が表示される
- プロンプトインジェクション対策:サンドボックス内のプロセスはOS レベルで制限されるため、仮にAIの判断が操作されても、システムファイルの改ざんやデータの外部送信を防止できる
パーミッションモード
Claude Codeには複数のパーミッションモードがあり、プロジェクトの性質に応じて使い分ける。
| モード | 説明 | 推奨場面 |
|---|---|---|
default |
ツールの初回使用時に許可を求める | 通常の開発 |
plan |
分析のみ。ファイル変更やコマンド実行は不可 | コードレビュー・調査 |
acceptEdits |
ファイル編集を自動許可。コマンドは許可を求める | 信頼できるプロジェクト |
dontAsk |
事前許可されたツールのみ自動実行。それ以外は拒否 | CI/CD環境・厳格な制限 |
チーム開発では、管理者設定(managed settings)を使い、全権限をスキップするモード(bypassPermissions)を無効化することを推奨する。
{
"permissions": {
"disableBypassPermissionsMode": "disable"
}
}
Hooks(コマンド実行前の自動チェック)
Hooksは、Claude Codeの操作の前後に自動実行されるカスタムスクリプトである。コマンド実行前に動作する「PreToolUse」フックを使えば、危険なコマンドのブロックやシークレットの検出を自動化できる。
シークレット検出フックの例(.claude/hooks/detect-secrets.sh):
#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
# コマンド内のシークレットパターンを検出
if echo "$COMMAND" | grep -qE '(password|token|api.?key|secret).*='; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Potential secret detected in command"
}
}'
exit 0
fi
exit 0
設定例(.claude/settings.json):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/detect-secrets.sh"
}
]
}
]
}
}
このフックにより、Bashコマンド実行前にシークレットのパターンが検出された場合、自動的にブロックされる。
推奨ツール
チェックリストの「毎コミット」の負荷を軽減するため、以下の自動化ツールの導入を推奨する。人間のレビューは必須だが、機械的に検出可能な問題はツールに任せるべきである。
シークレットスキャン(pre-commitフック)
| ツール | 概要 |
|---|---|
| gitleaks | Git履歴を含むシークレットスキャン。pre-commitフックとして導入可能 |
| trufflehog | 高精度なシークレット検出。600以上のパターンに対応 |
静的解析(CI連携)
| ツール | 概要 |
|---|---|
| Semgrep | 軽量な静的解析。SQLインジェクション等のパターンを検出 |
| CodeQL | GitHubネイティブの静的解析。PRに自動コメント |
依存関係の脆弱性チェック
| ツール | 概要 |
|---|---|
| Dependabot | GitHubネイティブ。脆弱な依存関係を検出しPRを自動作成 |
| osv-scanner | Googleが開発。OSVデータベースと照合して脆弱性を検出 |
gitleaksをpre-commitフックとして導入するだけでも、シークレットの誤コミットを大幅に削減できる。
シークレット漏洩時の緊急対応
万が一シークレットがリポジトリにコミットされた場合、以下のフローで対応する。git履歴から削除しても、pushした時点でシークレットは漏洩したとみなすこと。
対応フロー
- 即時無効化:漏洩したシークレット(APIキー・トークン・パスワード)をプロバイダの管理画面から即座に無効化・ローテーションする
- 影響範囲の調査:漏洩したシークレットで何が実行可能だったかを特定する。ログを確認し、不正利用の痕跡がないか調査する
- 新しいシークレットの発行:新しいキーを発行し、環境変数やシークレット管理サービスに安全に設定する
- 原因の特定と再発防止:なぜ漏洩が起きたかを特定し、pre-commitフック(gitleaks等)の導入やCLAUDE.mdへのルール追記など、再発防止策を実施する
- 報告:チーム開発の場合、セキュリティ担当者・テックリードに報告する。影響範囲に応じて顧客やユーザーへの通知が必要な場合もある
重要な注意点
-
git rebaseやgit filter-branchで履歴からシークレットを削除しても、GitHub等ではキャッシュが残る可能性がある。シークレットの削除ではなく、無効化が最優先である - GitHub Secret Scanningが有効な場合、パートナーパターンに該当するシークレットは自動的にプロバイダに通知される
まとめ:全項目チェックリスト(コピペ用)
以下のチェックリストをそのままプロジェクトに貼り付けて使用できる。
個人開発チェックリスト
シークレット管理
- ソースコード内にAPIキー・トークンが直書きされていないか(担当:自分 / 頻度:毎コミット ※gitleaks等で自動化推奨)
-
.envファイルが.gitignoreに含まれているか(担当:自分 / 頻度:プロジェクト開始時) -
.env.example(値なしテンプレート)をリポジトリに用意しているか(担当:自分 / 頻度:プロジェクト開始時) - プロンプトにシークレットの実値を含めていないか(担当:自分 / 頻度:毎プロンプト)
CLAUDE.md
- CLAUDE.mdにパスワード・内部URL等のシークレットが含まれていないか(担当:自分 / 頻度:毎コミット)
- シークレットは環境変数名のみ記載し実値を書いていないか(担当:自分 / 頻度:毎コミット)
サプライチェーン
- AIが追加したパッケージの名前・リポジトリURL・更新日を確認したか(担当:自分 / 頻度:パッケージ追加時)
- パッケージがレジストリに実在し正規のものか確認したか(担当:自分 / 頻度:パッケージ追加時)
- パッケージバージョンをピン留めしているか(担当:自分 / 頻度:パッケージ追加時)
コードレビュー
- セキュリティ関連箇所(認証・暗号化・入力検証・権限設定)を中心にdiffを確認してからコミットしているか(担当:自分 / 頻度:毎コミット)
- ユーザー入力を直接クエリやコマンドに埋め込んでいないか(担当:自分 / 頻度:毎コミット)
上級:ローカルにシークレットを置かない設計
- 外部APIとの通信層をプロトコルで抽象化しているか(担当:自分 / 頻度:設計時)
- ローカル開発用のモック実装を用意しているか(担当:自分 / 頻度:設計時)
- 本番のシークレットはSecrets Manager等で管理しているか(担当:自分 / 頻度:プロジェクト開始時)
- プロンプトにシークレットの実値を含めずに開発できる設計になっているか(担当:自分 / 頻度:毎プロンプト)
Claude Code設定
- サンドボックスを有効化しているか(担当:自分 / 頻度:プロジェクト開始時)
- パーミッションモードをプロジェクトの性質に合わせて設定しているか(担当:自分 / 頻度:プロジェクト開始時)
チーム開発チェックリスト
個人開発チェックリストの全項目に加えて、以下を確認すること。
権限管理
- AIが変更した権限設定(IAM・ファイル・DB)をレビューしたか(担当:レビュアー / 頻度:PR作成時)
-
chmod 777やワイルドカード権限が含まれていないか(担当:レビュアー / 頻度:PR作成時) - 本番環境の権限変更にはダブルチェック体制があるか(担当:テックリード / 頻度:PR作成時)
CI/CD
- CI/CD設定ファイルにシークレットが直書きされていないか(担当:レビュアー / 頻度:PR作成時)
- GitHub Secrets等のシークレット管理機能を使用しているか(担当:インフラ担当 / 頻度:CI/CD変更時)
- ビルドログにシークレットが出力されない設定になっているか(担当:インフラ担当 / 頻度:CI/CD変更時)
情報管理
-
.claude/settings.local.jsonが.gitignoreに含まれているか(担当:テックリード / 頻度:プロジェクト開始時) - 共有端末のセッションデータを定期削除しているか(担当:テックリード / 頻度:四半期)
- 画面共有・録画時にプロンプト履歴が映り込まない運用があるか(担当:テックリード / 頻度:四半期)
- 退職者のセッションデータ削除手順が定められているか(担当:テックリード / 頻度:発生時)
レビュープロセス
- PRテンプレートにセキュリティチェック項目が含まれているか(担当:テックリード / 頻度:プロジェクト開始時)
- AI生成コードであることを明示するラベル運用があるか(担当:テックリード / 頻度:プロジェクト開始時)
- 認証・暗号化・入力検証の変更に対し、レビューコメントを残したか(担当:レビュアー / 頻度:PR作成時)
- セキュリティ関連の変更は専任レビュアーを必須にしているか(担当:テックリード / 頻度:PR作成時)
Claude Code設定(チーム共通)
- Claude Codeの権限バイパス(bypassPermissions)を管理者設定で禁止しているか(担当:テックリード / 頻度:プロジェクト開始時)
- Claude CodeのHooks機能でシークレットの自動検出を設定しているか(担当:テックリード / 頻度:プロジェクト開始時)
- gitleaks等のシークレットスキャンをpre-commitフックに導入しているか(担当:テックリード / 頻度:プロジェクト開始時)
おわりに
バイブコーディングは開発速度を劇的に向上させる強力な手法である。しかし、AIが生成するコードは人間が書くコードと同様に、あるいはそれ以上にセキュリティレビューが必要である。AIが大量のコードを高速に生成するからこそ、人間によるセキュリティの防壁が重要になる。
このチェックリストを社内に展開する際は「バイブコーディングを禁止するためのルールではなく、安全に活用するためのガイドラインである」と一言添えると、チームの抵抗感なく導入できるはずである。たとえば、以下のようなメッセージと共にチームに共有するとよいだろう。
「Claude Code等のAIエージェントを使ったバイブコーディングは推奨しています。ただし、AIが生成するコードにもセキュリティリスクがある以上、チェックリストに沿った確認を習慣化しましょう。このガイドラインはAI活用を制限するものではなく、安全に最大限活用するためのものです。」
セキュリティは一度設定して終わりではなく、継続的に改善していくものである。まずはgitleaksの導入とサンドボックスの有効化から始めてみてほしい。
参考
- Claude Code Security - Anthropic
- Claude Code Settings - Anthropic
- Claude Code Sandboxing - Anthropic
- Claude Code Permissions - Anthropic
- Claude Code Hooks - Anthropic
- Best Practices for Claude Code - Anthropic
- OWASP Top 10 for LLM Applications 2025
- gitleaks - GitHub
- Semgrep
- AWS Secrets Manager - AWS
- ECS でのシークレット管理 - AWS
@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!