mcpField
I
implementing-secret-scanning-with-gitleaks

implementing-secret-scanning-with-gitleaks

github.com/mukul975セキュリティ35.2k454 回インストール8 週間前に更新
リポジトリ

implementing-secret-scanning-with-gitleaks について

Gitリポジトリに Gitleaks のシークレットスキャンを導入する実践スキルです。履歴のスキャン、pre-commit と CI/CD のチェック、独自ルール、ベースライン管理、漏えい時の対応を扱います。

主な機能

  1. 01リポジトリ履歴のスキャン
  2. 02pre-commitフックによるシークレットのコミット防止
  3. 03CI/CDへのスキャン導入
  4. 04独自検知ルールの定義
  5. 05ベースライン管理と漏えい対応

活用シーン

  1. 01既存リポジトリへのシークレット検査導入
  2. 02認証情報のGit履歴への混入防止
  3. 03CI/CDでのリポジトリスキャン

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill implementing-secret-scanning-with-gitleaks

インストール後、Claude Code で/implementing-secret-scanning-with-gitleaksを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

詳細

Gitleaks によるシークレットスキャンの実装

使用する場面

  • 開発者が誤って API キー、パスワード、トークン、秘密鍵をリポジトリにコミットしてしまう可能性がある場合
  • シークレットが Git の履歴に入るのを防ぐ、コミット前のゲートを設定する場合
  • ローテーションが必要な、過去にコミットされたシークレットがないか、既存のリポジトリ履歴をスキャンする場合
  • コンプライアンス要件により、すべてのソースコードリポジトリでシークレット検出が義務付けられている場合
  • 手動でのシークレット監査から、自動化された継続的なスキャンに移行する場合

次の用途には使用しないでください:稼働中のアプリケーションやメモリ内のシークレットを検出する場合(ランタイムシークレット検出を使用)、検出後のシークレットを管理する場合(Vault または AWS Secrets Manager を使用)、コンテナイメージをスキャンする場合(Trivy または Grype を使用)。

前提条件

  • バイナリ、Go install、または Docker で Gitleaks v8.18+ をインストール済みであること
  • ローカルフックとの連携用に pre-commit フレームワークをインストール済みであること
  • スキャン対象の履歴がある Git リポジトリ
  • CI/CD プラットフォーム(GitHub Actions、GitLab CI など)へのアクセス権

ワークフロー

ステップ 1:インストールしてリポジトリを初回スキャンする

リポジトリのベースラインスキャンを実行し、Git の履歴にあるすべての既存シークレットを特定します。

# Install Gitleaks
brew install gitleaks  # macOS
# or download binary from https://github.com/gitleaks/gitleaks/releases

# Scan entire git history for secrets
gitleaks detect --source . --report-format json --report-path gitleaks-report.json -v

# Scan only staged changes (for pre-commit)
gitleaks protect --staged --report-format json --report-path gitleaks-staged.json

# Scan specific commit range
gitleaks detect --source . --log-opts="HEAD~10..HEAD" --report-format json

# Scan without git history (filesystem only)
gitleaks detect --source . --no-git --report-format json
ステップ 2:コミット前フックを設定する

シークレットがコミットされるのを防ぐため、Gitleaks をコミット前フックとして設定します。

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.21.2
    hooks:
      - id: gitleaks
        name: gitleaks
        description: Detect hardcoded secrets using Gitleaks
        entry: gitleaks protect --staged --verbose --redact
        language: golang
        pass_filenames: false
# Install pre-commit framework
pip install pre-commit

# Install hooks defined in .pre-commit-config.yaml
pre-commit install

# Run against all files (not just staged)
pre-commit run gitleaks --all-files

# Test the hook with a deliberate secret
echo 'AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"' >> test.txt
git add test.txt
git commit -m "test"  # Should be blocked by gitleaks
ステップ 3:GitHub Actions に統合する
# .github/workflows/secret-scanning.yml
name: Secret Scanning

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  gitleaks:
    name: Gitleaks Secret Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for comprehensive scanning

      - name: Run Gitleaks
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}  # Required for gitleaks-action v2

      # Alternative: Run Gitleaks directly
      - name: Install Gitleaks
        run: |
          wget -q https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz
          tar -xzf gitleaks_8.21.2_linux_x64.tar.gz
          chmod +x gitleaks

      - name: Scan for secrets
        run: |
          if [ "${{ github.event_name }}" == "pull_request" ]; then
            ./gitleaks detect \
              --source . \
              --log-opts="${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}" \
              --report-format sarif \
              --report-path gitleaks.sarif \
              --exit-code 1
          else
            ./gitleaks detect \
              --source . \
              --report-format sarif \
              --report-path gitleaks.sarif \
              --exit-code 1 \
              --baseline-path .gitleaks-baseline.json
          fi

      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: gitleaks.sarif
          category: gitleaks
ステップ 4:カスタム検出ルールを作成する

組織固有のシークレットパターンに対応するルールを作成します。

# .gitleaks.toml
title = "Organization Gitleaks Configuration"

[extend]
useDefault = true  # Include all default rules

# Custom rule for internal API tokens
[[rules]]
id = "internal-api-token"
description = "Internal API token for service-to-service auth"
regex = '''(?i)x-internal-token["\s:=]+["\']?([a-zA-Z0-9_\-]{40,})["\']?'''
entropy = 3.5
keywords = ["x-internal-token"]
tags = ["internal", "api"]

[[rules]]
id = "database-connection-string"
description = "Database connection string with embedded credentials"
regex = '''(?i)(postgres|mysql|mongodb|redis)://[^:]+:[^@]+@[^/]+/\w+'''
keywords = ["postgres://", "mysql://", "mongodb://", "redis://"]
tags = ["database", "credentials"]

[[rules]]
id = "jwt-secret"
description = "JWT signing secret"
regex = '''(?i)(jwt[_-]?secret|jwt[_-]?key)["\s:=]+["\']?([a-zA-Z0-9/+_\-]{32,})["\']?'''
entropy = 3.0
keywords = ["jwt_secret", "jwt-secret", "jwt_key", "jwt-key"]

# Allowlist for test files and known safe patterns
[allowlist]
description = "Global allowlist"
paths = [
  '''(^|/)test(s)?/''',
  '''(^|/)spec/''',
  '''\.test\.(js|ts|py)$''',
  '''\.spec\.(js|ts|py)$''',
  '''__mocks__/''',
  '''fixtures/''',
  '''(^|/)vendor/''',
  '''node_modules/'''
]
regexes = [
  '''EXAMPLE''',
  '''example\.com''',
  '''test[-_]?(key|secret|token|password)''',
  '''(?i)placeholder''',
  '''000000+'''
]
ステップ 5:既存リポジトリのベースラインを管理する

履歴上のシークレットをローテーションする間も開発を妨げないよう、既知の検出結果のベースラインを作成します。

# Generate baseline from current state
gitleaks detect --source . --report-format json --report-path .gitleaks-baseline.json

# Subsequent scans compare against baseline (only new findings trigger failures)
gitleaks detect --source . --baseline-path .gitleaks-baseline.json --exit-code 1

# Review baseline periodically and remove entries as secrets are rotated
cat .gitleaks-baseline.json | python3 -m json.tool | head -50
ステップ 6:漏えいしたシークレットに対処する

シークレットが検出された場合は、ローテーションと履歴のクリーンアップ手順に従います。

# 1. Immediately rotate the exposed credential
#    - Revoke the old API key/token in the service provider
#    - Generate a new credential
#    - Store the new credential in a secrets manager

# 2. Remove secret from git history using git-filter-repo
pip install git-filter-repo

# Create expressions file for secrets to remove
cat > /tmp/expressions.txt << 'EOF'
regex:AKIA[0-9A-Z]{16}==>REDACTED_AWS_KEY
regex:(?i)password\s*=\s*"[^"]*"==>password="REDACTED"
EOF

git filter-repo --replace-text /tmp/expressions.txt --force

# 3. Force-push the cleaned history (coordinate with team)
# git push --force --all  # WARNING: Requires team coordination

# 4. Add the secret pattern to .gitleaks.toml rules
# 5. Update the baseline file to remove the resolved finding

主な概念

用語定義
シークレットソースコードに含めるべきでない認証情報、トークン、キー、または機密文字列
コミット前フックコミットの作成前に実行され、検出されたシークレットを含むコミットをブロックする Git フック
エントロピー文字列のランダム性を示す尺度。エントロピーが高い文字列ほど、シークレットである可能性が高くなります
ベースライン新しいシークレットと既存のシークレットを区別するために使用する、既存の検出結果のスナップショット
許可リスト検出対象から除外するパス、パターン、またはコミットを指定する設定
SARIF検出結果をセキュリティダッシュボードにアップロードするための静的解析結果交換形式
git-filter-repoすべてのコミットから機密データを削除するために Git の履歴を書き換えるツール

ツールとシステム

  • Gitleaks:コミット前フック、CI/CD、履歴スキャンに対応するオープンソースのシークレット検出ツール
  • pre-commit:複数の言語に対応したコミット前フックを管理・保守するフレームワーク
  • git-filter-repo:Git の履歴からシークレットを削除するための履歴書き換えツール
  • TruffleHog:検証済みのシークレット検出機能を備えた代替のシークレットスキャナー
  • GitHub Secret Scanning:パートナーのパターンに一致するシークレットを検出する、GitHub の標準機能

よくあるシナリオ

シナリオ:レガシーリポジトリへのシークレットスキャンの導入

背景:5年前に作成されたリポジトリで、一度もスキャンが実施されていません。過去に使用したシークレットをローテーションする間、開発を全面的に停止させずにシークレットスキャンを有効化する必要があります。

アプローチ:

  1. gitleaks detect をリポジトリの全履歴に対して実行し、ベースラインの JSON ファイルを生成します
  2. 各検出結果をトリアージし、有効(ローテーションが必要)、無効(すでにローテーション済み)、または誤検知に分類します
  3. 有効なシークレットをすべて直ちにローテーションし、利用するサービスを更新します
  4. 修正済みの有効なシークレットを除外して、ベースラインファイルをコミットします
  5. 新たな開発に対して、プリコミットフックを直ちに有効化します
  6. ベースラインを使用した CI/CD スキャンを追加し、新たなシークレットのみを検出します
  7. 過去のシークレットをローテーションするにつれて、ベースラインを段階的に縮小します

注意点:トリアージせずにベースラインを生成すると、未ローテーションのシークレットに伴うリスクを受け入れることになります。サービスプロバイダーに確認せず、過去のシークレットが無効だと決めつけないでください。共有リポジトリでチーム内の調整なしに git-filter-repo を実行すると、チームメンバー全員にリベースの競合が発生します。

出力形式

Gitleaks Secret Scanning Report
=================================
Repository: org/web-application
Scan Type: Full History
Commits Scanned: 4,523
Date: 2026-02-23

FINDINGS:
  Total: 12
  New (not in baseline): 3
  Baseline (pre-existing): 9

NEW FINDINGS (blocking):
  [1] AWS Access Key ID
      Rule: aws-access-key-id
      File: src/config/aws.py:23
      Commit: a1b2c3d (2026-02-22, [email protected])
      Secret: AKIA...REDACTED
      Entropy: 3.8

  [2] GitHub Personal Access Token
      Rule: github-pat
      File: scripts/deploy.sh:15
      Commit: d4e5f6g (2026-02-21, [email protected])
      Secret: ghp_...REDACTED
      Entropy: 4.2

  [3] Internal API Token
      Rule: internal-api-token
      File: src/services/auth.py:89
      Commit: h7i8j9k (2026-02-20, [email protected])

QUALITY GATE: FAILED (3 new findings)
Action: Rotate exposed credentials immediately.

コメント