GitHub Token Clone Push or ZIP from Unusual ASN

Last updated 11 days ago on 2026-11-03
Created 11 days ago on 2026-11-03

About

Detects git clone, git push, or ZIP download authenticated with a classic PAT, fine-grained PAT, or OAuth access token from an autonomous system (ASN) not previously seen for that user in the last 7 days. The source IP is resolved to its ASN at query time, so address churn inside the same ISP or cloud provider does not produce new alerts. A token used from an unfamiliar ASN can indicate credential theft or use from an unauthorized location.
Tags
Domain: CloudDomain: SaaSPlatform: GitHubUse Case: Threat DetectionTactic: CollectionTactic: ExfiltrationTactic: Initial AccessTactic: Defense EvasionData Source: GithubData Source: GitHub Audit LogsRule Type: ES|QLNoise: HighLanguage: esql
Severity
low
Risk Score
21
MITRE ATT&CK™

Exfiltration (TA0010)(external, opens in a new tab or window)

Collection (TA0009)(external, opens in a new tab or window)

Initial Access (TA0001)(external, opens in a new tab or window)

Defense Evasion (TA0005)(external, opens in a new tab or window)

False Positive Examples
CI, laptops, or travel networks using the same PAT or OAuth token from a new egress IP. Confirm the token owner and whether the repositories are expected.
License
Elastic License v2(external, opens in a new tab or window)

Definition

Integration Pack
Prebuilt Security Detection Rules
Related Integrations

github(external, opens in a new tab or window)

Query
text code block:
FROM logs-github.audit-* | WHERE event.dataset == "github.audit" AND event.action IN ("git.clone", "git.push", "repo.download_zip") AND github.programmatic_access_type IN ("OAuth access token", "Fine-grained personal access token", "Personal access token") AND user.name IS NOT NULL AND github.actor_ip IS NOT NULL | IP_LOCATION asn = github.actor_ip WITH { "database_file": "GeoLite2-ASN.mmdb", "properties": ["asn", "organization_name"] } | IP_LOCATION geo = github.actor_ip WITH { "properties": ["country_iso_code"] } | WHERE asn.asn IS NOT NULL | STATS Esql.event_count = COUNT(*), Esql.first_seen = MIN(@timestamp), Esql.last_seen = MAX(@timestamp), Esql.source_ip_values = VALUES(github.actor_ip), Esql.country_values = VALUES(geo.country_iso_code), Esql.repo_values = VALUES(github.repo), Esql.event_action_values = VALUES(event.action), Esql.programmatic_access_type_values = VALUES(github.programmatic_access_type), Esql.user_agent_values = VALUES(github.user_agent), Esql_priv.token_id_values = VALUES(github.token_id), Esql_priv.hashed_token_values = VALUES(github.hashed_token) BY user.name, asn.asn, asn.organization_name // The 7-day history is the rule look-back (from = now-10085m). A group is new when its first event // falls inside the current interval; the 10m bound allows for the 5m interval plus scheduling drift. // Novelty is keyed on user + ASN only, so a new IP inside an already-seen ASN does not re-alert. | WHERE DATE_DIFF("minute", Esql.first_seen, NOW()) <= 10 | EVAL Esql.source_as_number = asn.asn, Esql.source_as_organization_name = asn.organization_name | KEEP user.name, Esql.*, Esql_priv.*

Install detection rules in Elastic Security

Detect GitHub Token Clone Push or ZIP from Unusual ASN in the Elastic Security detection engine by installing this rule into your Elastic Stack.

To setup this rule, check out the installation guide for Prebuilt Security Detection Rules(external, opens in a new tab or window).