git-security-2025 について
開発者向けの Git セキュリティガイドです。ゼロトラスト、署名付きコミット、シークレットスキャン、監査の設定例とインシデント対応手順を扱います。
主な機能
- 01ゼロトラストの Git 原則
- 02GPG と SSH によるコミット署名
- 03シークレットのスキャンと防止
- 04ブランチ保護と監査
- 05シークレット漏えいへの対応
活用シーン
- 01リポジトリの署名付きコミット要件の設定
- 02コミット前のシークレットスキャン
- 03ブランチ保護と継続的な監査の設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill git-security-2025インストール後、Claude Code で/git-security-2025を入力して読み込まれたか確認します。
同梱ファイルreferences/credential-and-code-scanning.md
詳細
🚨 重要なガイドライン
Windows のファイルパス要件
必須:Windows ではファイルパスに常にバックスラッシュを使用してください
Windows で Edit または Write ツールを使用する場合、ファイルパスにはスラッシュ(/)ではなく、必ずバックスラッシュ(\)を使用してください。
例:
- ❌ 誤り:
D:/repos/project/file.tsx - ✅ 正しい:
D:\repos\project\file.tsx
これは以下に適用されます:
- Edit ツールの file_path パラメーター
- Write ツールの file_path パラメーター
- Windows システムでのすべてのファイル操作
ドキュメント作成ガイドライン
ユーザーから明示的に依頼されない限り、新しいドキュメントファイルを作成しないでください。
- 優先事項:新しいドキュメントを作成するのではなく、既存の README.md ファイルを更新してください
- リポジトリの整理:ユーザーから別途依頼されない限り、リポジトリのルートは README.md のみとし、整理された状態を保ってください
- スタイル:ドキュメントは簡潔、明快、かつ専門的にしてください。AI が生成したような文体は避けてください
- ユーザーの希望:ユーザーがドキュメントの作成を明示的に依頼した場合に限り、追加の .md ファイルを作成してください
Git セキュリティのベストプラクティス 2025
ゼロトラストセキュリティモデル(2025 年標準)
概要: すべての開発者の身元を明示的に認証し、認可する必要があります。すべての Git 操作を記録、署名し、継続的に監視します。
基本原則:
- 決して信頼せず、常に検証する - すべてのコミットを検証する
- 最小権限のアクセス - 必要最小限の権限を付与する
- 継続的な監視 - すべての操作を記録し、監査する
- 侵害を前提とする - 多層防御戦略を採用する
Git にゼロトラストを導入する
1. 署名付きコミットの必須化:
# Global requirement
git config --global commit.gpgsign true
git config --global tag.gpgsign true
# Enforce via branch protection (GitHub/GitLab/Azure DevOps)
# Repository Settings → Branches → Require signed commits
2. 身元の検証:
# Every commit must verify identity
git log --show-signature -10
# Reject unsigned commits in CI/CD
# .github/workflows/verify.yml
- name: Verify all commits are signed
run: |
git log --pretty="%H" origin/main..HEAD | while read commit; do
if ! git verify-commit "$commit" 2>/dev/null; then
echo "ERROR: Unsigned commit $commit"
exit 1
fi
done
3. 継続的な監査ログの記録:
# Enable Git audit trail
git config --global alias.audit 'log --all --pretty="%H|%an|%ae|%ad|%s|%GK" --date=iso'
# Export audit log
git audit > git-audit.log
# Monitor for suspicious activity
git log --author="*" --since="24 hours ago" --pretty=format:"%an %ae %s"
4. 最小権限のアクセス:
# GitHub branch protection (zero-trust model)
branches:
main:
protection_rules:
required_pull_request_reviews: true
dismiss_stale_reviews: true
require_code_owner_reviews: true
required_approving_review_count: 2
require_signed_commits: true
enforce_admins: true
restrictions:
users: [] # No direct push
teams: ["security-team"]
5. 継続的な監視:
# Monitor all repository changes
# .github/workflows/security-monitor.yml
name: Security Monitoring
on: [push, pull_request]
jobs:
monitor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for unsigned commits
run: git verify-commit HEAD || echo "::warning::Unsigned commit detected"
- name: Scan for secrets
run: gitleaks detect --exit-code 1
- name: Check commit author
run: |
AUTHOR=$(git log -1 --format='%an <%ae>')
echo "Commit by: $AUTHOR"
# Log to SIEM/security monitoring
署名付きコミット(2025 年に必須)
理由: コミットの作成者を暗号学的に検証し、なりすましを防止して、監査証跡を確保します。
業界の動向: 2025 年のワークフローでは、署名付きコミットがますます必須になっています。
GPG 署名(従来方式)
セットアップ:
# Generate GPG key
gpg --full-generate-key
# Choose: RSA and RSA, 4096 bits, expires in 2y
# List keys
gpg --list-secret-keys --keyid-format=long
# Example output:
# sec rsa4096/ABC123DEF456 2025-01-15 [SC] [expires: 2027-01-15]
# uid [ultimate] Your Name <[email protected]>
# ssb rsa4096/GHI789JKL012 2025-01-15 [E] [expires: 2027-01-15]
# Configure Git
git config --global user.signingkey ABC123DEF456
git config --global commit.gpgsign true
git config --global tag.gpgsign true
# Export public key for GitHub/GitLab
gpg --armor --export ABC123DEF456
# Copy output and add to GitHub/GitLab/Bitbucket
# Sign commits
git commit -S -m "feat: add authentication"
# Verify signatures
git log --show-signature
git verify-commit HEAD
git verify-tag v1.0.0
トラブルシューティング:
# GPG agent not running
export GPG_TTY=$(tty)
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc
# Cache passphrase longer
echo 'default-cache-ttl 34560000' >> ~/.gnupg/gpg-agent.conf
echo 'max-cache-ttl 34560000' >> ~/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
# Test signing
echo "test" | gpg --clearsign
SSH 署名(最新の代替手段 - 2023 年以降)
SSH を使う理由: よりシンプルで、既存の SSH キーを再利用でき、GPG は不要です。
セットアップ:
# Check if SSH key exists
ls -la ~/.ssh/id_ed25519.pub
# Generate if needed
ssh-keygen -t ed25519 -C "[email protected]"
# Configure Git to use SSH signing
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
# Add public key to GitHub
cat ~/.ssh/id_ed25519.pub
# GitHub Settings → SSH and GPG keys → New SSH key → Key type: Signing Key
# Sign commits (automatic with commit.gpgsign=true)
git commit -m "feat: add feature"
# Verify
git log --show-signature
許可された署名者のファイルを設定する(検証用):
# Create allowed signers file
echo "[email protected] $(cat ~/.ssh/id_ed25519.pub)" > ~/.ssh/allowed_signers
# Configure Git
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
# Verify commits
git verify-commit HEAD
シークレットのスキャンと防止
GitHub シークレットスキャン(プッシュ保護)
リポジトリで有効にする:
- Settings → Code security → Secret scanning → Enable
- プッシュ保護を有効にする(プッシュ時にシークレットをブロックします)
AI を活用した検出(2025 年):
- AWS 認証情報
- Azure サービスプリンシパル
- Google Cloud キー
- GitHub トークン
- データベース接続文字列
- API キー(OpenAI、Stripe、Anthropic など)
- 秘密鍵
- OAuth トークン
- カスタムパターン
ブロックされたプッシュの例:
$ git push
remote: error: GH013: Repository rule violations found for refs/heads/main.
remote:
remote: - Push cannot contain secrets
remote:
remote: Resolve the following violations before pushing again
remote:
remote: -- AWS Access Key
remote: locations:
remote: - config.py:12
remote:
remote: (Disable push protection: https://github.com/settings/security_analysis)
remote:
To github.com:user/repo.git
! [remote rejected] main -> main (push declined due to repository rule violations)
修正方法:
# Remove secret from file
# Use environment variable instead
echo "AWS_ACCESS_KEY=your_key" >> .env
echo ".env" >> .gitignore
# Remove from history if already committed
git rm --cached config.py
git commit -m "Remove secrets"
# If in history, use filter-repo
git filter-repo --path config.py --invert-paths
git push --force
Gitleaks(ローカルスキャン)
インストール:
# macOS
brew install gitleaks
# Linux
wget https://github.com/gitleaks/gitleaks/releases/download/v8.18.0/gitleaks_8.18.0_linux_x64.tar.gz
tar -xzf gitleaks_8.18.0_linux_x64.tar.gz
sudo mv gitleaks /usr/local/bin/
# Windows
choco install gitleaks
使用方法:
# Scan entire repository
gitleaks detect
# Scan uncommitted changes
gitleaks protect
# Scan specific directory
gitleaks detect --source ./src
# Generate report
gitleaks detect --report-format json --report-path gitleaks-report.json
# Use in CI/CD
gitleaks detect --exit-code 1
コミット前フック:
# .git/hooks/pre-commit
#!/bin/bash
gitleaks protect --staged --verbose
if [ $? -ne 0 ]; then
echo "⚠️ Gitleaks detected secrets. Commit blocked."
exit 1
fi
Git-secrets(AWS に特化)
# Install
brew install git-secrets # macOS
# or
git clone https://github.com/awslabs/git-secrets.git
cd git-secrets
sudo make install
# Initialize in repository
git secrets --install
git secrets --register-aws
# Add custom patterns
git secrets --add 'password\s*=\s*[^\s]+'
git secrets --add 'api[_-]?key\s*=\s*[^\s]+'
# Scan
git secrets --scan
git secrets --scan-history
署名付きコミットの強制
ブランチ保護ルール
GitHub:
Repository → Settings → Branches → Branch protection rules
☑ Require signed commits
☑ Require linear history
☑ Require status checks to pass
GitLab:
Repository → Settings → Repository → Protected branches
☑ Allowed to push: No one
☑ Allowed to merge: Maintainers
☑ Require all commits be signed
Azure DevOps:
Branch Policies → Add policy → Require signed commits
受信前フック(サーバー側での強制)
#!/bin/bash
# .git/hooks/pre-receive (on server)
zero_commit="0000000000000000000000000000000000000000"
while read oldrev newrev refname; do
# Skip branch deletion
if [ "$newrev" = "$zero_commit" ]; then
continue
fi
# Check all commits in push
for commit in $(git rev-list "$oldrev".."$newrev"); do
# Verify commit signature
if ! git verify-commit "$commit" 2>/dev/null; then
echo "Error: Commit $commit is not signed"
echo "All commits must be signed. Configure with:"
echo " git config commit.gpgsign true"
exit 1
fi
done
done
exit 0
セキュリティ設定
推奨する Git 設定
# Enforce signed commits
git config --global commit.gpgsign true
git config --global tag.gpgsign true
# Use SSH signing (modern)
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
# Security settings
git config --global protocol.version 2
git config --global transfer.fsckobjects true
git config --global fetch.fsckobjects true
git config --global receive.fsckobjects true
# Prevent credential leaks
git config --global credential.helper cache --timeout=3600
# Or use system credential manager
git config --global credential.helper wincred # Windows
git config --global credential.helper osxkeychain # macOS
# Line ending safety
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # macOS/Linux
# Editor safety (avoid nano/vim leaks)
git config --global core.editor "code --wait"
.gitignore のセキュリティ
# Secrets
.env
.env.*
*.pem
*.key
*.p12
*.pfx
*_rsa
*_dsa
*_ecdsa
*_ed25519
credentials.json
secrets.yaml
config/secrets.yml
# Cloud provider
.aws/
.azure/
.gcloud/
gcloud-service-key.json
# Databases
*.sqlite
*.db
# Logs (may contain sensitive data)
*.log
logs/
# IDE secrets
.vscode/settings.json
.idea/workspace.xml
# Build artifacts (may contain embedded secrets)
dist/
build/
node_modules/
vendor/
認証情報の管理と CodeQL スキャン
認証情報管理(PAT、SSH キー、Git Credential Manager、ローテーション、保存)に関する詳細なガイダンス、および CodeQL とセキュリティスキャンのセットアップについては、references/credential-and-code-scanning.md を参照してください。開発者の認証情報を強化する場合や、リポジトリレベルの静的セキュリティ分析を追加する場合は、このリファレンスを読み込んでください。
監査証跡
詳細なログ記録を有効にする
# Log all Git operations
git config --global alias.ll 'log --all --graph --decorate --oneline --show-signature'
# Check commit verification
git log --show-signature -10
# Export audit log
git log --pretty=format:"%H,%an,%ae,%ad,%s" --date=iso > git-audit.csv
# Verify all commits in branch
git log --show-signature main..HEAD
セキュリティチェックリスト
リポジトリの設定:
- ☑ ブランチ保護を有効にする
- ☑ 署名付きコミットを必須にする
- ☑ プッシュ保護付きのシークレットスキャンを有効にする
- ☑ CodeQL または同様のスキャンを有効にする
- ☑ Dependabot/Renovate を設定する
- ☑ すべてのコントリビューターに 2FA を必須にする
開発者のワークステーション:
- ☑ GPG または SSH によるコミット署名を使用する
- ☑ 認証情報マネージャーを設定する(平文は使用しない)
- ☑ gitleaks をインストールして設定する
- ☑ 包括的な .gitignore を作成する
- ☑ 転送時の fsckobjects を有効にする
- ☑ パスフレーズ付きの SSH キーを使用する
ワークフロー:
- ☑ シークレットをコミットしない
- ☑ コミット前に変更をレビューする
- ☑ プル/マージ時に署名を検証する
- ☑ 定期的にセキュリティ監査を実施する
- ☑ 認証情報を定期的にローテーションする
- ☑ シークレットには環境変数を使用する
インシデント対応
コミットでシークレットが漏えいした場合:
# 1. Rotate compromised credentials IMMEDIATELY
# 2. Remove from latest commit (if not pushed)
git reset HEAD~1
# Edit files to remove secret
git add .
git commit -m "Remove secrets"
# 3. If pushed, remove from history
git filter-repo --path config/secrets.yml --invert-paths
git push --force
# 4. Notify team to re-clone
# 5. Enable push protection to prevent future leaks
署名なしのコミットが検出された場合:
# Identify unsigned commits
git log --show-signature | grep "No signature"
# Re-sign commits (if you authored them)
git rebase --exec 'git commit --amend --no-edit -n -S' -i HEAD~10
# Force push (with team coordination)
git push --force-with-lease