ARCHITECTURE BRIEF

Secure access for GitHub, at the level your reviewers will ask about.

Scope: the human, administrative and continuous-integration paths to source code. Audience: security architects and platform engineers. Applies to GitHub Enterprise Server 3.x and GitHub Enterprise Cloud. Every scenario below names its residual risk, because a control write-up without one is a sales deck.

Authentication answers who. It does not answer from where.

the thesis

GitHub authenticates credentials well. It does not evaluate where a credential is presented from, which device presents it, or whether the network path carrying it should exist. Personal access tokens, SSH keys, OAuth tokens and app installation tokens are bearer secrets: each is valid from any network until it expires or is revoked. InstaSafe adds a network-path control and a device control in front of GitHub's own authentication, and nothing behind it changes.

  • On Enterprise ServerEvery pre-authentication listener moves behind a gateway that uses single-packet authorisation, so the appliance has no public surface and the population able to attempt an exploit shrinks from the internet to your enrolled fleet.
  • On Enterprise CloudInstaSafe is the SAML identity provider for the enterprise, and the gateway's static egress address is the only entry in GitHub's IP allow list. GitHub itself performs the refusal.
  • What is genuinely newTwo independent checks on every request, in series, owned by two different parties. Either can refuse, and neither depends on the other being configured correctly.
GitHub decides
  • Is this credential valid and unexpired?
  • Does this identity hold the role the action needs?
  • Has single sign-on authorised this token?
  • Is this push breaking a protected-branch rule?
GitHub does not decide
  • Which network is this credential arriving from?
  • Is the device encrypted, patched and protected?
  • Should a path from this machine exist at all?
  • Is this the laptop that enrolled, or a copy of its token?
exposure inventory

The default state, with nothing in front.

Bound means GitHub limits the credential to a device or a network by itself. Read the last column first: it is the same answer seven times.

Enterprise Server appliance: 4 of 5 ports answer before anybody authenticates. A scanner reaches every one of these before anybody authenticates. Nothing binds the credential to a device or a network.

SurfacePortEnterprise Server, internet-facingEnterprise CloudCredentials acceptedBound
Web interface and SAML endpoints443Reachable before authenticationgithub.com, publicPassword with a second factor, SAML session cookieNo
git over HTTPS443ReachableReachablePersonal access token, classic or fine-grained; OAuth token; app installation tokenNo
git over SSH22ReachableReachableUser SSH key, deploy keyNo
REST and GraphQL API443ReachableReachablePersonal access token, OAuth token, app installation token, the workflow tokenNo
Administrative shell122Reachable unless filteredNot applicableAdministrator SSH keyNo
Management console8443Reachable unless filteredNot applicableConsole passwordNo
Unauthenticated git protocol9418Anonymous read if private mode is offNot applicableNonen/a

Enterprise Cloud can bind every one of these credential types to a network, with its IP allow list. The feature needs a stable, trusted source address, and a remote developer does not have one. Supplying that address is the whole of what the Cloud pattern below does.

threat scenarios

Eight scenarios, each with the risk that is left over.

What is exposed, how it is exploited, what it costs, where GitHub's own control stops, what InstaSafe changes, and what remains afterwards.

T1 A leaked bearer credential used from the attacker's own network

Stopped at the network path. Residual reach: the code.

Exposure
Personal access tokens, SSH keys and OAuth tokens are valid from any address.
Attack path
The secret surfaces in a public repository, a build log, a laptop backup or a third-party breach, and the holder clones from their own infrastructure. In April 2022, OAuth user tokens issued to the Heroku and Travis CI integrations were stolen and used to download private repositories from a number of organisations.
Impact
Source code and the secrets embedded in it are taken, and those secrets become a pivot into cloud accounts. In the 2022 case an access key found inside downloaded repositories was used against a package registry.
Where GitHub stops
Token expiry, fine-grained tokens, single sign-on authorisation of tokens and secret scanning all limit a token's lifetime and scope. None of them limits where a valid token may be used, with the one exception of the Enterprise Cloud IP allow list.
What InstaSafe changes
On Server there is no route to the appliance without an authorised agent session, so the token cannot be presented at all. On Cloud the allow list holds the gateway's egress address and only authenticated, posture-checked agents reach the gateway.
Residual
A credential used from an authorised device, whether by an insider or by malware on an enrolled endpoint. Tokens held by allow-listed third-party applications, used from those applications' own infrastructure.

T2 A pre-authentication exploit against an internet-facing appliance

Stopped at the network path. Residual reach: GitHub itself.

Exposure
On Enterprise Server the web and SAML endpoints, SSH, and the management console where it is unfiltered, all answer before anybody authenticates.
Attack path
A single unauthenticated request to a vulnerable endpoint. CVE-2024-4985, published in May 2024 and scored 10.0, let an unauthenticated attacker forge a SAML response and obtain site administrator on an instance with encrypted assertions enabled. It was fixed in 3.13.0 and in patch releases of the supported 3.9 to 3.12 lines.
Impact
Instance compromise: code read and tampered with, a foothold in whatever that code builds, and the credentials stored on the appliance.
Where GitHub stops
Patching, private mode and perimeter firewall rules. The exposure window runs from disclosure to the patch landing, and single sign-on requires the SAML endpoint to stay reachable throughout.
What InstaSafe changes
The appliance keeps no public listener and the gateway drops every packet until a valid authorisation packet arrives from an enrolled client. Pre-authentication endpoints become reachable only from authorised devices.
Residual
An authorised user, or a compromised enrolled device, can still reach a vulnerable endpoint. Patching cadence remains a requirement, not an optimisation.

T3 A stolen single-sign-on session, or phished credentials

Stopped at the device. Residual reach: the code.

Exposure
Identity provider and GitHub session cookies can be replayed from another host.
Attack path
A phishing kit sitting in the middle of the exchange captures the live session and replays it from the attacker's infrastructure before it expires.
Impact
Web and API access carrying the victim's rights.
Where GitHub stops
SAML single sign-on, two-factor authentication and session lifetime. A captured session can still be replayed from any network inside that lifetime.
What InstaSafe changes
On Server the replaying host has no path to the appliance. On Cloud the allow list rejects a request from an address that is not on it. InstaSafe's own second factor, push approval or a hardware security key, is tied to the enrolled device.
Residual
An attacker operating on the victim's own enrolled device.

T4 A clone onto an unmanaged or non-compliant endpoint

Stopped at the device. Residual reach: the code.

Exposure
GitHub has no device signal of its own.
Attack path
A contractor clones to a personal laptop with no disk encryption. The laptop is lost, sold or infected.
Impact
Repository contents sitting at rest on a device nobody controls.
Where GitHub stops
None by default. The exception is identity-provider conditional access used with Enterprise Managed Users, which is a narrower configuration than most estates run.
What InstaSafe changes
Posture is evaluated before the path opens, across disk encryption, operating system patch level, endpoint protection, screen lock and agent integrity, and evaluated again during the session, so access ends when a device drifts out of policy.
Residual
A compliant device compromised later in its posture window. Anything already cloned stays on that disk.

T5 The deprovisioning gap

Stopped at the directory. Residual reach: the code.

Exposure
SSH keys and personal access tokens on a GitHub account survive the user's removal from the directory.
Attack path
A leaver, or anybody holding a leaver's key or token, keeps working git access after the exit interview.
Impact
Unauthorised access after offboarding, attributed to a former employee.
Where GitHub stops
Directory-driven deprovisioning, and revocation of single-sign-on-authorised credentials when the SAML identity is unlinked. Coverage depends on what the provisioning integration actually covers, on credentials that were never tied to single sign-on, and on outside collaborators.
What InstaSafe changes
Disabling the user in the directory revokes the InstaSafe session and closes the path, whatever credentials remain on the GitHub side.
Residual
On Enterprise Cloud, a credential stays usable from an allow-listed third-party application's own addresses. Clean up on the GitHub side as well.

T6 Network-wide reach handed to a contractor by a VPN

Stopped at the network path. Residual reach: GitHub itself.

Exposure
A VPN profile grants network-layer reach to whole subnets.
Attack path
Malware on a contractor's device scans the subnet and moves from the segment holding the git server to other hosts on it.
Impact
Compromise that extends well beyond source code.
Where GitHub stops
Outside GitHub's scope entirely.
What InstaSafe changes
Access is scoped to the application rather than the network: the appliance's 443 and 22, no subnet route, plus time windows and an end date attached to the policy.
Residual
What a user can do once inside GitHub is still governed by GitHub's own roles and branch protections.

T7 The administrative plane on Enterprise Server

Stopped at the network path. Residual reach: GitHub itself.

Exposure
The administrative shell on 122 and the management console on 8443.
Attack path
A console password guessed at leisure, or a stolen administrator SSH key.
Impact
Appliance-level control: configuration, backups and the authentication settings themselves.
Where GitHub stops
Strong passwords and network filtering, where that filtering is usually drawn broadly because the admin plane is used rarely and urgently.
What InstaSafe changes
A separate application with its own policy: the admin group only, from a managed device, with a fresh second factor. Developers hold no route to 122 or 8443 at all.
Residual
A compromised administrator device.

T8 Continuous-integration runners and integrations

Not stopped in the path; scoped instead. Residual reach: the code.

Exposure
Runner registration tokens, the per-job workflow token, and hosted services that need to reach a self-hosted instance.
Attack path
A stolen registration token enrols a rogue runner. A compromised runner host reads whatever it checks out. Hosted runners cannot be pinned to an allow list because their addresses change.
Impact
Code read, and the pipeline that builds it tampered with.
Where GitHub stops
Runner groups, ephemeral runners and federated tokens to cloud providers. None of it gives standard hosted runners a stable address.
What InstaSafe changes
Self-hosted runners sit in the gateway's network, or run a headless agent under a non-human identity scoped to GitHub alone. On Enterprise Cloud, GitHub's larger runners with static addresses can be allow-listed beside the gateway.
Residual
InstaSafe does not sandbox a job, so hardening the runner host stays with you. An inbound integration to a hidden appliance needs an explicit design.

Four components, and which plane each one sits in.

The split matters for a privacy review: the controller decides and the gateway carries, and they are not in the same place.

components _ control architecture
  • Controller · control planeAuthenticates, evaluates policy, issues access. Carries no repository traffic.
  • Gateway · data planeYour network, beside the appliance or at a static cloud address. Silent without a valid packet.
  • Agent · endpointSigns in, reports posture, sends the packet, tunnels the flow. Headless on runners.
  • Identity provider · identityYour directory, unchanged. InstaSafe is GitHub's SAML provider and federates back to it.

Git traffic goes from the laptop to your gateway to the destination. It does not transit InstaSafe infrastructure, which is the line that decides this for most code-sensitive teams.

The access sequence, end to end.

Six steps. The client-side invariant is in step four and it is the one to check in a proof of concept: no proxy command, no git proxy setting, no rewritten remote.

  1. AUTHENTICATEThe user authenticates to the agent against the identity provider, then passes a second factor: push approval, a one-time code or a hardware security key.
  2. EVALUATEThe controller evaluates group, device posture, time window, location and source address. On failure the agent names the check that failed rather than returning a generic denial.
  3. AUTHORISE THE PATHThe agent sends one authorisation packet to the gateway, which opens for that client alone. Before this point the gateway has not responded to it at all.
  4. CARRY THE FLOWgit, API and web flows to permitted destinations run through the encrypted tunnel. Remote URLs, SSH configuration and git configuration are untouched.
  5. GITHUB DECIDESGitHub authenticates the key or token exactly as before. Two independent checks have now run in series, owned by two parties.
  6. RECORDThe session is logged with user, device, posture result, destination, start and end, and exported to your monitoring platform.
pre-authentication surface

What an unknown client gets back, before it logs in.

This is the column a reviewer should care about most, because it decides how large the population attempting an exploit can be.

DesignResponse to an unknown clientgit over SSHClient-side git changes
Network VPNThe concentrator answers. After login the user reaches the whole subnet.NativeNone
Tunnel with an identity-aware reverse proxyA public hostname serves a login pageA second hostname with a proxy command, or a browser terminalSSH config
Per-protocol proxy with a local client proxyDepends on the access tierA separate SSH service and a wildcard domainA per-URL git proxy setting and a rewritten SSH config
InstaSafe gateway with single-packet authorisationNone. Packets are dropped.Native, through the agentNone

Compiled from each vendor's own published setup guide for self-hosted git. Where a tier changes the answer, the table says so rather than picking the flattering tier.

pattern a, enterprise server

Pattern A, Enterprise Server: one application per port.

Path: agent, then gateway, then appliance. The appliance holds a private address and nothing else.

Enterprise Server appliance: no port answers until the gateway has authorised the client. Gets no reply. The gateway drops every packet until an authorisation packet arrives from an enrolled client.

pattern a _ ghes
  • 443 · ghes-webWeb, git over HTTPS, API. Developers and contractors, posture pass, second factor.
  • 22 · ghes-sshgit over SSH. The same audience and policy as 443.
  • 122 · ghes-admin-sshAdministrative shell. Admin group, managed device, fresh second factor.
  • 8443 · ghes-consoleManagement console. The same administrator-only policy as 122.
  • 9418 · not publishedUnauthenticated git protocol. Enable private mode as well.

Pattern A, in the order that keeps a rollback available.

Public ingress comes off last, after the teams have moved. Until that step every change is reversible by stopping.

  1. GATEWAYSDeploy two gateways in the appliance's subnet and permit gateway to appliance on 443, 22, 122 and 8443. Leave the existing public rules in place for now.
  2. APPLICATIONSCreate the five applications above and bind each one to both gateways, so a gateway failure is a failover rather than an outage.
  3. SINGLE SIGN-ONManagement console, then Authentication, then SAML, with InstaSafe as the identity provider. Keep one built-in site administrator for recovery, and do not enable encrypted assertions unless you are on a release that carries the CVE-2024-4985 fix.
  4. PRIVATE DNSResolve the appliance's existing hostname to its private address for agent clients. The hostname and every clone URL stay as they are.
  5. MIGRATE, THEN CLOSEMove users team by team. Then remove all internet ingress and release the public address. A laptop without the agent should now get a timeout, not a refusal: a refusal means something is still answering.

GitHub Connect calls github.com outbound and is unaffected. A hosted service that calls into the appliance loses reachability at the last step, so inventory those before you take it.

pattern b, enterprise cloud

The destinations that have to leave from one address.

Path: agent, then gateway, then the gateway's static egress address, then github.com. GitHub enforces the allow list; InstaSafe controls who gets to use the address on it.

7published destinations leave through one gateway and one static address, so GitHub's allow list holds a single entry.

  • github.comWeb interface, git over HTTPS, git over SSH
  • api.github.comREST, GraphQL, the gh command line
  • codeload.github.comArchive downloads
  • objects.githubusercontent.comLarge File Storage, release assets
  • raw.githubusercontent.comRaw file reads
  • uploads.github.comRelease uploads
  • ghcr.io and *.pkg.github.comGitHub Packages and the container registry

Check this list against GitHub's own meta endpoint before go-live and after any GitHub estate change. It is GitHub's to alter, not ours, and a destination missing from your gateway is a developer whose clone hangs.

Pattern B, in the order that does not lock the owners out.

The allow list applies to every role, enterprise owners included, so it is the last step and it needs a tested way back in before it is taken.

  1. A FIXED EXITDeploy the gateway in a cloud subnet with a static public address, IPv4 and IPv6 where one is assigned, and publish the destinations above so agent flows to them leave from it.
  2. SINGLE SIGN-ONConfigure SAML at the enterprise level, so every organisation inherits it rather than being configured one at a time. Pilot, then require.
  3. RUNNERSMove private-repository workflows to self-hosted runners that leave through the gateway, or to larger runners with static addresses. This has to be finished before the next step, not during it.
  4. THE ALLOW LISTEnterprise settings, then Authentication security, then the IP allow list. Add the gateway and a break-glass range you have already tested, validate both with GitHub's check-IP tool, then enable. Decide deliberately whether installed GitHub Apps may contribute their own addresses.

What the allow list switches off on the way in.

Each of these is GitHub's behaviour, not a limitation of the pattern. They are listed so a pilot plan can absorb them rather than discover them.

side effects _ allow list
0 of 6 markedtick the ones your estate actually uses, and bring the list to the design review

Residual risk and exclusions.

The same list the eight scenarios end on, gathered in one place so it can be lifted into a risk register without reading the brief twice.

  • CODE CONTENTInstaSafe does not inspect repository content or block a secret in a commit. Keep secret scanning and push protection switched on.
  • A CLONE ON DISKA permitted user on a compliant device can keep a clone. Optional in-session controls over clipboard, screenshot and removable storage reduce casual copying; they do not prevent a clone.
  • GITHUB.COM ITSELFInstaSafe does not hide github.com. On Enterprise Cloud the allow list is GitHub's control, and InstaSafe secures the path to the address on it.
  • THIRD-PARTY TOKENSA token held by an allow-listed application remains usable from that application's own infrastructure, which is the cost of allow-listing it.
  • A COMPROMISED DEVICEAn enrolled device inside its posture window holds exactly the access its user holds. Continuous evaluation shortens that window; it does not remove it.
  • JOB ISOLATIONIsolating a continuous-integration job and hardening the runner host are outside InstaSafe's scope and stay with your platform team.

Operations, once it is running.

The six answers an operations review asks for, in the order it tends to ask them.

operations _ github
  • Logging format and fieldsCEF, newline-delimited JSON or syslog. User, device, posture result, destination, source, start, end.
  • Source address in GitHub's logOn Cloud it is the gateway's, for everybody. Join user and device from the InstaSafe log.
  • AvailabilityTwo gateways per site. Clients fail over without intervention.
  • CapacitySize for clone, Large File Storage and package throughput, not request count.
  • Policy as codeApplications, policies and users through the InstaSafe API and Terraform.
  • Contractor accessWeekday windows and an end date. An open session closes at the cut-off.

Write the user-and-device join into your detection content before go-live, not after the first investigation. On Enterprise Cloud it is the only thing standing between one shared source address and an unattributable clone.

verification

Six tests. Run them before you sign it off.

A control nobody tested is a control nobody has. The second column is the part people skip: the test only means something from the right place.

CheckRun it fromCommandExpected
Appliance is unreachableAn external host, no agentnmap -Pn -p 22,122,443,8443,9418 <ghes-host>All filtered, and no reset packets
Gateway is silentAn external host, no agentnc -vz -w5 <gateway-ip> 443Timeout, with zero response packets
Developer access is unchangedA laptop with the agent onssh -T git@<ghes-host>Succeeds with no change to SSH or git configuration
A Cloud token off the pathA laptop with the agent offgit ls-remote https://github.com/<org>/<private>.gitRefused, with an IP allow list error
Cloud SSH off the pathA laptop with the agent offgit clone git@github.com:<org>/<private>.gitRefused
A leaver's credentialsA laptop, user disabled in the directorygit clone # with a still-valid token and SSH keyRefused on both platforms

Test four is the one that catches a half-finished rollout. If it succeeds with the agent off, the allow list is saved but not enforcing, and every other control on this page is resting on an assumption.

audit recordactormeera@acme.comresourceprod-db-01decisionALLOW · step-upapproved bys.callawaysessionrecorded · 14m 22sSIGNEDsha2569f2c…a41e
WHAT A REVIEW CAN CONFIRM

Three claims,each with a test beside it.

The brief is written so that a reviewer can refuse it on evidence rather than on taste.

No pre-auth surface

A port scan of the appliance and a connection attempt to the gateway both return nothing, from outside, with no agent.

The credential is bound

A valid token and a valid SSH key are both refused off the path, and both work on it, from the same machine minutes apart.

The session is attributable

Every grant carries user, device and posture result into your monitoring platform, which is what closes the gap GitHub's single source address opens.

//Ready when you are//

Bring the design review, and the objections.

A session with an architect rather than a demo: your plan, your identity provider, your runner estate, and the six verification tests run against a test organisation or appliance.

Regulated, air-gapped, or on-premise? See deployment options