Secret Scanning(シークレット/機密情報漏洩スキャン)ガイド
1. はじめに
開発中にうっかりAPIキーやトークンをコミットしてしまった経験はありませんか?GitHubのSecret Scanningは、そうした機密情報の漏洩を防ぎ、検出するための強力なセキュリティ機能です。
本記事では、Secret Scanningの仕組みから実践的な活用方法まで、技術者の視点で詳しく解説します。
2. Secret Scanningとは
Secret Scanningは、リポジトリ内のAPIキー、トークン、認証情報などの機密情報を自動的に検出するセキュリティ機能です。単なる事後検出だけでなく、プッシュ前のブロック機能も備えており、予防と検出の両面から機密情報を保護します。
2.1. 利用可能な環境
- パブリックリポジトリ:GitHub.com上で無料で利用可能
- プライベートリポジトリ:GitHub Secret Protectionが有効な組織所有リポジトリ(GitHub Team以上)
3. Secret Scanningの動作フロー
Secret Scanningは以下のような流れで動作します。
4. 主要機能の詳細
4.1. 検出範囲の広さ
Secret Scanningは以下の範囲を網羅的にスキャンします。
4.1.1. Git履歴
- すべてのブランチの完全なコミット履歴
- アーカイブされたリポジトリも対象
4.1.2. GitHub上のコンテンツ
- Issuesのタイトル、説明、コメント
- Pull Requestsのタイトル、説明、コメント
- GitHub Discussionsのタイトル、本文、コメント
- Wikiページ
- Secret Gist(URLを知っていれば誰でもアクセス可能なため)
この広範囲なスキャンにより、コード以外の場所に記載された機密情報も漏らさず検出できます。
4.2. Push Protection:予防的セキュリティ
Push Protectionは、機密情報を含むコミットをプッシュ前にブロックする機能です。
4.2.1. 対応環境
- コマンドライン(Git CLI)
- GitHub Web UI
- REST API
- GitHub MCP server(パブリックリポジトリのみ)
4.2.2. ブロック時の対応オプション
プッシュがブロックされた場合、以下の選択肢があります。
4.2.3. バイパス時の挙動
- アラートがSecurityタブに作成される
- 監査ログに記録される
- 組織オーナー、セキュリティマネージャー、リポジトリ管理者にメール通知
- GitHubトークンの場合は自動的に無効化される(パブリックリポジトリ)
4.3. アラートの種類
Secret Scanningは3種類のアラートを生成します。
| アラートタイプ | 通知先 | 用途 |
|---|---|---|
| User alerts | リポジトリのSecurityタブ | サポートされる機密情報とカスタムパターンの検出 |
| Push protection alerts | リポジトリのSecurityタブ | バイパス時の記録 |
| Partner alerts | サービスプロバイダーに直接 | パートナープログラム参加企業への通知 |
4.3.1. User alertsとGeneric alertsの区別
アラートは精度に応じて2つのリストに分類されます。
Default alerts(デフォルトアラートリスト)
- サポートされるパターンとカスタムパターン
- 誤検出率が低い
- メインの表示リスト
Generic alerts(汎用アラートリスト)
- 非プロバイダーパターン(秘密鍵など)
- AIで検出された汎用シークレット(パスワードなど)
- 誤検出率がやや高い可能性
- 別リストで表示され、より慎重なトリアージが必要
- リポジトリあたり最大5,000件まで
4.4. Validity Checks:有効性の検証
検出された機密情報が現在も有効かどうかを確認する機能です。
4.4.1. ステータスの種類
| ステータス | 意味 | 対応優先度 |
|---|---|---|
active |
有効な機密情報 | 高:即座に対応が必要 |
inactive |
無効化済み | 中:不正利用の有無を確認 |
unknown |
検証不可 | 中:手動確認が必要 |
4.4.2. 対応パートナー
GitHubは各サービスプロバイダーと連携し、トークンの有効性を確認します。検証時にトークンがプロバイダーに送信されますが、最小限の侵襲的なGETリクエストを使用し、個人情報は取得しません。
4.4.3. オンデマンド検証
アラート画面の「Verify secret」ボタンから、必要な時に手動で検証を実行できます。
4.5. Extended Metadata:拡張メタデータ
特定のトークンタイプについて、詳細な情報を表示する機能です(現在パブリックプレビュー)。
4.5.1. 表示される情報
| メタデータ | 説明 |
|---|---|
| Owner ID | プロバイダーの一意識別子 |
| Owner name | 所有者のユーザー名 |
| Owner email | 所有者のメールアドレス |
| Org name | 組織/ワークスペース/プロジェクト名 |
| Secret issued date | 発行日時 |
| Secret expiry date | 有効期限 |
| Secret name | 表示名 |
4.5.2. 対応トークン
現在、以下のトークンで利用可能です。
- OpenAI API
- Google OAuth
- Slack tokens
このメタデータにより、「誰が」「どの組織で」作成したトークンなのかが即座に把握でき、インシデントレスポンスが大幅に効率化されます。
5. 高度な機能
5.1. Delegated Bypass:委任型バイパス
Push Protectionのバイパスに承認プロセスを導入する機能です。
5.1.1. 仕組み
5.1.2. バイパス権限を持つユーザー
- 組織オーナー
- セキュリティマネージャー
- バイパスリストに追加されたチーム・ロール
- 「review and manage secret scanning bypass requests」権限を持つカスタムロール
5.1.3. 設定方法
リポジトリレベル
# Settings > Security > Advanced Security > Push Protection
# "Who can bypass push protection" で設定
bypass_list:
- role: security_team
- team: infrastructure
組織レベル
カスタムセキュリティ構成を使用して設定します。
# Custom Security Configuration
push_protection: enabled
bypass_privileges: specific_actors
actors:
- security_team
- senior_engineers
5.1.4. リクエストの有効期限
バイパスリクエストは7日間で自動的に期限切れとなります。
5.2. Custom Patterns:カスタムパターン
組織固有の機密情報パターンを定義できる機能です。
5.2.1. 定義範囲
- リポジトリレベル:最大100パターン
- 組織レベル:最大500パターン
- エンタープライズレベル:最大500パターン
5.2.2. 正規表現の構成要素
| フィールド | 説明 | デフォルト値 |
|---|---|---|
| Secret format | 機密情報自体のパターン | - |
| Before secret | 直前の文字パターン | `\A |
| After secret | 直後の文字パターン | `\z |
| Additional match requirements | 追加のマッチング条件 | - |
5.2.3. サンプル:社内トークンの定義
要件:
- 長さ5〜10文字
- ピリオドで終わらない
- 数字と大文字を含む
- 小文字の連続は1文字まで
-
$%@!のいずれかを含む
# Custom Pattern Example
pattern_name: "社内APIトークン"
secret_format: "[$#%@AA-Za-z0-9]{5,10}"
before_secret: "\\A|[^0-9A-Za-z]"
after_secret: "[^\\.]"
additional_requirements:
must_match:
- "[A-Z]" # 大文字を含む
- "[0-9]" # 数字を含む
- "[$%@!]" # 特殊文字を含む
must_not_match:
- "[a-z]{2,}" # 小文字の連続なし
マッチする例:
a9@AAfT!-
ee95GG@ZA942@aa(マッチ部分:@ZA942@a) a9@AA!ee9
マッチしない例:
-
a9@AA.!(ピリオドで終わる) -
a@AAAAA(特殊文字がない) -
aa9@AA!ee9(小文字が連続)
5.2.4. Dry Run機能
本番適用前に、最大1,000件のサンプル結果をプレビューできます。
5.3. Copilot Secret Scanning:AI活用機能
GitHub Copilotの技術を活用した2つの機能があります(GitHub Copilot購読不要)。
5.3.1. 汎用シークレット検出
構造化されていないパスワードなどをAIで検出します。
特徴
- LLM(大規模言語モデル)を使用
- パスワードパターンを学習ベースで検出
- Generic alertsリストに表示
- プッシュあたり最大100件を検出
制限事項
- 明らかに偽物やテスト用のパスワードは検出しない
- エントロピーが低いパスワードは検出しない
- ファイルあたり5件以上が誤検出とマークされたら、そのファイルは対象外
- 生成ファイルやベンダーファイルは対象外
- 暗号化ファイルは対象外
- SVG、PNG、JPEG、CSV、TXT、SQL、ITEMファイルは対象外
- テストコード(特定の条件下)は対象外
有効化方法
# Repository Settings > Advanced Security > Secret Protection
scan_for_generic_passwords: enabled
組織レベルではカスタムセキュリティ構成で設定します。
5.3.2. 正規表現ジェネレーター
自然言語から正規表現を生成するAI機能です。
使用方法
- カスタムパターン作成画面で「Generate with AI」をクリック
- 日本語(または英語)で検出したいパターンを説明
- サンプル文字列を入力(任意)
- 最大3つの正規表現候補が生成される
- 各候補をクリックすると平易な説明が表示される
- 適切な候補を選択して使用
入力例
説明:
SHA-256ハッシュ値を検出したい。
16進数64文字で、"hash:"という接頭辞が付いている。
サンプル:
hash:a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1
注意点
- 英語での説明が最も高精度
- 構造化されたパターンに適している
- 生成結果は必ずDry Runで検証する
- 必要に応じて手動調整を行う
5.4. Non-Provider Patterns:非プロバイダーパターン
特定のサービスプロバイダーに紐づかない機密情報を検出します。
5.4.1. 検出対象
| パターン | 説明 | 精度 |
|---|---|---|
| ec_private_key | 楕円曲線秘密鍵 | 高 |
| generic_private_key | 汎用秘密鍵 | 高 |
| http_basic_authentication_header | Basic認証ヘッダー | 中 |
| http_bearer_authentication_header | Bearerトークン | 中 |
| mongodb_connection_string | MongoDB接続文字列 | 高 |
| mysql_connection_string | MySQL接続文字列 | 高 |
| openssh_private_key | OpenSSH秘密鍵 | 高 |
| pgp_private_key | PGP秘密鍵 | 高 |
| postgres_connection_string | PostgreSQL接続文字列 | 高 |
| rsa_private_key | RSA秘密鍵 | 高 |
注:非プロバイダーパターンはValidity Checksに対応していません。
5.4.2. 有効化方法
# Repository Settings > Advanced Security > Secret Protection
non_provider_patterns: enabled
5.5. Delegated Alert Dismissal:委任型アラート却下
アラートの却下に承認プロセスを導入する機能です。
5.5.1. 仕組み
5.5.2. 却下権限を持つユーザー
- 組織オーナー
- セキュリティマネージャー
- 「Review and manage secret scanning alert dismissal requests」権限を持つカスタムロール
5.5.3. 設定方法
カスタムセキュリティ構成で設定します。
# Custom Security Configuration
secret_scanning:
enabled: true
prevent_direct_alert_dismissals: enabled
5.6. ファイル・フォルダーの除外
誤検出を減らすため、特定のディレクトリやファイルをスキャン対象外にできます。
5.6.1. 設定ファイル
リポジトリルートに .github/secret_scanning.yml を作成します。
# .github/secret_scanning.yml
# ドキュメントディレクトリ全体を除外
paths-ignore:
- "docs/**"
- "examples/**"
# 特定のファイルパターンを除外
- "test/fixtures/*.json"
- "config/samples/*.yml"
# JavaScriptのテストファイルを除外
- "foo/bar/*.js"
5.6.2. 制限事項
- 最大1,000エントリーまで
- ファイルサイズが1MBを超える場合は無視される
5.6.3. ベストプラクティス
# .github/secret_scanning.yml
# 除外理由をコメントで明記
paths-ignore:
# ドキュメント用のサンプルAPIキー
- "docs/api-examples/**"
# モックデータ(有効な認証情報は含まない)
- "tests/mocks/**"
# 外部ライブラリ(管理対象外)
- "vendor/**"
- "node_modules/**"
- 除外は最小限に
- 理由をコメントで記載
- 定期的に見直しを実施
- セキュリティチームと共有
6. サポートされる機密情報パターン
Secret Scanningは500種類以上のパターンをサポートしています。
6.1. 主要なサービスプロバイダー
6.1.1. クラウドプロバイダー
| プロバイダー | トークンタイプ | Validity Check | Push Protection |
|---|---|---|---|
| Amazon AWS | Access Key ID + Secret | ✓ | ✓ |
| Azure | 50種類以上のサービス | 一部対応 | 一部対応 |
| Google Cloud | API Key, OAuth, Service Account | 一部対応 | 一部対応 |
| Alibaba Cloud | Access Key ID + Secret | - | ✓ |
6.1.2. AI・機械学習プラットフォーム
| プロバイダー | トークンタイプ | Validity Check | Push Protection |
|---|---|---|---|
| OpenAI | API Key | ✓ | ✓ |
| Anthropic | API Key, Admin API Key | ✓ | ✓ |
| Google Gemini | API Key | - | - |
| Hugging Face | User Access Token | ✓ | ✓ |
| Groq | API Key | ✓ | ✓ |
| DeepSeek | API Key | - | - |
| xAI | API Key | - | ✓ |
| Mistral AI | API Key | - | - |
6.1.3. 決済・金融サービス
| プロバイダー | トークンタイプ | Validity Check | Push Protection |
|---|---|---|---|
| Stripe | API Key(本番/テスト) | ✓ | ✓ |
| Square | Access Token | ✓ | ✓ |
| PayPal | Client ID + Secret | - | - |
| Checkout.com | Secret Key | ✓ | ✓ |
6.1.4. 開発プラットフォーム
| プロバイダー | トークンタイプ | Validity Check | Push Protection |
|---|---|---|---|
| GitHub | PAT, OAuth, SSH Key | ✓ | ✓ |
| GitLab | Access Token | ✓ | ✓ |
| npm | Access Token | - | ✓ |
| Docker | Personal Access Token | - | ✓ |
| CircleCI | Personal Access Token | ✓ | ✓ |
6.1.5. コミュニケーション
| プロバイダー | トークンタイプ | Validity Check | Push Protection |
|---|---|---|---|
| Slack | API Token, Webhook URL | ✓ | ✓ |
| Discord | Bot Token | ✓ | ✓ |
| Twilio | Account SID, API Key | 一部対応 | ✓ |
| SendGrid | API Key | - | ✓ |
6.2. トークンバージョン管理
一部のトークンは複数バージョンが存在し、Push Protectionは最新バージョンのみをサポートします。これは誤検出を減らすためです。
バージョン管理対象の例
- AWS Access Key(複数バージョン)
- GitHub Personal Access Token(fine-grained, classic)
- Anthropic API Key(複数バージョン)
- Slack API Token(複数バージョン)
6.3. ペアマッチング
一部の機密情報は、IDとシークレットの両方が同じファイルで検出された場合のみアラートを生成します。
ペアマッチング対象
- AWS Access Key ID + Secret Access Key
- Alibaba Cloud Access Key ID + Secret
- Google Cloud Storage Access Key ID + Secret
これにより、部分的な検出による誤検出を削減し、実際のリスクに集中できます。
7. 実践的な運用ガイド
7.1. 機密情報漏洩時の対応フロー
7.2. 通知設定の最適化
7.2.1. リポジトリレベルの設定
# リポジトリをWatchする設定
watch_level: custom
notifications:
security_alerts: true
notification_method:
email: true
web: true
7.2.2. 組織レベルの通知対象者
以下のユーザーに自動的に通知されます:
- リポジトリ管理者
- セキュリティマネージャー
- 組織オーナー(管理者権限がある場合)
- 読み書き権限を持つカスタムロール
7.2.3. コミット作成者への通知
機密情報を誤ってコミットした開発者には、通知設定に関わらず必ず通知されます。
7.3. アラートのフィルタリング
効率的なトリアージのため、以下の条件でフィルタリングできます。
| フィルター | 説明 | 使用例 |
|---|---|---|
bypassed:true |
バイパスされたアラート | Push Protectionをバイパスした cases |
is:open |
オープン状態 | 未解決のアラート |
is:closed |
クローズ状態 | 解決済みアラート |
is:publicly-leaked |
パブリックに漏洩 | 公開リポジトリでの検出 |
is:multi-repository |
複数リポジトリ | 同じ機密情報が複数箇所に存在 |
validity:active |
有効なトークン | 即座に対応が必要 |
validity:inactive |
無効なトークン | 不正利用の確認が必要 |
validity:unknown |
検証不可 | 手動確認が必要 |
provider:github |
プロバイダー指定 | GitHub関連のトークンのみ |
secret-type:aws_access_key_id |
シークレットタイプ指定 | AWS関連のみ |
resolution:false-positive |
却下理由で絞り込み | 誤検出として却下 |
resolution:used-in-tests |
テスト用 | テストコードで使用 |
results:generic |
汎用シークレット | AIで検出されたパスワードなど |
7.4. 監査とレポーティング
7.4.1. Audit Log確認項目
Secret Scanningに関連する重要なイベント:
# Audit Logで確認すべきイベント
secret_scanning:
- secret_scanning.enable
- secret_scanning.disable
- secret_scanning_alert.create
- secret_scanning_alert.dismiss
- secret_scanning_alert.reopen
- secret_scanning_push_protection.enable
- secret_scanning_push_protection.disable
- secret_scanning_push_protection_bypass.create
- secret_scanning_custom_pattern.create
- secret_scanning_custom_pattern.update
- secret_scanning_custom_pattern.delete
7.4.2. アクセストークン別の監査
組織・エンタープライズレベルのAudit Logでは、特定のアクセストークンに関連するイベントを検索できます。
# 特定トークンの使用履歴を追跡
actor_id:TOKEN_ID
8. トラブルシューティング
8.1. Push Protectionで検出されなかった場合
以下の理由が考えられます。
8.1.1. サポート対象外のシークレット
サポートされる機密情報パターンのリストで対応状況を確認してください。
8.1.2. レガシートークン
古いバージョンのトークンは誤検出率が高いため、Push Protectionでサポートされていない可能性があります。
例:Azure Storage Keyは新しいトークンのみサポート
8.1.3. プッシュサイズの制限
- 大量のファイルを含むプッシュはタイムアウトする可能性
- 5件を超える新しい機密情報は最初の5件のみ表示
- 1,000件以上の既存機密情報を含むプッシュはブロックされない
- パブリックリポジトリで50MBを超えるプッシュはスキップ
8.1.4. 複雑な履歴
プッシュ内容が複雑すぎる場合、機密情報を導入したコミットを特定できないことがあります。
8.2. ペアマッチングの制限
IDとシークレットが以下の条件を満たす場合のみアラートが生成されます:
- 同じファイル内に存在
- 同じリポジトリにプッシュ
異なるファイルや異なるリポジトリにプッシュされた場合、アラートは生成されません。
8.3. GitHub Enterprise Serverでの制約
GitHub Enterprise Serverでは、GitHub Enterprise Cloud上のトークンを検出できず、逆もまた同様です。
9. セキュリティ構成のベストプラクティス
9.1. 段階的な導入アプローチ
9.2. 組織向け推奨設定
カスタムセキュリティ構成の例
# GitHub-recommended security configuration をベースに
# 組織の要件に応じてカスタマイズ
secret_scanning:
enabled: true
push_protection: enabled
# Validity checksを有効化
validity_checks: enabled
# 拡張メタデータを有効化
extended_metadata: enabled
# 非プロバイダーパターンを有効化
non_provider_patterns: enabled
# 汎用シークレット検出を有効化
scan_for_generic_secrets: enabled
# Delegated bypassを有効化
bypass_privileges: specific_actors
bypass_list:
- security_team
- platform_team
# Delegated dismissalを有効化
prevent_direct_alert_dismissals: enabled
9.3. カスタムパターンの命名規則
# 組織内で統一された命名規則を使用
pattern_name: "[組織名]_[サービス]_[トークンタイプ]"
# 例
patterns:
- name: "acme_internal_api_key"
description: "ACME社内部APIキー"
- name: "acme_database_password"
description: "ACMEデータベースパスワード"
- name: "acme_signing_key"
description: "ACME署名用秘密鍵"
9.4. 定期的なレビュープロセス
9.4.1. 月次レビュー
- オープン状態のアラート件数
- バイパス件数と理由の分析
- 誤検出の傾向分析
- カスタムパターンの精度確認
9.4.2. 四半期レビュー
- 除外ルールの妥当性確認
- カスタムパターンの見直し
- Delegated Bypass/Dismissalのレビュアー構成確認
- トレーニング実施状況の確認
9.4.3. 年次レビュー
- セキュリティポリシー全体の見直し
- 新しいサービス・技術スタックへの対応
- インシデント対応プロセスの改善
- 組織全体のセキュリティ意識向上施策
10. まとめ
GitHub Secret Scanningは、機密情報漏洩を防ぐための包括的なソリューションです。
10.1. 主要な特徴
- 予防と検出の両立:Push Protectionによる事前ブロックと、Secret Scanningによる事後検出
- 広範囲なカバレッジ:500種類以上のパターンサポート、Git履歴全体とGitHub上のコンテンツをスキャン
- インテリジェントな検証:Validity ChecksとExtended Metadataによる効率的なトリアージ
- 柔軟なガバナンス:Delegated Bypass/Dismissalによる承認プロセス
- AI活用:汎用シークレット検出と正規表現ジェネレーター
10.2. 導入のメリット
- セキュリティリスクの低減:機密情報漏洩の早期発見と予防
- 開発効率の向上:誤検出の削減と自動化による負荷軽減
- コンプライアンス対応:監査証跡の自動記録
- インシデント対応の効率化:詳細なメタデータによる迅速な対応
10.3. 今後の展開
Secret Scanningは継続的に進化しています。新しいサービスプロバイダーのサポート追加、AI機能の精度向上、ワークフロー統合の強化など、今後もさらなる改善が期待できます。
技術者として、これらの機能を適切に理解し活用することで、より安全な開発環境を構築できます。組織の要件に応じて段階的に導入し、継続的に改善していくことをお勧めします。