In a nutshell
Secret Scanning is GitHub's detection feature that automatically finds API keys, tokens, and connection strings lurking in your repository.
Secrets already committed get an alert; secrets about to be pushed are blocked at git push time by Push protection. Stopping leaks before they happen is the core strategy.
Why secrets matter in private / internal repos
Private does not mean the breach stays contained. An attacker who compromises one developer account or runner can use internally exposed secrets to expand the attack. Keep secrets in a secret manager and block leaks with Push protection. Here are 8 reasons why.
Main capabilities
-
PUSH PROTECTION
In
ghas-test-1, push a generated secret../demo/secret-scanning/01-push-protection.shThe push is blocked and the terminal prints an unblock URL.
Show which patterns are push-protected, enterprise-wide: octodemo → Pattern configurations ↗. Flip a pattern in the Enterprise setting column; the Alert total, False positives, and Bypass rate columns back the noise-vs-risk call with real data.
Jump directly to patterns disabled by GitHub default ↗. The filter is
github-default:disabled: it filters GitHub defaults, not the current enterprise setting.Same page is revisited on the What gets detected slide, to dig out the generic patterns.
-
BYPASS PUSH PROTECTION
Open the
unblock-secretURL from the block message in your browser, pick a reason and bypass.The reason decides what happens to the alert: It's used in tests creates a closed alert (resolved as "used in tests"), so nothing is left to triage. I'll fix it later creates an open alert that stays until someone revokes or rotates the secret.
You get “secret can now be pushed”.
Push the same branch again.
git push origin HEADOpen the resulting alert under Security → Secret scanning and show who bypassed it and why.
To keep bypasses under control: open ghas-test-1 → Advanced Security ↗, then set Push protection → Who can bypass push protection for secret scanning to Specific roles or teams (= Delegated bypass).
Configure it across the org: open theomonfort-org → Security configuration ↗, set Push protection to Enabled and Bypass privileges to Specific actors, then select the actors. Click Save configuration and apply it to the target repos. Configuring delegated bypass at the org / enterprise level disables the repo-level setting.
Demo the request flow as a contributor without bypass privileges (org owners / security managers can always bypass). Submit a request with a justification from the block page; reviewers receive an email notification.
Review requests: ghas-test-1 → Push protection bypass requests ↗ (Security and quality → Requests → Push protection bypass). Filter by All statuses → Open, open a request, and show Approve bypass request / Deny bypass request. After approval, the requester pushes again.
Gate the merge too: in ghas-test-1 → New branch ruleset ↗, turn on Require secret scanning alerts are resolved (Preview).
An I'll fix it later secret is still an open alert, so the PR merge is blocked. It's used in tests doesn't block.
-
VALIDITY CHECK
In the default view under Security → Secret scanning, use the Validity filter.
Triage by real risk: start with the secrets that are still live.
Push protection checks pushes to all branches on GitHub, not local commits at commit time. Merge protection checks before PR merge.
What gets detected
-
WHERE THE GENERIC PATTERNS HIDE
Open octodemo → Patterns disabled by GitHub default ↗, prefiltered with
github-default:disabled.It is one flat list, with no generic label. This filter matches the GitHub default value; it is not a generic-only filter.
Point them out by name — these ten are the entire set:
rsa_private_keyopenssh_private_keyec_private_keypgp_private_keygeneric_private_keymongodb_connection_stringmysql_connection_urlpostgres_connection_stringhttp_basic_authentication_headerhttp_bearer_authentication_headerEvery one reads Disabled under GitHub default: detection is on, but push protection is off by default.
-
CUSTOM PATTERN + DRY RUN
Open ghas-test-1 → New pattern ↗ (
Settings → Advanced Security → Custom patterns → New pattern).Matching secrets are already planted in the demo repo, so you only need to create the pattern:
Pattern name —
Octodemo internal service tokenSecret format —
octodemo_(live|test)_[A-Za-z0-9]{32}Test string —
octodemo_live_L1QNGy4DLxQJ8C85kfwP0lmvCHLDuVxJThe test string has to go green before the form will save. Then use Save and dry run.
The dry run reports the planted secrets without creating alerts. Review the hits, then Publish pattern.
-
ENABLE GENERIC / CUSTOM PATTERNS
Open octodemo → Pattern configurations ↗.
Generic: In Default patterns, find a pattern such as
rsa_private_keyand set Enterprise setting to Enabled.Custom: Switch to Custom patterns, choose a published enterprise pattern, and set Enterprise setting to Enabled. For the repository-scoped pattern created above, use Push protection → Enable in that repository's custom pattern settings instead.
This enables push protection, not detection. New pushes containing a matching secret are blocked when the demo repository also has push protection enabled and no organization override disables the pattern.
Four detection engines, layered from exact partner formats to unstructured secrets that only AI can catch.
How to manage exposed secrets
-
THE CAMPAIGNS TAB
Open theomonfort-org → Campaigns ↗.
The tracking view: each campaign with its due date, manager, and a burn-down of open vs closed alerts. The point to land: alerts get an owner and a deadline here, not in a spreadsheet.
-
CREATE ONE FROM SECRET SCANNING FILTERS
Create campaign → From secret scanning filtersBuild the filter live so they see the triage logic. Start from
is:open, narrow to the repos that matter, then set Validity to Active and Unknown.Watch the alert count drop with each filter. That is the whole argument: a finishable list instead of a backlog. Must be 1000 alerts or fewer to save.
-
NAME IT, DATE IT, SHIP IT
Save as → Draft campaign, then fill in the name, description, due date, and campaign manager.
Note the manager picker only offers org owners and security managers.
Review and publish notifies everyone who can see the alerts, and the campaign shows up in each repo's Security tab. Mention secret campaigns are in public preview.
When a secret is found, remediation matters more than detection. At scale, don’t work the raw alert list, run it as a security campaign.
My recommended starting checklist 📖 Docs
-
1. INTERNAL SECRET PATTERNS
ghas-test-1 → New custom pattern ↗: show Secret format, Test string, then Save and dry run before publishing.
-
2. PUSH PROTECTION PATTERNS
octodemo → Pattern configurations ↗: review False positives, Bypass rate, and the Enterprise setting column.
-
3. DIFFERENT RULES BEFORE MERGE
ghas-test-1 → New branch ruleset ↗: Require secret scanning alerts are resolved → Generic patterns. Target
main; keep the ruleset disabled for a walkthrough. -
4. PUSH PROTECTION BYPASS
octodemo → Security configurations ↗: open the intended configuration, then Push protection → Bypass privileges → Specific actors.
Enterprise settings can affect other repositories. Do not save or apply changes during a read-only demo.
-
5. SECRET REMEDIATION CAMPAIGN
theomonfort-org → Campaigns ↗: Create campaign → From secret scanning filters. Scope to ghas-test-1 and save as a draft.
-
6. STORE WORKFLOW SECRETS
ghas-test-1 → Actions secrets ↗: show New repository secret. Do not enter a real secret during screen sharing.
With Secret Protection and push protection enabled, this is the order I recommend.
URL templates: replace ENTERPRISE, ORG, OWNER, REPO.
Availability by product
| Feature | Public repo | Private / internal without product |
Secret Protection / GHAS |
|---|---|---|---|
| Secret scanning alerts | ✅ Free | ❌ | ✅ Included |
| Push protection (repo / org) | ✅ Free | ❌ | ✅ Included |
| Partner program alerts (sent to the provider) | ✅ Free, always on | ❌ | ❌ Public repos only |
| Validity checks | ❌ | ❌ | ✅ Supported providers |
| Generic patterns | ❌ | ❌ | ✅ Included |
| Custom patterns | ❌ | ❌ | ✅ Included |
| AI-detected secrets | ❌ | ❌ | ✅ Included |
| Public monitoring | ❌ | ❌ | ✅ GHEC Enterprise |
🆓 User push protection is free and enabled by default on all plans, but only covers pushes to public repositories. Partner alerts also notify providers only about leaks in public repositories and public npm packages — always on, and not configurable.
👤 User-owned repositories are a special case: alerts require GHEC with Enterprise Managed Users, or GHES with Secret Protection enabled on the enterprise. Org-owned private / internal repos only need Secret Protection on Team or GHEC.
💰 Generic, custom, and AI detection, validity checks, and private / internal repository coverage require Secret Protection or a legacy GHAS license. Public monitoring is an enterprise-wide feature for GHEC Enterprise.
📘 Details: Advanced Security products ↗ / Partner program ↗ / Public monitoring ↗
Public monitoring (NEW) 📖 Docs
- 🌐 Public only — git, PR comments, issues, discussions. Never your private repos.
- ⚡ Real time. Needs Secret Protection or GHAS. Public preview, no extra cost.
- 🧩 No setup — enable it and existing findings appear straight away.
| Attributed by | What it checks | Catches |
|---|---|---|
| 👤 Member | Committer is a member | Managed and known accounts |
| 🌐 Verified domain | Email on your domain | Personal account, work email |
⚙️ Turned on under Security and quality, by an enterprise owner or security manager.
Secret Risk Assessment 📖 Docs
Scans every org repo to show what secrets sit where. Free for Team and Enterprise orgs.
- 🔎 Scope — every repo, any visibility, archived included
- 📊 Output — secret types and counts per repo. Values are never stored or shown.
- 🕒 Frequency — point-in-time, rerunnable every 90 days. Not continuous monitoring.
- 🚀 Run it —
Org → Security and quality → Assessments → Scan your organization. The first run also starts the free code security assessment.
📊 Answers “how many secrets are leaking?” and gives you the numbers for a budget case.