GitHub organization audit logs record who did what in your org—repo changes, team events, user actions, and so on. Helr pulls these events via the GitHub REST API (Get the audit log for an organization): GET /orgs/{org}/audit-log. Events are paginated with a Link header (rel=next); the API uses cursor-based pagination via after/before in the link URLs.
You authenticate with a personal access token (classic) or a GitHub App token that has the read:audit_log scope. The authenticated user must be an organization owner to use this endpoint.
- The audit log API is only available for organizations on GitHub Enterprise Cloud or GitHub Enterprise Server. Standard GitHub.com organizations (Free, Team without an Enterprise account) do not have access; the API returns 404 Not Found for them.
- An organization you own (or have owner access to), or an Enterprise you own (for the enterprise-level endpoint below).
- A personal access token (classic) or GitHub App token with
read:audit_log(org) or Enterprise administration (read) (enterprise).
- Sign in to GitHub.com.
- Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token (classic).
- Name it (e.g.
helr-audit-log). Set expiration as needed. - Under Scopes, enable read:audit_log (under "Admin: Organization").
- Generate the token and copy it. It is shown only once. Store it as
GITHUB_TOKEN(or another env var you reference inhelr.yaml).
Note: The audit log API supports classic PATs with read:audit_log. Fine-grained PATs are not supported for this endpoint. GitHub App user/installation tokens with the appropriate org permissions also work.
In helr.yaml, add a GitHub audit log source. Set the organization name (login) via environment variable. See Configuration for more options.
github-audit:
url: "https://api.github.com/orgs/${GITHUB_ORG}/audit-log"
schedule:
interval_secs: 300
jitter_secs: 30
auth:
type: bearer
token_env: GITHUB_TOKEN
headers:
Accept: "application/vnd.github+json"
X-GitHub-Api-Version: "2022-11-28"
User-Agent: "Helr"
query_params:
per_page: "100"
order: "asc"
pagination:
strategy: link_header
rel: next
max_pages: 15
resilience:
timeout_secs: 30
retries:
max_attempts: 5
initial_backoff_secs: 2
max_backoff_secs: 60
multiplier: 2.0
circuit_breaker:
enabled: true
failure_threshold: 5
success_threshold: 2
half_open_timeout_secs: 60
rate_limit:
respect_headers: true
page_delay_secs: 2GITHUB_ORG: The organization login (slug), e.g.my-company, not the display name.GITHUB_TOKEN: Your classic PAT (or App token) withread:audit_log.order: asc: Fetches oldest-first so you can ingest in chronological order; usedescfor newest-first.- Rate limit: The audit log API allows 1,750 queries per hour per user and IP. Use a conservative
interval_secs(e.g. 300) andmax_pages(e.g. 15);page_delay_secshelps spread pages.
For automation, you can use a GitHub App with permission to read the organization audit log. Install the app on the org, then use an installation access token or user-to-server token. Configure Helr the same way as Option A: auth.type: bearer and token_env pointing at the token your app obtains.
export GITHUB_ORG="your-org-login"
export GITHUB_TOKEN="ghp_..."
helr validate
helr test --source github-audit # or: helr run --onceYou should see NDJSON lines (one per audit event). Then run helr run for continuous collection.
If your org is not on GitHub Enterprise, the organization endpoint (/orgs/{org}/audit-log) returns 404. If you have an Enterprise (GitHub Enterprise Cloud or Server), use the enterprise endpoint instead: GET /enterprises/{enterprise}/audit-log. You must be an enterprise owner.
In helr.yaml, point the source at the enterprise URL and set the enterprise slug (and, for GitHub Enterprise Server, the API host):
github-audit:
url: "https://${GITHUB_API_HOST}/enterprises/${GITHUB_ENTERPRISE}/audit-log"
# ... same auth, headers, query_params, pagination, resilience as above ...GITHUB_API_HOST: Useapi.github.comfor GitHub Enterprise Cloud. For GitHub Enterprise Server, use your instance (e.g.api.mycompany.ghe.com).GITHUB_ENTERPRISE: The enterprise slug (e.g.my-enterprise), not the org name. Find it in your Enterprise settings URL.GITHUB_TOKEN: Classic PAT with read:audit_log (under Admin: Enterprise) or GitHub App with Enterprise administration (read).
Then run:
export GITHUB_API_HOST="api.github.com" # or api.yourcompany.ghe.com for GHE
export GITHUB_ENTERPRISE="your-enterprise-slug"
export GITHUB_TOKEN="ghp_..."
helr validate
helr test --source github-audit- First request only: Use
fromandfrom_paramto send a start time. GitHub uses aphrasequery for search; see Searching the audit log. - Query params: Use
query_paramsforphrase,include(web|git|all),order,per_page(max 100). The audit log retains events for 180 days (Git events 7 days). By default only the past three months are considered; usephrase=created:>=YYYY-MM-DDto narrow.
Example: only web events and a date phrase:
github-audit:
url: "https://api.github.com/orgs/${GITHUB_ORG}/audit-log"
# ...
query_params:
per_page: "100"
order: "asc"
include: "web"
phrase: "created:>=2024-01-01"Events include a _document_id field. To skip duplicates across polls or replay, add:
github-audit:
# ...
dedupe:
id_path: "_document_id"
capacity: 10000To test without calling the API repeatedly: run once with --record-dir ./recordings (with valid credentials) to save responses, then use helr run --once --replay-dir ./recordings to replay from disk.
| Symptom | Check |
|---|---|
GITHUB_ORG / GITHUB_TOKEN unset |
Export both; use org login, not display name. |
401 Unauthorized |
Token valid, not revoked, and has read:audit_log. |
403 Forbidden (administrative rules / User-Agent) |
GitHub requires a User-Agent header. Add User-Agent: "Helr" (or your app name) under headers in helr.yaml. |
403 Forbidden (access) |
Authenticated user must be an organization owner (or have audit log access). |
403 / 429 rate limit |
Audit log API limit is 1,750 queries/hour. Increase interval_secs, lower max_pages, set page_delay_secs; Helr uses Retry-After when respect_headers: true. |
404 Not Found |
The audit log API is only available for GitHub Enterprise. Standard (Free/Team) orgs get 404. Use the enterprise endpoint if you have an Enterprise: url: "https://${GITHUB_API_HOST}/enterprises/${GITHUB_ENTERPRISE}/audit-log" with GITHUB_ENTERPRISE (enterprise slug) and GITHUB_API_HOST (e.g. api.github.com or api.yourcompany.ghe.com). See "If you get 404: Enterprise-level audit log" above. |
| Config placeholder unset | ${GITHUB_ORG} (or ${GITHUB_ENTERPRISE} / ${GITHUB_API_HOST} for enterprise) in helr.yaml requires that env var. |
| No events | Check phrase and include; default view is last three months. |
- API: Get the audit log for an organization —
GET https://api.github.com/orgs/{org}/audit-log. - Auth: Classic PAT or GitHub App token with
read:audit_log;Authorization: Bearer <token>. - Pagination: Link header
rel=next; Helr useslink_headerstrategy. - Rate limit: 1,750 queries per hour; use conservative interval and
page_delay_secs. - Env:
GITHUB_ORG(organization login),GITHUB_TOKEN.