GitHub Secret Scanning Push Protection Bypassed or Disabled
Detects bypass of GitHub secret scanning push protection, approval of a bypass request, or disabling push protection at enterprise, organization, or repository scope. This is separate from turning secret scanning off. Bypass means a detected secret was allowed into the repository — the pattern used after tj-actions and similar CI secret-dump attacks.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/11/02"
3integration = ["github"]
4maturity = "production"
5updated_date = "2026/11/02"
6
7[rule]
8author = ["Elastic"]
9description = """
10Detects bypass of GitHub secret scanning push protection, approval of a bypass request, or disabling push protection at
11enterprise, organization, or repository scope. This is separate from turning secret scanning off. Bypass means a
12detected secret was allowed into the repository — the pattern used after tj-actions and similar CI secret-dump attacks.
13"""
14false_positives = [
15 """
16 Documented test of push protection using a dummy token, or a temporary disable while fixing a noisy pattern.
17 Re-enable afterward and confirm no live secret was pushed.
18 """,
19]
20from = "now-9m"
21language = "esql"
22license = "Elastic License v2"
23name = "GitHub Secret Scanning Push Protection Bypassed or Disabled"
24note = """## Triage and analysis
25
26### Investigating GitHub Secret Scanning Push Protection Bypassed or Disabled
27
28`secret_scanning_push_protection.bypass` fires when a user pushes a detected secret anyway. `secret_scanning_push_protection_request.approve` is a reviewer allowing that push. `business_secret_scanning_push_protection.disable`, `org.secret_scanning_push_protection_disable`, and `repository_secret_scanning_push_protection.disable` turn the control off at enterprise, organization, and repository scope respectively (the `*_new_repos_disable` actions turn it off for newly created repositories). This is separate from disabling secret scanning itself, which is covered by the `GitHub Secret Scanning Disabled` rule.
29
30### Possible investigation steps
31
32- Identify `user.name`, `github.repo`, `event.action`, and `github.secret_type`, and confirm whether the actor is expected to bypass or administer this control.
33- Review `github.actor_ip` and `github.user_agent` to validate the source of the change, and pivot on `github.hashed_token` / `github.programmatic_access_type` to determine whether it was performed via the UI or a token.
34- For a bypass or approved bypass: inspect the commit that landed, rotate the secret type reported in `github.secret_type`, and check workflow logs for printed credentials.
35- For a disable: re-enable push protection and review commits pushed during the window it was off.
36- Correlate with other control changes in the same window (secret scanning disabled, bypass-list additions, new owners, PAT grants) that may indicate broader tampering.
37
38### False positive analysis
39
40- Security team testing push protection with a known dummy value during an approved exercise.
41- A noisy custom pattern that maintainers temporarily disable. Confirm no live secret was pushed and that the control is re-enabled afterward.
42
43### Response and remediation
44
45- Re-enable push protection at the affected scope. Rotate any secret that was bypassed.
46- Restrict who can bypass or disable the control, and review the push-protection bypass list.
47- Review Actions secrets and PATs created in the same window, and confirm the acting account is not compromised.
48"""
49references = [
50 "https://github.com/SigmaHQ/sigma/blob/master/rules/application/github/audit/github_push_protection_bypass_detected.yml",
51 "https://docs.github.com/en/code-security/secret-scanning/working-with-secret-scanning-and-push-protection/working-with-push-protection-from-the-command-line",
52]
53risk_score = 47
54rule_id = "0b026848-9d06-44ba-8a56-6af27790452d"
55severity = "medium"
56tags = [
57 "Domain: Cloud",
58 "Domain: SaaS",
59 "Platform: GitHub",
60 "Use Case: Threat Detection",
61 "Tactic: Defense Evasion",
62 "Data Source: Github",
63 "Data Source: GitHub Audit Logs",
64 "Rule Type: ESQL",
65 "Resources: Investigation Guide",
66]
67timestamp_override = "event.ingested"
68type = "esql"
69
70query = '''
71from logs-github.audit-* metadata _id, _index, _version
72| where
73 data_stream.dataset == "github.audit"
74 and event.action in (
75 "secret_scanning_push_protection.bypass",
76 "secret_scanning_push_protection_request.approve",
77 "business_secret_scanning_push_protection.disable",
78 "business_secret_scanning_push_protection.disabled_for_new_repos",
79 "org.secret_scanning_push_protection_disable",
80 "org.secret_scanning_push_protection_new_repos_disable",
81 "repository_secret_scanning_push_protection.disable"
82 )
83| keep
84 _id,
85 _index,
86 _version,
87 @timestamp,
88 event.action,
89 user.name,
90 github.org,
91 github.repo,
92 github.actor_ip,
93 github.hashed_token,
94 github.programmatic_access_type,
95 github.user_agent,
96 github.secret_type
97'''
98
99
100[[rule.threat]]
101framework = "MITRE ATT&CK"
102[[rule.threat.technique]]
103id = "T1562"
104name = "Impair Defenses"
105reference = "https://attack.mitre.org/techniques/T1562/"
106[[rule.threat.technique.subtechnique]]
107id = "T1562.001"
108name = "Disable or Modify Tools"
109reference = "https://attack.mitre.org/techniques/T1562/001/"
110
111
112
113[rule.threat.tactic]
114id = "TA0005"
115name = "Defense Evasion"
116reference = "https://attack.mitre.org/tactics/TA0005/"
117
118[rule.investigation_fields]
119field_names = [
120 "@timestamp",
121 "event.action",
122 "user.name",
123 "github.org",
124 "github.repo",
125 "github.actor_ip",
126 "github.hashed_token",
127 "github.programmatic_access_type",
128 "github.user_agent",
129 "github.secret_type",
130]
Triage and analysis
Investigating GitHub Secret Scanning Push Protection Bypassed or Disabled
secret_scanning_push_protection.bypass fires when a user pushes a detected secret anyway. secret_scanning_push_protection_request.approve is a reviewer allowing that push. business_secret_scanning_push_protection.disable, org.secret_scanning_push_protection_disable, and repository_secret_scanning_push_protection.disable turn the control off at enterprise, organization, and repository scope respectively (the *_new_repos_disable actions turn it off for newly created repositories). This is separate from disabling secret scanning itself, which is covered by the GitHub Secret Scanning Disabled rule.
Possible investigation steps
- Identify
user.name,github.repo,event.action, andgithub.secret_type, and confirm whether the actor is expected to bypass or administer this control. - Review
github.actor_ipandgithub.user_agentto validate the source of the change, and pivot ongithub.hashed_token/github.programmatic_access_typeto determine whether it was performed via the UI or a token. - For a bypass or approved bypass: inspect the commit that landed, rotate the secret type reported in
github.secret_type, and check workflow logs for printed credentials. - For a disable: re-enable push protection and review commits pushed during the window it was off.
- Correlate with other control changes in the same window (secret scanning disabled, bypass-list additions, new owners, PAT grants) that may indicate broader tampering.
False positive analysis
- Security team testing push protection with a known dummy value during an approved exercise.
- A noisy custom pattern that maintainers temporarily disable. Confirm no live secret was pushed and that the control is re-enabled afterward.
Response and remediation
- Re-enable push protection at the affected scope. Rotate any secret that was bypassed.
- Restrict who can bypass or disable the control, and review the push-protection bypass list.
- Review Actions secrets and PATs created in the same window, and confirm the acting account is not compromised.
References
Related rules
- GitHub Fine-Grained PAT Auto-Approve Enabled
- GitHub PAT Access Restriction Disabled
- GitHub MFA Requirement Disabled
- GitHub IP Allow List Modified
- GitHub Dependabot Alerts or Security Updates Disabled