Secret leaks: what GitHub Advanced Security does not cover
Automatic secret scanning is enabled with a single toggle, and after that it formally works: GitHub Advanced Security finds strings resembling keys in change history and creates an alert.
The weak spot is elsewhere — history is not rewritten, so a token that entered the repository long ago remains there, along with everyone who managed to make a clone.
Hence the gap between "there is a signal" and "the leak is closed." On a live project, the alert counter goes into the hundreds: test stubs, configuration examples, anonymized data in documentation.
Without selection rules and an exclusion list, the stream of notifications merges into a single list where a live key sits next to a dozen safe matches.
The tool itself covers only detection. It does not know whether the token is valid, where else it is configured, which services use it, and who can revoke it.
A token incident usually surfaces not at the moment of discovery, but when requests from a foreign network have already gone through it. The investigation then starts with an access audit, not with the scanner signal.
Out-of-the-box repository protection also does not answer organizational questions: who has rights to long-lived branches, what to do with a leaked key, how rotation works.
Secret scanning without these decisions gives a false sense of control — the toggle is on, the report is green, and the keys continue to sit in history.
We explain how to configure selection, exclusions, and a response procedure so that a finding turns into a closed incident, not a report line.
What continuous secret scanning provides
Continuous secret scanning is ongoing control, not a pre-release check.
GitHub Advanced Security scans all repositories in the organization on every push and periodically rereads history, including branches untouched for a long time: a key accidentally saved in a config several months ago is found just like a fresh one.
The main metric here is time to key revocation: the time from the secret appearing in a branch to its revocation and replacement. Without automation, it is measured in days because the finding is learned about after the fact — after a foreign request or incident investigation.
The alert log records, for each case, the time, repository, commit, and closure status, so it is clear at which step the process gets stuck, and the time to revocation is reduced to hours.
Reducing false notifications is a condition for the scheme to work, not a cosmetic touch.
We configure exclusions by paths and file types, add templates for internal key formats, and mark alerts in test data: otherwise the stream of notifications turns into noise that engineers stop reading, and findings are lost along with it.
Control of all repositories rests on organization-level rules: private, archived, and forks fall under a single policy, and blocking at push time prevents a key from being saved to a remote branch before merging.
As a result, a whole class of failures goes away — leakage through credentials that remain in history and continue to work after the file is deleted.
Comparison of modes: where and when to run scanning
Scanning modes differ not in depth of analysis but in the point of launch: the earlier the check sees a secret, the cheaper it is to revoke it.
Local pre-commit checks stop a secret before it is written to history, but they work only where the rule is installed on the developer's machine. Scanning on push catches the string already in the shared repository, and the key must be considered exposed.
The second factor is coverage. Full scanning gives a unified picture across all repositories, but does not distinguish active development from archives. A regular sweep of the entire perimeter covers old branches and abandoned projects where secrets live for years.
If the code is hosted in your own environment, the set of modes narrows to those supported by the local instance.
| Connection option | When it fits | Limitations |
|---|---|---|
| Full scanning in a cloud repository | Many repositories, a unified report is needed | The secret is found after it has already entered history |
| Check on push | Active development, a barrier is needed | Blocks push; false positives require a bypass |
| Local pre-commit checks | Catch a secret before it is written to history | Depends on installing the rule on the developer's machine |
| Regular sweep of the entire perimeter | Archives, old branches, abandoned projects | Response is delayed between runs |
| Operation in your own environment | Closed network, code storage requirements | The instance must be updated and maintained yourself |
In practice, modes are combined: GitHub Advanced Security allows you to keep pre-commit checks, a push barrier, and a scheduled sweep of the rest of the perimeter in one system.
Implementation stages: from repository audit to handover
Implementing secret scanning starts not with enabling checks but with an inventory.
As long as it is unknown how many repositories exist in the organization and which are active, any configuration turns into guesswork: some projects remain uncovered, and some produce noise that the team quickly learns to ignore.
- Repository audit. We collect a complete list, separate archived and test projects, and mark contractor repositories and publicly exposed ones.
- Coverage scheme. For each group, we fix the mode: check on every change, periodic run, or one-time pass through the entire history.
- Rules and exclusions. We enable the standard set of templates, supplement them with custom ones for internal key formats, and create exclusions narrowly by path rather than disabling the check.
- False positive review. We run the rules on real history, label noise, and refine filters until the share of confirmed findings becomes acceptable for the on-call team.
- Notifications and access. We agree on who receives a finding message, who is authorized to close it, and how reminders are configured if a case remains without response.
- Handover and training. We hand over documentation and the leak response procedure, including the key revocation process, and walk through real examples with teams.
GitHub Advanced Security fits into this perimeter rather than replacing it. After handover, the team has the coverage scheme, rules, exclusions, and a clear procedure for acting on a finding.
Set of settings, schemes, and response procedures
Configuring secret scanning in GitHub Advanced Security does not end with a rule enabled in the repository.
After implementation, the team is left with a set of configurations and procedures — from it, a new engineer or contractor can redeploy the process without reconstructing the logic from chat history and participants' memory.
- Scanning configurations: which branches and paths are checked, how exclusions for test data are formatted, and where alert thresholds are set.
- Repository coverage scheme — what is connected and what is intentionally out of scope (archives, vendor mirrors), so that a new project is not started without a check.
- Lists of custom templates for your internal formats of keys, tokens, and connection strings — what the base rule sets do not catch.
- Access policies: who changes rules, who sees findings, who closes an alert. Roles are separated so that the check is not disabled just to get a green build.
- Responsibility matrix — for each type of finding, the owner is named: service team, platform, or security, and the response time to the signal.
- Response procedure — the order from alert to rotation: who receives the signal, who stops the pipeline, who confirms revocation and key replacement.
- Incident documentation — a postmortem template with fields "how the key got into history" and "what was changed in the process," so a repeat does not follow the same scenario.
- Developer memo: local check before push, steps to take on an alert, cleaning branch history without losing work.
Case study: eliminated key leaks from the build pipeline
The starting point was manual search: keys were looked for during review, and once a quarter a search was run through repository history.
In six months, this found seven live tokens; four of them had been sitting in branches from nine to forty days — until the on-call engineer learned about the finding, and another two days went to approval and rotation.
We implemented GitHub Advanced Security so that checks run on every commit and on a schedule across the entire history, not only on the latest change.
Additionally, we described custom templates for internal key formats and exclusion lists for test data and demo configs — this is what removed the bulk of false notifications because of which the on-call engineer had previously stopped opening reports.
Metrics before and after
| Metric | Before | After |
|---|---|---|
| Commit coverage by checks | selectively, about 10% | 100%, on every commit |
| Secrets found in six months | 7, all manually | 23, of which 19 automatically |
| Average time to key revocation | about two days | 40 minutes |
| False positives | a stream without triage | reduced by about 70% |
| Key that reached the main branch | 4 cases | 0 — push is blocked |
A separate effect is that every alert got an owner and a deadline: the report provides the specific secret, file, commit, and author, so the question "whose key is this and what to do with it" is resolved without back-and-forth. The remaining four findings were closed by rotation the same day.
How built-in GitHub scanning differs from external scanners
Built-in scanning in GitHub Advanced Security works inside the platform: the engine checks not only the current state of a branch but also the entire change history, including commits cleaned out of the main branch.
That is exactly where keys most often remain after accidentally entering the code and being "wiped" by the next commit. An external scanner connected to repository events sees only the latest change and misses such traces.
Forks and third-party repositories are the second dividing line. A platform solution inherits the organization's rights and settings, so the check is enabled by policy for all repositories at once, including forks.
An external scanner needs separate access tokens, traversal of forks, and manual addition of new repositories to the scan scope.
Custom secret templates: the platform provides a ready set of rules and allows adding your own — for internal token formats, private keys, database connection strings.
External scanners are more flexible here, but each rule is a separate configuration file and must be maintained during updates.
The load on the build pipeline and the maintenance effort diverge in different directions. Built-in analysis runs on the platform side and does not consume build minutes, but it is limited by its rules.
An external one adds a step to the pipeline, requires its own node and regular database updates — but it covers non-standard scenarios. The working scheme: platform scanning as the base layer, external scanning selectively where depth for your own formats is needed.
Technical questions about configuring scanning
Scanning is enabled on a live repository, so the doubts are not theoretical: what to do with findings in history, whether the team will drown in false positives, and how to handle external forks. Below are short answers to five questions that come up when configuring GitHub Advanced Security.
A secret was deleted by the next commit — will scanning find it?
It will. The check runs across the entire branch history: the string remains in the repository objects and is found on rescanning. We consider such a secret exposed — we revoke it at the provider and issue a new one, rather than simply editing the file.
How do you distinguish a false positive from a real leak?
Detectors catch strings by entropy and pattern, so test stubs and documentation examples appear in the report alongside production keys. We create exclusions narrowly, by specific path and template — a broad rule masks a real leak.
We set triage priority manually: a key from a closed staging environment is handled as planned, while a production one with access to data is handled out of turn.
Data has already gone to an external fork — what should be done?
If the repository was forked externally, the history went with the copy and cannot be recalled — only secret rotation helps. Separately, we block secret injection into external fork builds and enable scanning on them.
Will this slow down developers' work?
The check runs in the background on push and when a merge request is opened, and slows things down only in blocking mode in branch protection. During implementation, we set it to "warn," and switch critical branches to blocking mode later: build time does not increase.
We have local environment files — should they be cleaned too?
A file does not enter the repository if it is in the ignore list, but history could have preserved an early version of it — we check that separately. We keep a template without values in the repository, and inject secrets from a secure vault at build time.
Let's discuss the task: where to start configuration
The first conversation is needed not for a presentation but to estimate the scope: how many organizations and repositories, how rights are structured, and whether blocking of commits with secrets is already in place. The more specific the input data, the fewer clarifying iterations before the start.
What is worth preparing for the task discussion:
- a list of organizations and repositories — or a way to get them: groups, templates, exclusions for archived projects;
- the current access model: teams, roles, who administers security settings;
- which types of secrets are critical specifically for you — cloud keys, build tokens, database passwords, private certificates;
- where secrets have already been found: incidents, manual checks, scanner reports in the build;
- the procedure for handling false positives — who closes alerts and how;
- compliance requirements and report retention periods, if any;
- who accepts the result on the customer's side and by what criteria.
This is enough to propose a pilot: enable Secret Scanning in GitHub Advanced Security on several repositories, look at the share of alerts and false positives, and configure custom templates and exclusion rules.
Based on the results, we will return with an estimate of the scope of work and an implementation plan — stages, order of connecting organizations, rollback points, and areas of responsibility.
If the data is not at hand, describe the task in words: how many teams, which secrets are critical, what has already been tried. We will collect the missing inputs ourselves and return with a plan.







