GitHub Enterprise Server vs Enterprise Cloud — where the feature gaps actually hurt, org-wide policy enforcement, required workflows for cross-repo CI enforcement, what SOC 2 / HIPAA / FedRAMP mean for your GitHub usage, audit log streaming to SIEM, CODEOWNERS as an access-control layer, CLA management, inner source contribution patterns, and cost governance when Actions minutes and storage start mattering
GitHub Enterprise comes in two deployment models. The choice between them is primarily driven by data residency requirements, network isolation needs, and operational capacity — not by feature preference, since GHEC generally has more features and gets them sooner.
Self-hosted: you run GitHub on your own infrastructure (on-prem, private cloud, or air-gapped). You manage the VM, storage, backups, upgrades, and HA. Available as an appliance (OVA/AMI). Requires a GitHub Enterprise license.
GitHub-managed SaaS with enterprise controls: org-level policies, EMU, SAML/OIDC SSO, audit log streaming, enterprise billing. Runs on github.com infrastructure. No operational burden. Supports data residency (EU) via GHEC with data residency add-on.
| Area | GHES | GHEC |
|---|---|---|
| Data residency / isolation | Full — data never leaves your network | US datacenters by default; EU residency add-on available |
| Air-gap support | Yes — works with no internet | No — requires internet access |
| Operational burden | High — you manage upgrades, HA, backups | None — GitHub manages infrastructure |
| Feature velocity | Lagging ~6–12 months behind GHEC | Gets new features first |
| Actions runners | Self-hosted only (no GitHub-hosted runners) | GitHub-hosted + self-hosted |
| Copilot Enterprise | Limited (some features require GHEC) | Full feature set |
| GitHub Pages | Limited (no CDN) | Full CDN-backed Pages |
| GitHub Advanced Security (GHAS) | Available (add-on license) | Available (add-on license) |
| Enterprise Managed Users (EMU) | Not available | Available |
GitHub provides the GitHub Enterprise Importer (GEI) tool for migrating repos, issues, PRs, wikis, and settings from GHES to GHEC.
GEI migrates: git history, pull requests and PR comments, issues and issue comments, releases and release assets, wikis, GitHub Actions workflows and secrets (secrets require re-entry). It does not migrate: branch protection rules (must be recreated), team memberships (must be recreated), webhooks, and deploy keys.
Organization admins can lock down how developers interact with GitHub at a policy level — independent of individual repo settings. These policies are the first line of defense for a compliant enterprise GitHub setup.
actions/*, github/*, and specific vetted community actions. All others are blocked at dispatch time.
GITHUB_TOKEN default permissions to read-only org-wide, requiring workflows to explicitly request write permissions. Reduces blast radius if a workflow is compromised.
By default any OAuth App a member authorizes gets access to org resources. Enable OAuth App access restrictions to require org admin approval before any OAuth App can access org data.
GitHub Enterprise Cloud supports IP allow lists that restrict who can access your org's resources. Only requests from listed CIDR ranges are accepted — everyone else gets a 403, even with valid credentials.
When you enable an IP allow list, GitHub-hosted Actions runners are blocked from accessing your org by default. You must either add GitHub's runner IP ranges (they publish a JSON list at api.github.com/meta) or switch to self-hosted runners. Self-hosted runners inside your network are the cleaner solution at enterprise scale.
Required workflows (GitHub Enterprise Cloud, 2023+) let you define a workflow in one "policy repo" and enforce it as a required status check on every repo in an org — without touching each repo's individual settings. It's the governance equivalent of a CODEOWNERS rule applied at the CI layer.
acme/.github or acme/org-workflows).github/workflows/org-security-scan.ymlGITHUB_TOKEN scoped to the target repo, not the policy source repoRequired workflows are ideal for: org-wide secret scanning on every PR, license compliance checks, required SAST scan before merge, and mandatory deployment approval steps. They eliminate the "someone forgot to add the security scan to this new repo" problem at scale.
Left unmanaged, an org quickly accumulates hundreds of repos with inconsistent naming, surprise public visibility, and no standard files. A repo creation policy prevents this before it starts.
| Setting | Location | Recommendation |
|---|---|---|
| Who can create repos | Org Settings → Member privileges | Members (not just admins), but require naming convention via automation |
| Default repo visibility | Org Settings → Member privileges | Private — members must explicitly choose public |
| Fork policy | Org Settings → Member privileges | Restrict forking to internal/private repos only for sensitive codebases |
| Repo topics requirement | Enforced via webhook/bot | Require at least one topic (team name or service type) for discoverability |
Combine a repository.created webhook with a GitHub App to automatically configure every new repo: add branch protection, apply the org CODEOWNERS template, create required labels, and add the repo to the relevant team.
GitHub (github.com / GHEC) holds several compliance certifications. Understanding which certifications apply, what they cover, and where your responsibility begins is critical for any org operating under a regulated framework.
GitHub Enterprise Cloud is SOC 2 Type II certified (Trust Services Criteria: Security, Availability, Confidentiality). This means GitHub's infrastructure controls have been audited by an independent auditor annually. You can request GitHub's SOC 2 report under NDA for your own audit evidence. Your responsibilities: access control (who has GitHub accounts), what you store in repos (no unencrypted PII/PHI), and your own SDLC processes.
GitHub will sign a Business Associate Agreement (BAA) for GHEC customers, which enables you to store PHI-adjacent code (code that processes health data) in GitHub repos. The BAA covers GitHub's infrastructure. It does not cover: storing actual PHI in issues/comments/wikis, GitHub Actions logs that contain PHI, or Copilot processing PHI-containing code. In practice: code is generally not PHI, but test fixtures, logs, and issues sometimes are — keep those clean.
GitHub Government Cloud (a separate GHEC deployment at github.us) holds FedRAMP Moderate authorization. It's only available to US federal agencies and their contractors. If your org operates on standard github.com, FedRAMP does not apply. If you need FedRAMP High, GHES in a government cloud (AWS GovCloud, Azure Government) is the typical approach.
GitHub maintains ISO 27001 (information security management) and ISO 27018 (protection of PII in public cloud) certifications. These are relevant for EU/global enterprise procurement and vendor risk assessments.
| Control area | GitHub's responsibility | Your responsibility |
|---|---|---|
| Physical security | Data center, hardware | Your laptop, your office |
| Network security | GitHub.com network perimeter | Your corporate network, VPN |
| Identity & access | GitHub account security (2FA enforcement option) | Who gets an account, SSO config, PAT hygiene |
| Data classification | Encrypts data at rest and in transit | What data you put in repos, issues, Copilot context |
| Vulnerability management | GitHub platform vulnerabilities | Dependencies in your code (Dependabot alerts) |
| Logging & monitoring | Provides audit log, retains 180 days | Stream and retain logs per your policy (1–7 years) |
GitHub's org audit log records every security-relevant action: who logged in, who pushed to main, who changed a branch protection rule, which OAuth apps were authorized, and more. For most compliance frameworks, you're required to retain these logs for 1–7 years and to monitor them for anomalies — GitHub's built-in 180-day retention is not enough.
Audit log streaming (GHEC Enterprise) pushes every audit event in real time to your chosen destination. This is the enterprise-grade solution — no polling, no retention gap.
| Streaming destination | Setup path |
|---|---|
| Amazon S3 | Org Settings → Audit log → Log streaming → Amazon S3. Requires an S3 bucket + IAM role. Events delivered as JSONL, gzip compressed. |
| Azure Blob Storage | Same settings path. Requires Storage Account + SAS token or managed identity. |
| Google Cloud Storage | Same settings path. Requires GCS bucket + service account JSON key. |
| Splunk (via HEC) | Same settings path. Requires Splunk HEC token + endpoint URL. Events indexed directly into Splunk. |
| Datadog | Same settings path. Requires a Datadog API key. Events appear as log events in Datadog Logs. |
Once logs are in your SIEM, write detection rules for: protected_branch.* changes outside business hours, org.remove_member followed by large repo access, secret_scanning.push_protection_bypass events, and repo.visibility_change from private to public. These are the signals that matter most for insider threat and misconfig detection.
CODEOWNERS combined with branch protection required reviews creates a code-level access control layer: certain paths in the codebase cannot be merged to main without an approving review from a designated owner. This is a lightweight alternative to repo-level permissions for organizations that keep everything in a monorepo.
CODEOWNERS only takes effect when branch protection Required pull request reviews has "Require review from Code Owners" checked. Without this, CODEOWNERS only requests reviews — it doesn't block merge.
Rulesets support bypass actors — roles or teams that can merge without the review requirement. Limit bypasses to: the repo admin team, an automated release bot, and on-call incident responders. Never give bypass to developers' personal accounts.
CODEOWNERS matching is last-match-wins: the last matching line in the file determines the owner. A * at the top as a catch-all is overridden by specific paths below — this is correct behavior but surprises teams that put the default at the bottom instead of the top.
cla-assistantA Contributor License Agreement (CLA) is a legal document that grants your org the rights to use and distribute a contributor's code. Required by most companies for external contributions to public or open-source repos. The cla-assistant bot automates the signing workflow on GitHub.
cla-assistant as a GitHub App or use the hosted version at cla-assistant.iocla/signed) to the PR, which you require before merge| Option | Pros | Cons |
|---|---|---|
| cla-assistant.io (hosted) | Zero ops, free for open source, immediate setup | Signature data stored on their servers; not suitable for highly regulated orgs |
| Self-hosted cla-assistant | Full control of data, store signatures in your own database | Requires deployment and maintenance of the bot service |
| Custom GitHub App | Fully bespoke logic, integrate with your legal system | Significant development effort |
You need a CLA for: public repos accepting external contributions to a commercial product, open-source projects that may need to relicense, and any repo where your legal team requires copyright assignment. You don't need a CLA for internal employee contributions (employment agreement covers it) or purely personal open-source projects.
Inner source applies open-source contribution patterns (fork, PR, review, merge) to internal codebases across teams. It solves a specific organizational problem: how do you let teams contribute improvements to a shared service without giving everyone write access to that service's repo?
Each shared repo has designated trusted committers — the team that owns the codebase. They review and merge contributions, maintain quality, and communicate the roadmap. Everyone else contributes via PRs from forks or branches.
Every inner source repo must have a CONTRIBUTING.md that explains: how to set up the dev environment, what the PR review SLA is, what constitutes a mergeable PR, and who the trusted committers are. Without this, contributors give up after one failed attempt.
Enable forking within the org so teams can work on changes without needing write access to the upstream. Forks within the same org remain private. PRs from forks show the originating team clearly to reviewers.
Use GitHub topics to make inner source repos discoverable: inner-source, platform-team, shared-service. Maintain an inner source portal (a hub repo or internal wiki) that lists available shared services and their contribution guides.
| Setting | Where | Value for inner source |
|---|---|---|
| Repository visibility | Repo settings | Internal (visible to all org members, not public) |
| Allow forking | Repo settings → General | Enabled |
| Base permissions for org members | Org settings → Member privileges | Read — all org members can view internal repos |
| Team access | Repo settings → Collaborators & teams | Owner team: Write/Maintain; all others: Read (contribute via fork/PR) |
The most common inner source failure is PRs that sit unreviewed for weeks. Set a published review SLA (24–48 hours for initial response) and track it. A contributing team that submits a PR and hears nothing for 2 weeks will never contribute again. The trusted committer's review response time is the single biggest predictor of inner source health.
GitHub Actions is consumption-billed. For large engineering orgs, Actions costs can grow faster than headcount as CI usage scales. Understanding the billing model, identifying waste, and setting guardrails is how platform teams keep costs predictable.
| Runner type | Rate (GitHub-hosted) | Notes |
|---|---|---|
| Linux (ubuntu-*) | $0.008 / minute | 2-core default; billed in 1-minute increments |
| Windows | $0.016 / minute (2×) | Higher due to license costs |
| macOS | $0.08 / minute (10×) | Significant — avoid for tasks that don't require macOS |
| Larger runners (4–64 core) | Proportional to core count | GitHub Enterprise only; price per minute × multiplier |
| Self-hosted runners | Free (you pay infra cost) | Break-even vs GitHub-hosted at ~500 minutes/day per runner |
| Scope | Default limit | Configurable? |
|---|---|---|
| Concurrent jobs per org | 500 (Free/Team), higher for Enterprise | Increase via GitHub Support |
| Concurrent jobs per repo | 20 (GitHub-hosted) | No |
| Job queue time before timeout | 24 hours | No |
| Job execution timeout | 6 hours (GitHub-hosted) | Via timeout-minutes: in workflow |
| API requests per repo per workflow | 1,000/hr (GITHUB_TOKEN) | Use a PAT for higher limits |
GitHub also bills for artifact and package storage beyond the free tier. Set retention-days: on artifact uploads (default 90 days, cost drops to zero at day 1 for ephemeral CI artifacts). Set up automated package version deletion for old package versions using the delete-package-versions action on a weekly schedule.