Skip to content

mdbook oauth

TL;DR: mdBook outputs static files, so you add OAuth at the edge or proxy. Fastest managed route: Cloudflare Access in front of your mdBook host. Most portable self-hosted route: NGINX + oauth2-proxy using auth_request. Traefik and Caddy have equivalent forward-auth patterns. Cloud-native gates: GCP IAP or AWS CloudFront + Cognito. All work on mobile because they use standard OAuth/OIDC browser flows. mdBook issue #1212 Cloudflare Access docs oauth2-proxy Integration Caddy forward_auth GCP IAP overview AWS OIDC with CloudFront

— Recommended choices by constraint Cloudflare Access docs oauth2-proxy Integration GCP IAP overview

  • Zero infra, minutes to live, SSO with Google/GitHub/One-time PIN: Cloudflare Access in front of your mdBook origin or Cloudflare Pages. Mobile friendly and works with any static host. Cloudflare Access docs
  • Kubernetes, Docker, classic VM with NGINX: oauth2-proxy + NGINX auth_request. Supports many IdPs (GitHub, Google, OIDC). Good defaults, proven pattern. oauth2-proxy Integration
  • Traefik or Caddy stacks: ForwardAuth to oauth2-proxy or Authelia. Pick Caddy if you like simple Caddyfile, Traefik if you live in labels/CRDs. Traefik thread Caddy forward_auth Authelia Caddy integration
  • Cloud-native gates with per-request JWTs and org policies: GCP IAP or AWS CloudFront + Cognito/Lambda@Edge. Use when you already standardize on these clouds. GCP IAP overview AWS Authorization@Edge

— Option A: NGINX + oauth2-proxy (most common, self-hosted) oauth2-proxy Integration

  1. Run oauth2-proxy next to your static fileserver (or even in front of it).
  2. NGINX uses auth_request to call /oauth2/auth. 202 means pass, 401 means redirect to /oauth2/start. oauth2-proxy Integration

Example NGINX (protect all pages) server { listen 443 ssl http2; server_name docs.example.com;

location = /oauth2/auth { internal; proxy_pass http://oauth2-proxy:4180/oauth2/auth; proxy_set_header Host host;proxysetheaderXOriginalURIhost; proxy_set_header X-Original-URI request_uri; proxy_set_header X-Real-IP remoteaddr;proxysetheaderXSchemeremote_addr; proxy_set_header X-Scheme scheme; }

location / { auth_request /oauth2/auth; error_page 401 = @oauth2_signin; # Pass through auth headers for upstream apps if needed auth_request_set useruser upstream_http_x_auth_request_user; proxy_set_header X-Auth-User user; root /var/www/mdbook; # static mdBook output try_files uri $uri/ /index.html; }

location @oauth2_signin { return 302 https://docs.example.com/oauth2/start?rd=$scheme://$host$request_uri; }

location /oauth2/ { proxy_pass http://oauth2-proxy:4180; } } oauth2-proxy Integration

oauth2-proxy env (GitHub as IdP) OAUTH2_PROXY_PROVIDER=github OAUTH2_PROXY_CLIENT_ID=… OAUTH2_PROXY_CLIENT_SECRET=… OAUTH2_PROXY_COOKIE_SECRET=<32b base64> OAUTH2_PROXY_EMAIL_DOMAINS=* OAUTH2_PROXY_WHITELIST_DOMAINS=docs.example.com OAUTH2_PROXY_REDIRECT_URL=https://docs.example.com/oauth2/callback oauth2-proxy Integration

— Option B: Cloudflare Access (fastest managed) Cloudflare Access docs

  1. Put your mdBook at docs.example.com behind Cloudflare.
  2. Create an “Access” application with policy: Allow emails in your org domain, or specific GitHub teams or Google groups.
  3. Cloudflare injects a signed CF-Access JWT on requests that pass Access. No origin changes required. Mobile login is handled in the browser. Cloudflare Access docs

— Option C: Traefik ForwardAuth with oauth2-proxy Traefik thread Static middleware:

  • ForwardAuth address: http://oauth2-proxy:4180/oauth2/auth
  • Trust forward headers, preserve X-Forwarded-Proto, and set authResponseHeaders to pass user info like X-Auth-Request-Email. oauth2-proxy Integration

— Option D: Caddy + Authelia Caddy forward_auth Authelia Caddy integration Caddyfile sketch: example.com { route { forward_auth authelia:9091 { uri /api/verify?rd=https://example.com copy_headers X-Forwarded-User X-Forwarded-Groups } file_server { root /srv/mdbook } try_files {path} {path}/ /index.html } } Caddy forward_auth Authelia Caddy integration

— Option E: GCP Identity-Aware Proxy GCP IAP overview

  • Host mdBook on a HTTPS backend (GCE NGINX, GKE Ingress, or Cloud Run).
  • Enable IAP on the load balancer or service, bind access to Google identities or groups.
  • IAP injects a X-Goog-Authenticated-User-* header and a signed JWT for verification if you need app-level checks. GCP IAP overview

— Option F: AWS CloudFront + Cognito (or any OIDC) AWS OIDC with CloudFront Authorization@Edge

  • Serve mdBook from S3 through CloudFront.
  • Use Cognito Hosted UI for login, store tokens in cookies, validate at the edge with Lambda@Edge before fetching from S3. Block direct S3 access with OAC or bucket policies. AWS OIDC with CloudFront Authorization@Edge

— Security checklist oauth2-proxy Integration Cloudflare Access docs GCP IAP overview

  • Redirect URIs: match scheme, host, path exactly in your IdP.
  • Cookies: secure, HTTPOnly, SameSite=Lax or as required by your provider.
  • Cache: do not cache 302 login redirects at the CDN.
  • Buckets: deny public S3 or GCS bucket reads if you front with CloudFront or IAP.
  • Headers: pass X-Forwarded-* consistently to keep callback URLs correct behind TLS terminators. oauth2-proxy Integration

— Mobile UX notes Cloudflare Access docs All options use standard OAuth in the browser. They work on iOS and Android. Cloudflare Access and IAP are the least finicky on mobile since they control the whole redirect loop and cookie settings. Cloudflare Access docs GCP IAP overview

My pick for you: if you want minimal ops and immediate SSO, use Cloudflare Access in front of your mdBook host. If you already run NGINX or Traefik, use oauth2-proxy with auth_request or ForwardAuth for full control. Cloudflare Access docs oauth2-proxy Integration