GitGuardian MCP: Make Secret Scanning a Hard Merge Gate
If AI agents can open pull requests, secret scanning has to block the merge. A scanner that only reports will write accurate notes about a key that already reached the protected branch. My baseline is pre-commit scanning for fast feedback, required CI checks for enforcement, and a policy-controlled break-glass path with audit logs.
I reviewed the GitGuardian MCP integration pattern and tested it against agent-generated PRs.
What breaks without a gate
Most setups I see have the scanner installed and switched to advisory mode. That combination looks like security and behaves like a log file.
"Teams adopting agent-generated code often add scanners but keep them non-blocking. That pattern fails."
Leaked credentials reach protected branches when scans run only locally, when CI jobs are optional, or when exceptions are handled in chat instead of policy. Agent-generated code carries more risk because it arrives at high volume and often gets less review than human-written code.
| Failure Mode | Why It Happens |
|---|---|
| Scans run only locally | The agent skips local hooks entirely |
| CI jobs are optional | The status check is not required for merge |
| Exceptions in chat | No audit trail and no policy enforcement |
| Scanner reports but does not block | The credential reaches the protected branch anyway |
An exception approved in a chat thread has the audit trail of a hallway conversation. The fix for every row is the same: make the scan a required status check, and move exceptions out of chat into a written, logged policy.
The two layers in ggshield
The CI gate is the control. The local hook is a convenience that makes the CI gate fail less often.
- CI Gate (GitHub Actions)
- Local Pre-Commit
name: secret-scan
on:
pull_request:
push:
branches: [main]
jobs:
gitguardian:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: GitGuardian scan
uses: GitGuardian/ggshield/actions/secret@v1.37.0
env:
GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }}
Then set this workflow as a required status check in branch protection. When the check fails, the merge is blocked. Without that setting, the workflow is decoration.
# Install ggshield
pip install ggshield
# Configure pre-commit
ggshield install --mode pre-commit
This gives developers and agents fast feedback before code reaches CI. It is not enough on its own, because agents can bypass local hooks. A pre-commit hook is a polite request to a process that never has to run it.
Agent-safe policy contract
I treat every MCP-driven code contribution as untrusted until it passes every gate below. The flow is short on purpose.
| Gate | Purpose |
|---|---|
| Secret scanning gate | Stop credential leaks |
| Unit/integration tests | Stop functional regressions |
| Ownership review for security-sensitive files | Stop unauthorized access changes |
Installing the tool is the small part. If the secret-scanning job is not a required gate, you do not have a control. Minimal policy: no direct pushes to protected branches, and no bypass of required checks outside a documented, time-bound break-glass process.
Rollout and break-glass
Enforcement has a running cost, and it is paid in false positives. Plan for that cost before the first blocked release, when nobody has patience for governance.
| Step | Action | Timeline |
|---|---|---|
| 1 | Add the ggshield scan in CI and set it as required | Week 1 |
| 2 | Add local/pre-commit scanning for faster fixes | Week 1 |
| 3 | Track false positives and write explicit ignore governance | Week 2-3 |
| 4 | Audit exception usage monthly and push it toward zero | Ongoing |
Break-glass process template
When a legitimate false positive blocks a critical merge:
- Requester files a break-glass request with justification
- Security team reviews within SLA (e.g., 1 hour for SEV-1)
- Time-bound exception granted (e.g., 24 hours)
- Exception logged with full audit trail
- Root cause addressed: either fix the false positive rule or refactor the code
- Exception revoked after time limit
Monthly audit: review all break-glass usage and reduce exceptions toward zero.
Apply the same pattern to any repo that feeds a build or deployment pipeline, including repos that receive AI-generated patches and automated dependency updates. Credentials that land in a repo get deployed with everything else.
Checklist
-
ggshieldruns in CI on pull requests and pushes tomain - The scan is a required status check in branch protection
- Direct pushes to protected branches are disabled
-
ggshield install --mode pre-commitis part of local setup - Security-sensitive files require ownership review
- Break-glass exceptions are time-bound, logged and revoked on expiry
- False positives are tracked and ignore rules have an owner
- Exception usage is audited monthly
What I learned
- My call: teams shipping AI-assisted code should adopt this now.
- A secret scan that is not a required gate is not a control.
- Agent-generated code needs the same scanning as human code, or stricter.
- False positive management is the operational cost of enforcement. Budget for it.
