Claude
Skills
Sign in
โ† Back

git-security-2025

Included with Lifetime
$97 forever

Git security best practices for 2025-2026 (signed commits, zero-trust, secret scanning). PROACTIVELY activate for: (1) configuring signed commits (GPG, SSH, S/MIME), (2) verifying commit signatures, (3) zero-trust Git workflows, (4) secret scanning (GitHub Advanced Security, gitleaks, trufflehog), (5) preventing secret leaks via pre-commit hooks, (6) protected branches and required reviewers, (7) CODEOWNERS for sensitive paths, (8) Sigstore-style attestations, (9) detecting and remediating leaked credentials, (10) supply-chain security (provenance, SBOM, SLSA). Provides: signed commit setup, secret-scanning integration, pre-commit hook templates, branch protection patterns, and incident-response checklist for credential exposure.

Security

What this skill does


## ๐Ÿšจ CRITICAL GUIDELINES

### Windows File Path Requirements

**MANDATORY: Always Use Backslashes on Windows for File Paths**

When using Edit or Write tools on Windows, you MUST use backslashes (`\`) in file paths, NOT forward slashes (`/`).

**Examples:**
- โŒ WRONG: `D:/repos/project/file.tsx`
- โœ… CORRECT: `D:\repos\project\file.tsx`

This applies to:
- Edit tool file_path parameter
- Write tool file_path parameter
- All file operations on Windows systems


### Documentation Guidelines

**NEVER create new documentation files unless explicitly requested by the user.**

- **Priority**: Update existing README.md files rather than creating new documentation
- **Repository cleanliness**: Keep repository root clean - only README.md unless user requests otherwise
- **Style**: Documentation should be concise, direct, and professional - avoid AI-generated tone
- **User preference**: Only create additional .md files when user specifically asks for documentation


---

# Git Security Best Practices 2025

## Zero-Trust Security Model (2025 Standard)

**What:** Every developer identity must be authenticated and authorized explicitly. All Git operations are logged, signed, and continuously monitored.

**Core Principles:**
1. **Never trust, always verify** - Every commit verified
2. **Least privilege access** - Minimal permissions required
3. **Continuous monitoring** - All operations logged and audited
4. **Assume breach** - Defense in depth strategies

### Implementing Zero-Trust for Git

**1. Mandatory Signed Commits:**
```bash
# 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. Identity Verification:**
```bash
# 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. Continuous Audit Logging:**
```bash
# 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. Least Privilege Access:**
```yaml
# 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. Continuous Monitoring:**
```bash
# 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
```

## Signed Commits (Mandatory in 2025)

**Why:** Cryptographically verify commit authorship, prevent impersonation, ensure audit trail.

**Industry Trend:** Signed commits increasingly required in 2025 workflows.

### GPG Signing (Traditional)

**Setup:**

```bash
# 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
```

**Troubleshooting:**

```bash
# 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 Signing (Modern Alternative - 2023+)

**Why SSH:** Simpler, reuse existing SSH keys, no GPG required.

**Setup:**

```bash
# 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
```

**Configure allowed signers file (for verification):**

```bash
# 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
```

## Secret Scanning & Prevention

### GitHub Secret Scanning (Push Protection)

**Enable in repository:**
- Settings โ†’ Code security โ†’ Secret scanning โ†’ Enable
- Enable push protection (blocks secrets at push time)

**AI-powered detection (2025):**
- AWS credentials
- Azure service principals
- Google Cloud keys
- GitHub tokens
- Database connection strings
- API keys (OpenAI, Stripe, Anthropic, etc.)
- Private keys
- OAuth tokens
- Custom patterns

**Example blocked push:**

```bash
$ 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)
```

**Fix:**

```bash
# 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 (Local Scanning)

**Install:**

```bash
# 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
```

**Usage:**

```bash
# 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
```

**Pre-commit hook:**

``

Related in Security