GitHub Audit Log Streaming, Explained From The Ground Up

GitHub Audit Log Streaming, Explained From The Ground Up

How GitHub lets an enterprise pipe every audit and Git event, in near real time, to the storage and security tools it already trusts — and everything you need to understand, set up, and operate it safely.

Picture a large office building with hundreds of employees, dozens of doors, and a security desk that records every badge swipe. Now imagine the security desk only keeps the last three months of swipe records on a clipboard at the front desk — after that, the pages are shredded. If a break-in happened five months ago, there would be no way to reconstruct what happened. This is roughly the problem GitHub’s audit log solves for software organizations, and it is exactly the limitation that audit log streaming was built to remove. Instead of relying on a clipboard with a short memory, streaming continuously copies every “badge swipe” — every settings change, every repository action, every permission grant — to a vault of the organization’s own choosing, one that can be kept for as long as compliance, security, or plain curiosity demands.

1What Is Audit Log Streaming?

Before touching architecture or setup, it helps to understand exactly what is being moved, and why GitHub built a dedicated feature for it instead of just letting people download a report.

The audit log itself

Every GitHub Enterprise account keeps an audit log: a running record of security-relevant and administrative actions taken across the enterprise. This includes things like a user being added to a team, a repository’s visibility changing from private to public, a personal access token being created, a branch protection rule being removed, or an organization owner changing billing settings. Each entry records who did it, what they did, when, and often from where.

Alongside the audit log, GitHub also tracks Git events — the raw plumbing-level actions of the Git protocol itself, such as clones, fetches, and pushes. These are far higher in volume than administrative audit events, which is why GitHub treats them as a related but separate stream of data.

Simple Analogy

Think of the audit log as the guest book at the front desk of a company (who signed in, when, and why), while Git events are like a security camera pointed at the loading dock, capturing every truck (clone, fetch, push) that comes and goes. Both matter, but they move at very different speeds and volumes.

Why “streaming” instead of just “viewing”

GitHub already lets administrators view the audit log inside the web interface, and lets them query it through search syntax or the REST API. That works fine for looking something up after the fact. But it has three built-in limits: the UI only shows a few months of history, Git events are not shown in the UI at all because of their volume, and manually pulling data through the API does not scale to a security team that wants to watch for suspicious activity continuously.

Audit log streaming solves all three problems at once. Once configured, GitHub pushes a continuous, near real-time copy of audit and Git events to an external destination the organization controls — an Amazon S3 bucket, a Splunk instance, a Datadog account, and so on. From that point on, the organization owns the data, can keep it for as long as it wants, and can run whatever analysis, alerting, or long-term archival process fits its own compliance program.

i
Good to know

Streaming is configured once per enterprise account, not per repository or per organization. A single stream (or, on newer plans, up to three simultaneous streams) covers every organization that belongs to that enterprise.

2Why Audit Log Streaming Matters

Streaming is not a convenience feature; for many regulated organizations it is close to a compliance requirement. Understanding the underlying motivations makes every later design decision easier to follow.

6 mo
max retention of audit events inside GitHub’s own UI
7 days
retention window for Git events before they roll off
3
simultaneous streams an enterprise can configure at once

Retention beyond GitHub’s own limits

Many industries — finance, healthcare, government contracting — are legally required to retain security-relevant logs for years, not months. GitHub’s own storage was never designed to be that permanent archive; streaming is the sanctioned way to build one, in a system the organization already trusts and already pays for.

A single pane of glass for security

Most security teams do not want to check five different systems for suspicious activity. They already have a SIEM (Security Information and Event Management) tool — Splunk and Datadog are two of the most common — where logs from firewalls, cloud infrastructure, and identity providers already converge. Streaming lets GitHub’s audit trail join that same pane of glass instead of living on an island.

Forensics and incident response

When something does go wrong — a leaked token, a suspicious permission change, a repository made public by mistake — investigators need a timeline that reaches back further than a few months and that cannot be quietly altered from inside GitHub itself. An external, append-only copy of the audit log gives investigators exactly that kind of independent, tamper-resistant record.

Regulatory audits

An auditor asks for proof that no one outside the security team could grant themselves owner access in the last two years. With streaming already in place, the answer is a query against the retained data rather than a scramble to reconstruct history from memory.

Insider risk monitoring

A security team builds automated alerts on top of the streamed data — for example, flagging any event where a private repository is made public, or where an enterprise owner role is granted outside business hours.

3Architecture and Components

Zooming out, audit log streaming is a pipeline with four moving parts: the event source, GitHub’s streaming service, the encrypted credential handshake, and the destination.

Source

Event generators

Every product surface inside GitHub Enterprise — organization settings, repository administration, the Git transport layer itself — emits an event whenever a tracked action happens.

Pipeline

GitHub’s streaming service

A managed internal service collects those events, batches them, and pushes them toward the configured destination using the protocol that destination expects.

Trust boundary

Encrypted credential exchange

Before any events flow, GitHub and the enterprise owner exchange the destination’s connection details through a one-way encryption scheme, so raw secrets are never stored in plain text on either side longer than necessary.

Sink

Destination

An external system — object storage, a log-management platform, or a SIEM — that receives and stores the events for as long as the organization configures it to.

flowchart LR
    A[GitHub Enterprise actions] --> B[Audit & Git events generated]
    B --> C[GitHub streaming service]
    C -->|encrypted, batched| D{Configured destination}
    D --> E[Amazon S3]
    D --> F[Azure Blob Storage / Event Hubs]
    D --> G[Splunk / HTTPS Event Collector]
    D --> H[Datadog]
    D --> I[Google Cloud Storage]
        
FIG 1 — High-level path an event takes from action to external storage

Enterprise-scoped, not organization-scoped

A common early misunderstanding is expecting to configure streaming per organization. In reality, the stream is set up once at the enterprise account level and automatically covers every organization nested inside that enterprise, along with enterprise-level events like billing and owner changes.

!
Common misconception

Streaming does not replace the in-product audit log — the UI view keeps working exactly as before. Streaming is an additional, parallel export, not a migration away from GitHub’s own interface.

4How It Works Internally

Understanding the internal mechanics — how credentials are protected, how files are named, and how delivery is guaranteed — explains almost every operational quirk you will encounter later.

The sealed-box credential exchange

GitHub never wants to store an organization’s long-lived cloud secret (an AWS access key, an Azure SAS token, a Splunk HEC token) in a way that a compromised database could expose in plain text. To avoid that, GitHub publishes a public encryption key specific to the enterprise. Before sending credentials, the administrator’s tooling encrypts them locally against that public key — a technique often called a “sealed box.” Only GitHub’s private key, held internally, can unseal that value, and it does so only at the moment it needs to authenticate to the destination.

Simple Analogy

It is like dropping a letter into a padlocked mailbox whose key only the recipient owns. Anyone can drop a letter in, but only the person with the private key can ever open the box and read what is inside — including GitHub’s own staff.

Batching and file format

Events are not streamed one at a time as individual network calls; that would be wasteful and slow. Instead, GitHub groups events into small batches and writes them as compressed JSON files. For storage-style destinations such as Amazon S3, files are typically organized in a predictable, time-partitioned folder structure, so a security tool — or a human — can quickly locate the events for a specific hour without scanning the entire bucket.

At-least-once delivery

GitHub’s streaming pipeline guarantees that an event will be delivered at least once. In distributed systems, this is a deliberate and common trade-off: guaranteeing “exactly once” delivery across an unreliable network is extremely expensive, while “at least once” is far simpler and only occasionally produces a duplicate. GitHub embeds a unique event identifier in every record specifically so that downstream tools can deduplicate if they need a perfectly clean dataset.

sequenceDiagram
    participant Owner as Enterprise Owner
    participant GH as GitHub
    participant Dest as Destination (e.g. S3)
    Owner->>GH: Request stream public key
    GH-->>Owner: Return encryption key
    Owner->>GH: Submit sealed (encrypted) credentials
    GH->>GH: Store sealed credentials only
    loop Continuous operation
        GH->>GH: Batch new audit/Git events
        GH->>Dest: Push encrypted batch (at-least-once)
        Dest-->>GH: Acknowledge receipt
    end
    GH->>GH: Run health check every 24 hours
        
FIG 2 — Setup handshake followed by the ongoing streaming loop
i
Practical implication

Because duplicates are possible, any alerting rule built on top of streamed data (for example, “notify me every time an owner role is granted”) should be written to tolerate seeing the same event ID twice rather than assuming perfect uniqueness.

5Supported Streaming Destinations

GitHub does not force organizations onto a single vendor. Instead it supports the handful of destinations that already dominate log storage and security analytics.

Object storage

Amazon S3

The most common destination. Supports both traditional long-lived access keys and a newer, more secure OIDC (short-lived token) authentication method that avoids storing permanent secrets at all.

Object storage

Google Cloud Storage

The Google Cloud equivalent of S3 — useful for organizations already standardized on Google Cloud for their infrastructure.

Object storage

Azure Blob Storage

Authenticated using a Shared Access Signature (SAS) token scoped to a specific storage container, keeping GitHub’s access limited to exactly what it needs.

Event bus

Azure Event Hubs

A near real-time event streaming service, useful when downstream systems want to react to audit events as a live feed rather than as periodic files.

SIEM

Splunk

One of the earliest supported destinations, connecting either directly or through Splunk’s own HTTP Event Collector (HEC), depending on how the Splunk deployment is configured.

SIEM

Datadog

Lets security and platform teams view GitHub audit events inside the same dashboards already used for infrastructure and application monitoring.

Choosing between object storage and a SIEM

Object storage destinations like S3, GCS, and Azure Blob Storage are best thought of as a durable, low-cost archive: cheap to keep for years, but not built for live searching without adding another tool on top (which is exactly what the earlier search result about routing S3-stored GitHub audit data into AWS CloudTrail Lake demonstrates — the bucket becomes raw material for a proper analysis layer). SIEM destinations like Splunk and Datadog, on the other hand, are built for immediate searching, dashboards, and alerting, at a higher per-gigabyte cost. Many mature organizations use both together: a SIEM for the most recent, actively monitored window, and object storage as the long-term, low-cost archive behind it.

Destination typeBest suited forTypical trade-off
Amazon S3 / Google Cloud Storage / Azure BlobLong-term, low-cost archival and compliance retentionNo built-in search UI; needs a separate query layer
SplunkReal-time search, correlation with other security logsHigher ingestion cost at large volume
DatadogUnifying GitHub events with existing infrastructure monitoringSame ingestion-cost consideration as any SIEM
Azure Event HubsFeeding events into custom, real-time downstream processingRequires building or operating a consumer application

6Setting Up a Stream, Step by Step

The exact fields differ slightly per destination, but the overall setup flow follows the same shape every time.

1

Prepare the destination

Create the receiving resource first — for example, an S3 bucket with public access blocked, or a Splunk HEC token — before touching GitHub at all.

2

Grant GitHub the minimum permission it needs

Attach a narrowly scoped policy (for S3, typically just permission to write objects into that one bucket) rather than a broad administrative credential.

3

Open the enterprise audit log settings

An enterprise owner navigates to the enterprise account’s audit log settings and chooses “Set up streaming,” then selects the destination type.

4

Provide destination details

Enter the connection information the destination requires — a bucket name and region for S3, a SAS token URL for Azure Blob, an HEC endpoint for Splunk, and so on. GitHub encrypts this information before it is stored.

5

Verify the endpoint

GitHub sends a test payload to confirm it can reach and write to the destination before the stream is considered active.

6

Save and monitor

Once saved, the stream begins exporting new events going forward — it does not retroactively export history from before the stream existed. From here, the enterprise owner periodically checks stream health and storage growth.

!
Easy mistake

Streaming only captures events generated from the moment the stream is turned on. Anyone expecting a historical backfill of everything that happened before setup will be disappointed — plan the retention strategy before, not after, you need it.

7What Actually Gets Streamed: Event Types

Not every action inside GitHub is treated the same way once it reaches the stream. Splitting events into categories makes filtering and cost management much easier.

Audit events

  • Settings and permission changes
  • Team membership and role changes
  • Repository visibility and branch-protection changes
  • OAuth app and personal access token activity
  • Lower volume, high security signal

Git events

  • Clone, fetch, and push actions
  • Not visible in the audit log UI at all
  • Only exportable via streaming or the API
  • Much higher volume than audit events
  • Only retained internally for about seven days

Because Git events are high-volume plumbing data rather than security-decision data, most streaming setups apply some form of filtering so the destination is not flooded with routine clone traffic when the security team only cares about administrative changes. Filters are typically expressed as patterns against the event’s category — for example, capturing every repo.* or business.* event while leaving out the noisiest categories.

“If it isn’t retained somewhere outside GitHub, a Git event that happened six days ago is functionally gone forever.”

8Security Considerations

A feature whose entire purpose is security cannot itself be a weak point — GitHub’s design choices reflect that directly.

Least-privilege credentials

Every destination integration is designed around the principle of granting GitHub only the narrow permission it actually needs — typically “write object” and nothing else. An access policy that only allows writing new objects into a single named bucket cannot be used to read, modify, or delete anything else in the account, which limits the blast radius if that specific credential were ever exposed.

Short-lived credentials where possible

For Amazon S3 specifically, GitHub supports an OIDC-based authentication flow as an alternative to a permanent access key. Instead of a secret that lives forever until someone manually rotates it, GitHub exchanges short-lived tokens for each session, which meaningfully shrinks the window during which a leaked credential would even be useful to an attacker.

ANTI-PATTERN-01 Avoid
Problem

An organization reuses a broad, pre-existing “admin” AWS credential for the GitHub audit log stream instead of creating a dedicated, narrowly scoped one.

Why It’s Harmful

If that credential is ever exposed, an attacker inherits every permission the credential carries, not just “write to one bucket” — turning a minor leak into a major one.

Correct Approach

Create a purpose-built identity for the stream with only the exact write permission the destination bucket needs, and prefer the OIDC flow where the destination supports it.

Data in transit and at rest

Credentials are encrypted end-to-end during setup using the sealed-box method described earlier, and the events themselves are transmitted over encrypted connections to the destination. Once the data lands in the destination, its ongoing protection — encryption at rest, access control on the bucket or index — becomes the organization’s own responsibility, just like any other data it stores.

i
Ownership boundary

GitHub is responsible for delivering the data securely. The organization is responsible for securing it once it arrives — the same shared-responsibility split familiar from any cloud service.

9Reliability, Monitoring, and Health Checks

A stream that silently stops working is arguably worse than no stream at all, because it creates false confidence. GitHub builds several safeguards around this exact risk.

Automatic health checks

GitHub runs a health check against every configured stream roughly once every 24 hours. If the destination cannot be reached, or if authentication fails, the enterprise owners are notified by email so the problem can be fixed before too much data is lost.

Pausing without losing data

Sometimes a destination needs planned maintenance — rotating a credential, resizing a bucket policy, migrating to a new Splunk cluster. GitHub allows a stream to be paused for up to seven days without losing any events, because that matches the retention window for the underlying Git event data. Anything paused longer than that risks losing Git events that rolled off before the stream resumed.

24 hr
interval between automatic stream health checks
≤ 7 days
safe pause window before Git event data is at risk
At least once
delivery guarantee — duplicates possible, gaps are not expected

Watching for silent drift

Beyond GitHub’s own health checks, mature operations teams add their own monitoring on the destination side — for example, an alert if no new files have landed in the S3 bucket for several hours, independent of whatever GitHub itself reports. Two independent checks catch failures that a single check might miss.

10Advantages and Trade-offs

No feature is free of costs. Weighing both sides honestly helps a team decide how aggressively to adopt streaming and how much tooling to build around it.

Advantages

  • Retention limited only by the destination’s own policy, not by GitHub’s built-in window
  • Access to Git events, which are otherwise invisible outside the API for seven days
  • Fits directly into existing SIEM and security workflows
  • Encrypted, least-privilege credential handling by default
  • Supports up to three concurrent destinations for redundancy or multi-team access

Disadvantages / Trade-offs

  • Enabling streaming can add a measurable, if usually minor, load on the platform
  • At-least-once delivery means downstream tools must handle occasional duplicates
  • No historical backfill — only events from the moment the stream is enabled
  • High-volume destinations like Splunk or Datadog can become expensive at scale
  • Ongoing operational responsibility shifts to the organization once data leaves GitHub

11Best Practices and Common Mistakes

Most incidents involving audit log streaming come from a handful of repeatable mistakes — and a handful of repeatable fixes.

Treat the destination bucket or index as sensitive data

An audit log is, by definition, a detailed map of who can do what across the entire company’s source code. If that log itself is left world-readable in a storage bucket, the fix becomes a new problem — apply the same access controls to the archive as to the systems it describes.

Enable streaming before you need it, not after an incident

Because there is no historical backfill, the value of streaming compounds over time. Teams that wait until after a security incident to turn it on discover the gap in their timeline exactly when they need it most.

Deduplicate on the event identifier

Any downstream automation — alerting rules, compliance reports — should key off the unique event ID rather than assuming every record is distinct, given the at-least-once delivery guarantee.

Layer a cheap archive under an expensive SIEM

Sending everything into a SIEM alone can get costly fast as event volume grows. A common, cost-efficient pattern is to send filtered, high-priority events to Splunk or Datadog for live monitoring, while sending the full unfiltered stream to S3 or GCS for cheap long-term retention.

Rotate destination credentials on a schedule

Even with least-privilege access, a credential that never rotates is a standing risk. Where OIDC-based, short-lived authentication is available, prefer it over a static key that needs manual rotation discipline.

!
Common mistake

Assuming the in-product audit log UI and the streamed data are identical. Git events, in particular, only ever appear in the stream — checking only the UI after an incident can miss them entirely.

12Real-World and Industry Examples

Seeing how streaming fits into a broader toolchain makes the abstract architecture from earlier chapters concrete.

Feeding AWS CloudTrail Lake

Organizations already standardized on AWS CloudTrail for cloud-wide auditing can stream GitHub’s audit log to an S3 bucket and then transform and load those events into CloudTrail Lake, letting them query GitHub activity using the exact same SQL-style interface they use for their AWS infrastructure logs. This turns GitHub from a separate silo into just another data source inside a single, unified query surface.

Compliance retention for regulated industries

A financial services company subject to multi-year record-keeping requirements streams both audit and Git events into cold object storage, satisfying auditors who ask to see proof of access-control history well beyond GitHub’s own six-month window.

Unified security dashboards

A platform engineering team streams into Datadog specifically so that a spike in failed authentication attempts against GitHub shows up on the same dashboard, in the same time window, as anomalies from their cloud infrastructure — making correlation across systems a matter of looking at one screen instead of five.

Automated insider-risk alerting

A security operations team builds Splunk alerts directly on top of the streamed audit events — for example, triggering an immediate page whenever a repository’s visibility changes from private to public, rather than discovering the change during a routine weekly review.

13Frequently Asked Questions

Q1Do I need a specific GitHub plan to use audit log streaming?

Audit log streaming is an Enterprise-tier capability, configured by an enterprise owner. It is not available for individual repositories or standalone free/team-tier organizations.

Q2Can I stream to more than one destination at the same time?

Yes. GitHub supports configuring multiple concurrent streams across its supported destinations, which lets one team route data to a SIEM for live monitoring while another team routes the same data to cold storage for archival.

Q3Will turning on streaming show me events from before I enabled it?

No. Streaming only captures events generated after the stream is enabled — there is no retroactive export of historical activity.

Q4What happens if my destination goes offline for a while?

A stream can be paused, or may fail silently, for up to about seven days without losing Git event data, since that matches GitHub’s internal retention window for those events. Beyond that window, unrecovered Git events may be gone permanently; audit events have a longer internal buffer.

Q5Is it normal to see the same event twice in my destination?

Yes. GitHub’s delivery guarantee is “at least once,” which occasionally produces duplicates during retries. Downstream systems should deduplicate using the event’s unique identifier if exact counts matter.

Q6Does streaming replace the audit log I see in the GitHub web interface?

No, it runs alongside it. The in-product view remains available for quick lookups; streaming is the mechanism for long-term retention and integration with external tools.

14Summary and Key Takeaways

Audit log streaming takes GitHub’s internal record of security-relevant and Git-level activity and continuously exports it, in near real time, to a destination the organization already trusts — Amazon S3, Google Cloud Storage, Azure Blob Storage, Azure Event Hubs, Splunk, or Datadog. It exists because GitHub’s own built-in retention is deliberately short, because Git events are not even visible in the product UI, and because most security teams need this data alongside everything else already flowing into their SIEM. The design leans heavily on least-privilege, encrypted credentials and an honest “at least once” delivery guarantee, and it rewards teams that plan retention, deduplication, and access control from day one rather than reacting after an incident.

Key Takeaways

  • It is an enterprise-level export, not a UI replacement — the built-in audit log view keeps working exactly as before.
  • Two data types flow through it — lower-volume, high-signal audit events, and much higher-volume Git events that are otherwise invisible after about seven days.
  • Credentials are protected with a sealed-box encryption scheme, and S3 additionally supports short-lived OIDC authentication instead of a permanent key.
  • Delivery is “at least once,” so duplicates are expected and should be handled by deduplicating on the event’s unique ID.
  • There is no historical backfill — only events generated after the stream is enabled are captured, which makes enabling it early a genuine security decision, not a paperwork exercise.
  • Object storage and SIEM destinations solve different problems — cheap long-term archival versus real-time search and alerting — and mature setups often combine both.
  • GitHub runs automatic health checks roughly every 24 hours and allows a stream to be paused for up to seven days without data loss, giving operators a safe maintenance window.