Content scanning
Inspect every push before a single byte reaches GitHub.
{
"name": "acme/demo", "id": 1, "installationId": 2,
"scan": {
"secrets": true,
"blockedPaths": [".github/workflows/", "*.pem"],
"maxBlobBytes": 5242880,
"allowlist": [{ "rule": "aws-access-key", "path": "docs/example.md" }]
}
}Options
secrets
Checks blob contents against built-in rules: private-key, github-token, aws-access-key, anthropic-key, openai-key, slack-token, gcp-service-account.
blockedPaths
Up to 100 plain-string patterns, ASCII case-insensitive:
| Pattern | Matches |
|---|---|
*.pem | Any file ending in .pem, at any depth |
dir/ | Everything below dir at the repository root |
.env | That path, and that file name at any depth (not .env.example) |
a/b | That exact path or anything below a/b/ |
maxBlobBytes
Blocks any new blob larger than the limit. With secrets on, it must be at most 10 MiB, and blobs over 10 MiB are always blocked because the rules can't read them.
allowlist
Up to 100 path-scoped exemptions for one rule (blocked-path, max-blob-bytes, or a secret rule id). The same content at another path is still blocked.
How it runs
The broker syncs a bare mirror of the repository, writes the push into a quarantine directory, indexes the pack against the mirror, and inspects every commit and blob the push adds — including earlier commits, merges, and root commits.
- Clean: the quarantined bytes are forwarded.
- Findings:
403 CONTENT_BLOCKEDlisting each finding'skind,rule,path, and 12-charactercommit. The matched value is never included. - Unreferenced objects:
403 UNSCANNABLE_OBJECT. - No mirror:
503 SCAN_UNAVAILABLE.
Findings can't be approved around. Rewrite history, or have an operator add a path-scoped allowlist entry.
Limits
Not a DLP guarantee
Rules are regexes. Encoded, compressed, encrypted, or split secrets get through. Scanning reduces accidental leaks and low-effort exfiltration; it doesn't stop a determined agent.
- Only blob contents and paths are checked — not commit messages, author fields, ref names, or LFS objects.
- Size the state volume for one full clone per scanned repository plus one push body per concurrent push.
- An approval consumed by a blocked push stays spent. A failed mirror sync leaves it unspent for retry.