Detection rules › Panther
GitHub User Initial Access to Private Repo
Detects when a user initially accesses a private organization repository.
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 Activity on a Private Repository from an Unusual IP (Elastic)
- GitHub Exfiltration via High Number of Repository Clones by User (Elastic)
- GitHub High Number Of Non Public GitHub Repositories Cloned (YARA-L)
- High Number of Cloned GitHub Repos From PAT (Elastic)
Rule body yaml
AnalysisType: rule
Filename: github_repo_initial_access.py
RuleID: "GitHub.Repo.InitialAccess"
DisplayName: "GitHub User Initial Access to Private Repo"
Enabled: true
LogTypes:
- GitHub.Audit
Tags:
- GitHub
Reference: https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/managing-an-individuals-access-to-an-organization-repository
Severity: Info
Description: Detects when a user initially accesses a private organization repository.
Tests:
- Name: GitHub - Initial Access
ExpectedResult: true
Mocks:
- objectName: get_string_set
returnValue: ""
- objectName: put_string_set
returnValue: ""
Log:
{
"@timestamp": 1623971719091,
"business": "",
"org": "my-org",
"repo": "my-org/my-repo",
"action": "git.push",
"p_log_type": "GitHub.Audit",
"protocol_name": "ssh",
"repository": "my-org/my-repo",
"repository_public": false,
"actor": "cat",
"user": "",
}
- Name: GitHub - Repeated Access
ExpectedResult: false
Mocks:
- objectName: get_string_set
returnValue: >
"cat":"my-repo"
Log:
{
"@timestamp": 1623971719091,
"business": "",
"org": "my-org",
"repo": "my-org/my-repo",
"action": "git.push",
"p_log_type": "GitHub.Audit",
"protocol_name": "ssh",
"repository": "my-org/my-repo",
"repository_public": false,
"actor": "cat",
"user": "",
}
- Name: GitHub - Initial Access Public Repo
ExpectedResult: false
Mocks:
- objectName: get_string_set
returnValue: ""
- objectName: put_string_set
returnValue: ""
Log:
{
"@timestamp": 1623971719091,
"business": "",
"org": "my-org",
"repo": "my-org/my-repo",
"action": "git.push",
"p_log_type": "GitHub.Audit",
"protocol_name": "ssh",
"repository": "my-org/my-repo",
"repository_public": true,
"actor": "cat",
"user": "",
}
- Name: GitHub - Clone without Actor
ExpectedResult: false
Log:
{
"@timestamp": 1623971719091,
"business": "",
"org": "my-org",
"repo": "my-org/my-repo",
"action": "git.push",
"p_log_type": "GitHub.Audit",
"protocol_name": "ssh",
"repository": "my-org/my-repo",
"repository_public": false,
"actor": "",
"user": "",
}
- Name: GitHub - Initial Access by Allowed User
ExpectedResult: false
Mocks:
- objectName: get_string_set
returnValue: ""
- objectName: put_string_set
returnValue: ""
Log:
{
"@timestamp": 1623971719091,
"business": "",
"org": "my-org",
"repo": "my-org/my-repo",
"action": "git.push",
"p_log_type": "GitHub.Audit",
"protocol_name": "ssh",
"repository": "my-org/my-repo",
"repository_public": false,
"actor": "secret-scanning[bot]",
"user": "",
}
Detection logic
Condition
not (actor_user is_null or actor_user contains "secret-scanning[bot]")
action in ["git.clone", "git.push", "git.fetch"]
repository_public is_null
This rule also runs imperative logic the parser cannot express as a filter; the conditions above are the structured part it could extract.
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
actor_user | contains | secret-scanning[bot] |
actor_user | is_null |
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 |
|---|---|---|
action | in |
|
repository_public | is_null |
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field |
|---|
actor_user |
repo |