Detection rules › Elastic
Github Activity on a Private Repository from an Unusual IP
Detects when there is activity on a private GitHub repository from an unusual IP address. Adversaries may access private repositories from unfamiliar IPs to exfiltrate sensitive code or data, potentially indicating a compromise or unauthorized access.
MITRE ATT&CK coverage
Event coverage
| Provider | Event |
|---|---|
| GitHub-git | git.clone |
| GitHub-git | git.push |
Rules detecting the same action
Other rules on this platform that filter on the same API call or operation.
- GitHub Access Granted To Personal Access Token Followed By High Number Of Cloned Non Public Repositories (YARA-L)
- GitHub Actions Unusual Bot Push to Repository (Elastic)
- GitHub Exfiltration via High Number of Repository Clones by User (Elastic)
- GitHub High Number Of Non Public GitHub Repositories Cloned (YARA-L)
- GitHub User Initial Access to Private Repo (Panther)
- High Number of Cloned GitHub Repos From PAT (Elastic)
Rule body elastic
[metadata]
creation_date = "2025/12/16"
integration = ["github"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Detects when there is activity on a private GitHub repository from an unusual IP address. Adversaries may
access private repositories from unfamiliar IPs to exfiltrate sensitive code or data, potentially indicating
a compromise or unauthorized access.
"""
from = "now-9m"
index = ["logs-github.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "Github Activity on a Private Repository from an Unusual IP"
references = [
"https://www.wiz.io/blog/shai-hulud-2-0-ongoing-supply-chain-attack",
"https://trigger.dev/blog/shai-hulud-postmortem",
"https://posthog.com/blog/nov-24-shai-hulud-attack-post-mortem",
]
risk_score = 21
rule_id = "daf2e0e0-0bab-4672-bfa1-62db0ee5ec22"
severity = "low"
tags = [
"Domain: Cloud",
"Use Case: Threat Detection",
"Tactic: Impact",
"Tactic: Initial Access",
"Tactic: Persistence",
"Data Source: Github",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset:"github.audit" and event.action:("git.push" or "git.clone") and github.repository_public:false
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"
[[rule.threat.technique]]
id = "T1195"
name = "Supply Chain Compromise"
reference = "https://attack.mitre.org/techniques/T1195/"
[[rule.threat.technique.subtechnique]]
id = "T1195.002"
name = "Compromise Software Supply Chain"
reference = "https://attack.mitre.org/techniques/T1195/002/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1213"
name = "Data from Information Repositories"
reference = "https://attack.mitre.org/techniques/T1213/"
[[rule.threat.technique.subtechnique]]
id = "T1213.003"
name = "Code Repositories"
reference = "https://attack.mitre.org/techniques/T1213/003/"
[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
[rule.new_terms]
field = "new_terms_fields"
value = ["source.ip", "github.repo"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset:"github.audit" and event.action:("git.push" or "git.clone") and github.repository_public:false
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
data_stream.dataset | eq |
|
event.action | in |
|
github.repository_public | eq |
|