Security
Secure Git Collaboration Workflows
Signed commits with GPG/SSH, verified commits on GitHub/GitLab, branch protection rules, required status checks, signed tags, and secure supply chain practices.
- Developers who need to configure Git security and authentication
- Basic SSH concepts
- Command-line experience
- Poor key management leading to security leaks
- Not understanding signing policy causing verification failures
What you will learn
- Understand the core purpose of Secure Git Collaboration Workflows
- Master the basic usage and common options of Secure Git Collaboration Workflows
- Signed commits with GPG/SSH, verified commits on GitHub/GitLab, branch protection rules, required status checks, signed tags, and secure supply chain practices.
- Understand key concepts: Signed Commits (GPG/SSH)
- Know when to use this feature and when to avoid it
Start with a problem
You're concerned about Git repository security — maybe key management isn't ideal, or commits aren't signed. You're not sure if your security setup is sufficient or where to start hardening it.
One-Sentence Understanding
Secure collaboration in Git relies on verified identities (signed commits), enforced policies (branch protection), and review gates that prevent unauthorized or malicious code from reaching production.
Signed Commits (GPG/SSH)
GPG Signing
# Generate GPG key
gpg --full-generate-key
gpg --list-secret-keys --keyid-format LONG
# Configure Git
git config --global user.signingkey KEY_ID
git config --global commit.gpgsign true
# Sign commits
git commit -S -m "signed commit message"
git log --show-signature -1
SSH Signing (Git 2.34+)
# Configure signing key
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global gpg.format ssh
git config --global commit.gpgsign true
# Add to allowed signers
cat > ~/.ssh/allowed_signers << EOF
* $(cat ~/.ssh/id_ed25519.pub)
EOF
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
# Sign and verify
git commit -S -m "ssh signed commit"
git log --show-signature -1
Add Public Key to Platform
# GPG
gpg --armor --export KEY_ID
# Paste at GitHub: Settings → SSH and GPG keys → GPG keys
# SSH (for signing)
cat ~/.ssh/id_ed25519.pub
# Paste at GitHub: Settings → SSH and GPG keys → SSH signing keys
Verified Commits on GitHub/GitLab
Once the public key is uploaded, commits display a Verified badge. This confirms:
- The commit author matches the key owner
- The commit content has not been tampered with
- The commit originates from a trusted identity
Branch Protection Rules
GitHub
Settings → Branches → Add branch protection rule
Key settings:
| Setting | Purpose |
|---|---|
| Require pull request before merging | Prevents direct pushes |
| Require approvals (1-8) | Mandatory code review |
| Dismiss stale reviews | Ensures latest changes reviewed |
| Require status checks | Blocks failing CI |
| Require signed commits | Enforces identity verification |
| Require linear history | Prevents merge commits |
| Include administrators | No exceptions for admins |
| Lock branch | Read-only for specified users |
GitLab
Settings → Repository → Protected Branches
Similar controls: allowed to merge, push, and code owner approval.
Required Status Checks
Enforce CI pipelines before merge:
# GitHub branch protection → Require status checks to pass
# Common checks:
# - continuous-integration (tests pass)
# - lint / typecheck (code quality)
# - security-scan (vulnerability scan)
# - dependency-review (license/compliance)
GitHub Actions status check example
name: CI
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm test
- run: npm run lint
- run: npm audit --audit-level=high
Signed Tags
Tags can also be signed to verify release authenticity.
# Create signed tag
git tag -s v1.0.0 -m "Release v1.0.0"
# Verify tag
git tag -v v1.0.0
# List signed tags with verification
git tag -v $(git tag)
Signed tags prevent attackers from creating fake releases with malicious code.
Enforcing Commit Signatures
Server-Side Enforcement
GitHub: Settings → Branches → Require signed commits
GitLab: Settings → Repository → Protected branches → Require signature on commits
CI Verification
# GitHub Actions
- name: Verify signed commits
run: |
git verify-commit HEAD
if [ $? -ne 0 ]; then
echo "Commit is not signed!"
exit 1
fi
Code Review Security Gates
Required Reviewers
# .github/CODEOWNERS
*.js @frontend-team
*.go @backend-team
Dockerfile @devops-team
security/* @security-team
Merge Queue
GitHub merge queues automatically test PR batches before merging, ensuring master is always green.
Secure Supply Chain Practices
Dependency Provenance
# Verify npm package signatures
npm audit signatures
# Check commit signatures in CI
git verify-commit HEAD
SLSA Framework
- Level 1: Build scripts exist
- Level 2: Build service is used
- Level 3: Builds are auditable and hermetic
- Level 4: Build is two-person reviewed
Signed Releases
# Create signed release metadata
gpg --sign -o release-v1.0.0.sig release-v1.0.0.txt
# Distribute alongside release artifact
gsutil cp release-v1.0.0.* gs://my-releases/
Key Takeaways
- Signed commits prevent impersonation — the bedrock of Git identity trust
- Branch protection enforces process — no bypasses, no shortcuts
- Required status checks block bad code — automated gate before human review
- Signed tags ensure release integrity — verify before deploying
- Review gates catch what automation misses — pair with CI for defense in depth
Try it yourself
- Practice the secure-git-workflows command in a test repository and observe state changes before and after
- Experiment with different options and compare the output differences
- Simulate a real scenario where you would need to use this, and walk through the full process
Continue Learning
security/gpg-signing— Deep dive on GPG commit signingsecurity/signing-advanced— Advanced signing scenarios and key rotationci-cd/github-actions-basics— Status checks and CI pipelinesbest-practices/pull-request-review-readiness— PR review best practices