ADR-0001 · GitLab OAuth is the identity on a private network
Status: Accepted, 2026-10-10.
Context
The service was built behind Cloudflare Access, with GitLab OAuth bound to the
Access identity. The experiment runs on the tailnet without Access or Tunnel.
The only other way to run without Access was REQUIRE_ACCESS=false, which
trusts a forgeable Cf-Access-Authenticated-User-Email header.
Decision
IDENTITY_MODE=gitlab-oauth makes GitLab OAuth the only user identity: the
Cf-Access-* headers are never read, connecting GitLab needs no prior
identity, and the session’s email is the GitLab user’s. Cookie names and the
Secure attribute follow the scheme of PUBLIC_SERVICE_URL. Production in
this mode requires an HTTPS service URL. cloudflare-access stays the default
and keeps its rules.
Why
Every write must end in GitLab attributed to the person who made it, and OAuth does exactly that. The network is the perimeter, so a second identity layer adds nothing, while a header-trust path would add a forgery risk.
Consequences
Reads are governed by ALLOW_ANONYMOUS_READ as before. The Access path stays
tested but is not deployed. A Tailscale-header identity remains a documented
alternative if OAuth on the tailnet ever fails.
Evidence
95e32bc, e883aea; test/identity-mode.test.js, test/e2e/oauth.spec.js.
Revisit when
The service is exposed beyond the tailnet, or a reader population without GitLab accounts needs access.