GitHub audit log analysis: step-by-step in your browser
Analyze GitHub audit log exports offline: drop JSON, Git events and Actions logs, read the verdict, triage findings, pivot on tokens and IPs, export a report.
TL;DR. Export the audit log as JSON (and Git events and Actions log archives if you have them), then drop everything on the GitHub Forensics tool. The analysis runs in your browser, with nothing uploaded. Read the verdict and its coverage notes first, then triage the findings by severity, pivot on the suspicious token or IP, check the timeline, and work through the remediation checklist. Budget about 30 minutes for a first pass on a typical organization.
This is the practical walkthrough of the analyzer on this site. It assumes you already have the files. If not, start with how to export the GitHub audit log.
Step 1: collect the exports
The minimum is the organization audit log as JSON. Each extra source removes a blind spot:
| You add | You unlock |
|---|---|
| IP addresses enabled before export | new-IP and new-country detections per token and per actor |
Git events (include=all, enterprise export or streaming) | mass-cloning detection (git.clone bursts) |
| Actions log archives of suspicious runs | secrets encoded or shipped by a workflow step |
| Secret-scanning alerts (REST JSON) | leaked credentials and the cloud next hop |
Export a few weeks before the suspected intrusion as well. The "new country" and "new IP" rules compare each token with its own history, and they need at least 24 hours of it.
Step 2: drop the files
Drop loose files, whole folders or ZIPs (nested up to three levels) on the tool. The format is detected from the content, not from the file name. The tool accepts the UI JSON / CSV exports, REST pages, streaming .json.log.gz, the Git events export-*.json.gz, Actions "Download log archive" ZIPs and secret-scanning alert JSON.
Files are read in 4 MB chunks, and gzip is decompressed on the fly, so multi-gigabyte streaming dumps work without loading everything into memory. Every skipped file is listed with a reason ("unrecognised format", "file ends mid-record", "records are not audit events"). Read that list. A truncated export is a common reason for a quiet result.
To see the output before using your own data, click Try a sample. It loads a clearly labelled fictional incident, analysed in the northwind-labs walkthrough.
Step 3: read the verdict and the coverage notes
The banner shows one of three verdicts. The policy is published in the rules file and on the tool page:
- Compromised: at least one critical finding (for example, a workflow step that encodes secrets), or two or more distinct high-severity rules on the same actor, token or IP.
- Suspicious: at least one high or medium finding.
- Clean: nothing above low.
Under the banner, Why lists the findings that drove the verdict, and Period covered shows the first and last timestamps. Check that the period includes the window you care about.
Next, read the coverage notes. They tell you what the verdict could not see: no IP addresses, no Git events, no token metadata (hashed_token), no workflow run events, or a truncated table. A Clean verdict with "No Git events" means mass cloning was not checked, not that it did not happen.
Step 4: triage the findings
Findings are sorted by severity. Each one shows the rule, its ATT&CK techniques, the first and last time, the count (and the distinct count for threshold rules), the entities involved and the evidence rows.
Triage one question at a time:
- Is the actor expected? An owner changing branch protection during office hours is normal. The same change made with a token from a VPS at 3 a.m. is not.
- Is the credential the usual one? Compare
hashed_token,programmatic_access_typeanduser_agentwith the actor's other events.curl/8.xwhere the developer normally usesgit/2.xis a strong signal. - Does it line up with other findings? A single
token-new-ipis often a laptop on hotel Wi-Fi. The same token also triggeringgit-clone-burstis an incident.
Some rules are noisy by nature. workflow-new-branch fires on every feature branch's first run, and actions-secret-created fires on routine CI work. They are rated low for that reason. They matter when they involve an actor that other findings have already flagged.
Step 5: pivot on entities
The Entities tab lists actors, tokens (by hash), IP addresses, repositories, workflows, runners and apps. Click Show events on any of them to filter the event table.
The most useful pivot is the token. Once you decide that a hashed_token is stolen, every event carrying it is attacker activity until proven otherwise, including events that fired no rule. Then pivot on the attacker's IP to find other credentials used from the same place. The leaked token playbook shows how to match a hash to a real token.
The Events tab supports free-text search (action, actor, IP, repository, any field), category filters, a Flagged only switch and UTC or local time. Click a row to see all its fields and which rules cite it.
Step 6: read the timeline, remediate, export
The Timeline with "Findings only" gives the incident narrative in order. Aggregated rows (for example 38 clones) keep it readable. Turn the filter off to see the surrounding context events: member changes, SAML updates, runner registrations.
The Remediation tab is a checklist ordered by urgency and derived from the rules that fired. It always starts with preserving evidence, then covers revoking tokens, rotating Actions secrets and cloud keys, removing persistence and restoring protections. Ticks are kept only on the page.
Finally, export:
- Events CSV: the events that match your current filters (so filter first, or clear the filters to export everything listed). Cells starting with
=,+,-or@are escaped to avoid formula injection. - Findings CSV: one line per finding.
- Report JSON: the full result, for your case file or another tool.
What the tool will not do for you
The rules are heuristics with fixed thresholds: 10 distinct repositories cloned within about an hour from one IP, and a 24-hour baseline for new IPs and countries. They are tuned for a mid-sized organization, not for yours. The audit log does not contain file contents either, so a modified workflow is inferred from its runs, not from the diff. Read GitHub audit log limitations before you write "no evidence of compromise" in a report.