RedlineKnowledge base

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.

Git history

Loading the page's history…