GitHub SSH or Deploy Key Added

Identifies the addition of an SSH public key to a GitHub user account or a deploy key to a repository. These keys grant Git access over SSH, so an adversary can add one to maintain persistent repository access after the original password, session, or token is revoked. Note that a user-level public_key.create action may not appear in a non-EMU enterprise audit stream, where it is retained only in the per-user security log.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/09/22"
  3integration = ["github"]
  4maturity = "production"
  5updated_date = "2026/09/22"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies the addition of an SSH public key to a GitHub user account or a deploy key to a repository. These keys grant
 11Git access over SSH, so an adversary can add one to maintain persistent repository access after the original password,
 12session, or token is revoked. Note that a user-level `public_key.create` action may not appear in a non-EMU enterprise
 13audit stream, where it is retained only in the per-user security log.
 14"""
 15false_positives = [
 16    """
 17    Developers adding a key for a new workstation, or administrators adding an approved deploy key for CI/CD or
 18    repository automation. Confirm the key, source IP, affected account or repository, and expected access level.
 19    """,
 20]
 21from = "now-9m"
 22language = "esql"
 23license = "Elastic License v2"
 24name = "GitHub SSH or Deploy Key Added"
 25note = """## Triage and analysis
 26
 27> **Disclaimer**:
 28> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
 29
 30### Investigating GitHub SSH or Deploy Key Added
 31
 32This rule fires on GitHub's `public_key.create` audit action, which records the addition of an SSH public key to a user account or a deploy key to a repository. Both provide durable Git access independent of the account password, making an unauthorized key a useful persistence mechanism after account or token compromise. Review the actor and source (`user.name`, `github.actor_ip`), repository context (`github.repo`), client and token (`github.user_agent`, `github.hashed_token`, `github.programmatic_access_type`), and the key's configured access in GitHub. Note that user-level `public_key.create` events may not reach `logs-github.audit-*` on non-EMU enterprises, where they are retained only in the per-user security log.
 33
 34### Possible investigation steps
 35
 36- Determine whether the event added a user SSH key or a repository deploy key. Confirm the change with the user or repository owner and verify whether `github.actor_ip` and `github.user_agent` are expected.
 37- For deploy keys, verify the repository, purpose, owner, and whether write access is required. Unexpected write-enabled deploy keys should receive higher priority.
 38- Geolocate `github.actor_ip` and review its ASN to check whether the source is consistent with the user's normal GitHub activity.
 39- Review `github.hashed_token` and `github.programmatic_access_type` to determine whether the key was added interactively or with a PAT or OAuth token, the latter being a stronger compromise signal.
 40- Correlate the same `user.name` and `github.actor_ip` with related account changes, such as unrecognized-device sign-ins, new personal access tokens, or OAuth grants, that indicate account takeover.
 41- Pivot to subsequent Git activity such as clones, pushes, or archive downloads that may have used the new key.
 42
 43### False positive analysis
 44
 45- A developer adding an SSH key for a new or replacement workstation. Confirm the key, source IP, and that the user expected it before dismissing.
 46- Automation or onboarding workflows that register SSH keys for a service account. Validate against deployment records and scope exceptions to the specific user where appropriate.
 47- Approved deploy keys used by CI/CD systems or repository automation. Confirm the repository, key owner, documented purpose, and whether the configured read or write access is expected.
 48
 49### Response and remediation
 50
 51- If the key was not authorized by the user or repository owner, delete it immediately.
 52- Reset the user's credentials and revoke active sessions if account takeover is suspected, and rotate any credentials used by affected automation.
 53- Review all SSH keys, personal access tokens, and OAuth authorizations on the account and remove any others that are unexpected.
 54- Hunt for Git activity that used the new key, such as clones, pushes, or archive downloads, to assess what was accessed.
 55- Consider requiring SSH certificates or hardware-backed keys where policy allows, and engage incident response per your organization's playbooks if compromise is confirmed.
 56"""
 57references = [
 58    "https://github.blog/news-insights/company-news/security-alert-new-phishing-campaign-targets-github-users/",
 59    "https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account",
 60    "https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys",
 61]
 62risk_score = 21
 63rule_id = "8205043a-5fd1-4dd8-be6f-55677ffe067b"
 64severity = "low"
 65tags = [
 66    "Domain: Cloud",
 67    "Domain: SaaS",
 68    "Platform: GitHub",
 69    "Use Case: Threat Detection",
 70    "Tactic: Persistence",
 71    "Data Source: Github",
 72    "Data Source: GitHub Audit Logs",
 73    "Rule Type: ES|QL",
 74    "Resources: Investigation Guide",
 75]
 76timestamp_override = "event.ingested"
 77type = "esql"
 78
 79query = '''
 80from logs-github.audit-* metadata _id, _index, _version
 81| where
 82  event.module == "github" and data_stream.dataset == "github.audit"
 83    and event.action == "public_key.create"
 84| keep
 85    _id,
 86    _index,
 87    _version,
 88    @timestamp,
 89    event.action,
 90    user.name,
 91    github.org,
 92    github.repo,
 93    github.actor_ip,
 94    github.hashed_token,
 95    github.programmatic_access_type,
 96    github.user_agent
 97'''
 98
 99
100[[rule.threat]]
101framework = "MITRE ATT&CK"
102[[rule.threat.technique]]
103id = "T1098"
104name = "Account Manipulation"
105reference = "https://attack.mitre.org/techniques/T1098/"
106[[rule.threat.technique.subtechnique]]
107id = "T1098.001"
108name = "Additional Cloud Credentials"
109reference = "https://attack.mitre.org/techniques/T1098/001/"
110
111
112
113[rule.threat.tactic]
114id = "TA0003"
115name = "Persistence"
116reference = "https://attack.mitre.org/tactics/TA0003/"
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]

Triage and analysis

Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

Investigating GitHub SSH or Deploy Key Added

This rule fires on GitHub's public_key.create audit action, which records the addition of an SSH public key to a user account or a deploy key to a repository. Both provide durable Git access independent of the account password, making an unauthorized key a useful persistence mechanism after account or token compromise. Review the actor and source (user.name, github.actor_ip), repository context (github.repo), client and token (github.user_agent, github.hashed_token, github.programmatic_access_type), and the key's configured access in GitHub. Note that user-level public_key.create events may not reach logs-github.audit-* on non-EMU enterprises, where they are retained only in the per-user security log.

Possible investigation steps

  • Determine whether the event added a user SSH key or a repository deploy key. Confirm the change with the user or repository owner and verify whether github.actor_ip and github.user_agent are expected.
  • For deploy keys, verify the repository, purpose, owner, and whether write access is required. Unexpected write-enabled deploy keys should receive higher priority.
  • Geolocate github.actor_ip and review its ASN to check whether the source is consistent with the user's normal GitHub activity.
  • Review github.hashed_token and github.programmatic_access_type to determine whether the key was added interactively or with a PAT or OAuth token, the latter being a stronger compromise signal.
  • Correlate the same user.name and github.actor_ip with related account changes, such as unrecognized-device sign-ins, new personal access tokens, or OAuth grants, that indicate account takeover.
  • Pivot to subsequent Git activity such as clones, pushes, or archive downloads that may have used the new key.

False positive analysis

  • A developer adding an SSH key for a new or replacement workstation. Confirm the key, source IP, and that the user expected it before dismissing.
  • Automation or onboarding workflows that register SSH keys for a service account. Validate against deployment records and scope exceptions to the specific user where appropriate.
  • Approved deploy keys used by CI/CD systems or repository automation. Confirm the repository, key owner, documented purpose, and whether the configured read or write access is expected.

Response and remediation

  • If the key was not authorized by the user or repository owner, delete it immediately.
  • Reset the user's credentials and revoke active sessions if account takeover is suspected, and rotate any credentials used by affected automation.
  • Review all SSH keys, personal access tokens, and OAuth authorizations on the account and remove any others that are unexpected.
  • Hunt for Git activity that used the new key, such as clones, pushes, or archive downloads, to assess what was accessed.
  • Consider requiring SSH certificates or hardware-backed keys where policy allows, and engage incident response per your organization's playbooks if compromise is confirmed.

References

Related rules

to-top