GitHub SSH Certificate Authority or Requirement Modified

Detects creation or deletion of a GitHub SSH certificate authority (CA), or disabling the requirement that members use SSH certificates, for an organization or enterprise. A CA lets an org issue short-lived SSH certificates and optionally require them in place of personal SSH keys, centralizing and time-bounding Git access. Destroying the CA or dropping the requirement makes ordinary unmanaged SSH keys acceptable again. Following an account takeover, an adversary may make these changes to authenticate with keys the organization does not manage and evade certificate-based access control, making this a high-impact change to Git access controls.

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 creation or deletion of a GitHub SSH certificate authority (CA), or disabling the requirement that members use
 11SSH certificates, for an organization or enterprise. A CA lets an org issue short-lived SSH certificates and optionally
 12require them in place of personal SSH keys, centralizing and time-bounding Git access. Destroying the CA or dropping
 13the requirement makes ordinary unmanaged SSH keys acceptable again. Following an account takeover, an adversary may
 14make these changes to authenticate with keys the organization does not manage and evade certificate-based access
 15control, making this a high-impact change to Git access controls.
 16"""
 17false_positives = [
 18    """
 19    Planned CA rotation. Create the replacement CA before deleting the old one, and do not disable the certificate
 20    requirement except during a documented outage.
 21    """,
 22]
 23from = "now-9m"
 24language = "esql"
 25license = "Elastic License v2"
 26name = "GitHub SSH Certificate Authority or Requirement Modified"
 27note = """## Triage and analysis
 28
 29> **Disclaimer**:
 30> 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.
 31
 32### Investigating GitHub SSH Certificate Authority or Requirement Modified
 33
 34A GitHub SSH certificate authority (CA) lets an organization or enterprise issue short-lived SSH certificates and optionally require that members use them instead of personal SSH keys. `ssh_certificate_authority.create` adds a CA, `ssh_certificate_authority.destroy` removes one, and `ssh_certificate_requirement.disable` drops the requirement so ordinary (unmanaged) SSH keys are accepted again. Destroying a CA or disabling the requirement weakens Git access control and can let an adversary authenticate with keys the organization does not manage. After an owner account is compromised, these changes are a defense-evasion step that re-opens key-based access the organization previously centralized and time-bounded.
 35
 36### Possible investigation steps
 37
 38- Identify the actor from `user.name`, `github.actor_ip`, `github.user_agent`, and `github.programmatic_access_type`, and confirm whether they legitimately hold organization or enterprise owner privileges.
 39- Determine the scope and nature of the change from `event.action` and the affected `github.org`/`github.business`, and verify whether it matches a documented CA rotation or policy decision.
 40- Distinguish rotation from tampering: a `ssh_certificate_authority.create` immediately followed by a `destroy` of the old CA can be a legitimate rotation, whereas a lone `destroy` or a `ssh_certificate_requirement.disable` with no replacement is higher risk.
 41- Confirm whether a replacement CA exists and whether the certificate requirement is still enabled after the change.
 42- Review `public_key.create` events after the change to spot unmanaged SSH keys added while the requirement was off, and review subsequent Git access using those keys.
 43- Pivot on `github.hashed_token` and `github.programmatic_access_type` to determine whether the change was made interactively in the UI or via a token, and check for correlated takeover indicators (new owner additions, PAT grants, 2FA/SSO changes, sign-ins from unusual IPs or ASNs) in the same window.
 44
 45### False positive analysis
 46
 47- A controlled CA rotation performed within an approved change window; the replacement CA should be created before the old one is deleted, and the certificate requirement should not be disabled except during a documented outage.
 48- A planned governance or migration change performed by a known administrator can generate these events as expected activity.
 49
 50### Response and remediation
 51
 52- If the change is unauthorized, restore the CA and re-enable the SSH certificate requirement as soon as possible.
 53- Revoke unexpected or unmanaged SSH keys added while the requirement was disabled, and audit Git access performed with those keys.
 54- Review org and enterprise audit logs for other changes made by the actor after the event, and revert any unauthorized modifications.
 55- Rotate credentials for the acting owner account if compromise is suspected, and force re-authentication.
 56- Escalate to incident response if the actor is unknown or unauthorized, or if the change is accompanied by new SSH keys, owner additions, token grants, or sign-ins from unfamiliar infrastructure.
 57- Harden by requiring SSH certificates org-wide, restricting who can manage the SSH CA and certificate requirement, and alerting on future CA creation/deletion and requirement changes.
 58"""
 59references = [
 60    "https://docs.github.com/en/organizations/managing-git-access-to-your-organizations-repositories/about-ssh-certificate-authorities",
 61]
 62risk_score = 73
 63rule_id = "f35a0ff1-017e-48b0-b782-5e0bdbcc390a"
 64severity = "high"
 65tags = [
 66    "Domain: Cloud",
 67    "Domain: SaaS",
 68    "Platform: GitHub",
 69    "Use Case: Threat Detection",
 70    "Tactic: Defense Evasion",
 71    "Tactic: Persistence",
 72    "Data Source: Github",
 73    "Data Source: GitHub Audit Logs",
 74    "Rule Type: ESQL",
 75    "Resources: Investigation Guide",
 76]
 77timestamp_override = "event.ingested"
 78type = "esql"
 79
 80query = '''
 81from logs-github.audit-* metadata _id, _index, _version
 82| where
 83  event.module == "github" and data_stream.dataset == "github.audit"
 84    and event.action in (
 85      "ssh_certificate_authority.create",
 86      "ssh_certificate_authority.destroy",
 87      "ssh_certificate_requirement.disable"
 88    )
 89| keep
 90    _id,
 91    _index,
 92    _version,
 93    @timestamp,
 94    event.action,
 95    user.name,
 96    github.org,
 97    github.actor_ip,
 98    github.hashed_token,
 99    github.programmatic_access_type,
100    github.user_agent,
101    github.business
102'''
103
104
105[[rule.threat]]
106framework = "MITRE ATT&CK"
107[[rule.threat.technique]]
108id = "T1562"
109name = "Impair Defenses"
110reference = "https://attack.mitre.org/techniques/T1562/"
111[[rule.threat.technique.subtechnique]]
112id = "T1562.001"
113name = "Disable or Modify Tools"
114reference = "https://attack.mitre.org/techniques/T1562/001/"
115
116[rule.threat.tactic]
117id = "TA0005"
118name = "Defense Evasion"
119reference = "https://attack.mitre.org/tactics/TA0005/"
120
121[[rule.threat]]
122framework = "MITRE ATT&CK"
123[[rule.threat.technique]]
124id = "T1556"
125name = "Modify Authentication Process"
126reference = "https://attack.mitre.org/techniques/T1556/"
127
128[rule.threat.tactic]
129id = "TA0003"
130name = "Persistence"
131reference = "https://attack.mitre.org/tactics/TA0003/"
132
133[rule.investigation_fields]
134field_names = [
135    "@timestamp",
136    "event.action",
137    "user.name",
138    "github.org",
139    "github.actor_ip",
140    "github.hashed_token",
141    "github.programmatic_access_type",
142    "github.user_agent",
143    "github.business",
144]

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 Certificate Authority or Requirement Modified

A GitHub SSH certificate authority (CA) lets an organization or enterprise issue short-lived SSH certificates and optionally require that members use them instead of personal SSH keys. ssh_certificate_authority.create adds a CA, ssh_certificate_authority.destroy removes one, and ssh_certificate_requirement.disable drops the requirement so ordinary (unmanaged) SSH keys are accepted again. Destroying a CA or disabling the requirement weakens Git access control and can let an adversary authenticate with keys the organization does not manage. After an owner account is compromised, these changes are a defense-evasion step that re-opens key-based access the organization previously centralized and time-bounded.

Possible investigation steps

  • Identify the actor from user.name, github.actor_ip, github.user_agent, and github.programmatic_access_type, and confirm whether they legitimately hold organization or enterprise owner privileges.
  • Determine the scope and nature of the change from event.action and the affected github.org/github.business, and verify whether it matches a documented CA rotation or policy decision.
  • Distinguish rotation from tampering: a ssh_certificate_authority.create immediately followed by a destroy of the old CA can be a legitimate rotation, whereas a lone destroy or a ssh_certificate_requirement.disable with no replacement is higher risk.
  • Confirm whether a replacement CA exists and whether the certificate requirement is still enabled after the change.
  • Review public_key.create events after the change to spot unmanaged SSH keys added while the requirement was off, and review subsequent Git access using those keys.
  • Pivot on github.hashed_token and github.programmatic_access_type to determine whether the change was made interactively in the UI or via a token, and check for correlated takeover indicators (new owner additions, PAT grants, 2FA/SSO changes, sign-ins from unusual IPs or ASNs) in the same window.

False positive analysis

  • A controlled CA rotation performed within an approved change window; the replacement CA should be created before the old one is deleted, and the certificate requirement should not be disabled except during a documented outage.
  • A planned governance or migration change performed by a known administrator can generate these events as expected activity.

Response and remediation

  • If the change is unauthorized, restore the CA and re-enable the SSH certificate requirement as soon as possible.
  • Revoke unexpected or unmanaged SSH keys added while the requirement was disabled, and audit Git access performed with those keys.
  • Review org and enterprise audit logs for other changes made by the actor after the event, and revert any unauthorized modifications.
  • Rotate credentials for the acting owner account if compromise is suspected, and force re-authentication.
  • Escalate to incident response if the actor is unknown or unauthorized, or if the change is accompanied by new SSH keys, owner additions, token grants, or sign-ins from unfamiliar infrastructure.
  • Harden by requiring SSH certificates org-wide, restricting who can manage the SSH CA and certificate requirement, and alerting on future CA creation/deletion and requirement changes.

References

Related rules

to-top