Independent comparison · no paid rankings
Home / Blog / Technical / OAuth proxy: protect an internal tool without rewriting authentication

OAuth proxy: protect an internal tool without rewriting authentication

Grafana, Jenkins, phpMyAdmin — tools without native SSO rushed online. An OAuth proxy adds a front door without rewriting the app.

Hébergeurs.eu Editorial Team 3 min read

The team exposes Grafana in three "temporary" clicks for an audit. No native SSO, default admin password changed "later". Two weeks later port 443 still faces the Internet with homemade basic auth easy to brute-force.

An OAuth proxy puts authentication where legacy apps cannot — in front, not inside.

Typical architecture

Client → TLS terminator → oauth2-proxy → upstream app. Flow: IdP redirect → callback → encrypted cookie → app access.

App stays internal HTTP; only edge is exposed.

Secure configuration

Cookie: Secure, HttpOnly, SameSite=Lax minimum. Rotatable --cookie-secret. Restrict --email-domain or OIDC groups.

Never expose upstream directly without parallel auth — instant bypass.

Headers and trust

Pass X-Forwarded-User/Email/Groups. App must not trust these from the world; firewall: proxy only.

For app RBAC, map OIDC claims → headers or separate proxy paths.

Special cases

Inbound webhooks: auth bypass route with separate HMAC secret.

Machine API: not oauth2-proxy — mTLS or dedicated API token.

Health checks: /health without auth for LB, no sensitive data.

Operations

Centralize auth failure logs. Session expiry matches company policy. Document offboarding: revoke IdP sessions + rotate cookie secret if sensitive departure.

Deployment checklist

  1. Upstream app not directly reachable from Internet
  2. Cookie Secure HttpOnly SameSite configured
  3. Restrictive --email-domain or OIDC groups
  4. Listed bypass routes (health, webhook HMAC)
  5. X-Forwarded-* trusted app-side from proxy only
  6. WebSocket tested end-to-end
  7. Session expiry aligned with HR policy
  8. Centralized auth failure logs
  9. Documented offboarding procedure
  10. Cert renewal tested without mass logout

Validate with internal "bypass proxy" pentest — if success, fix network before announcing SSO.

Team integration and lifecycle

Onboarding: new engineer gets IdP access + proxy path doc — not direct upstream URL. Offboarding: revoke IdP and invalidate session cookies (rotate cookie-secret if sensitive departure).

Multi-environment: staging oauth2-proxy to staging IdP app registration — do not share prod/staging client_id.

Observability: oauth-proxy 401/403 vs upstream 502 metrics — distinguish auth fail vs app down.

Limits: oauth2-proxy does not replace fine authorization (app RBAC) — it authenticates, app still authorizes.

Multiple internal tools (Grafana + Prometheus + Kibana): one oauth2-proxy per upstream or central Traefik forward auth — both work, do not mix cookie secrets.

Session length vs idle timeout: align with data sensitivity (prod logs vs HR wiki).

Break-glass local account disabled by default, enabled via break-glass procedure only — no forgotten backdoor.

High availability

Two oauth2-proxy instances behind load balancer with shared cookie secret — session sticky or encrypted cookie works stateless.

IdP outage impact : document fallback read-only mode or maintenance page — SSO dependency explicit.

Health check oauth2-proxy /ping excluding upstream — LB removes bad proxy nodes only.

Operational summary

OAuth proxy adds SSO in front of legacy apps — secure cookies, no direct upstream access, bypass routes documented. WebSocket and cert renewal tested. IdP outage runbook explicit.

Production readiness

Load test login flow peak Monday morning. Verify cookie expiry matches HR policy. Pen test bypass attempt documented closed. Backup auth break-glass tested quarterly.

SSO rollout narrative

Rolling out oauth2-proxy across three internal tools took one sprint when the network path was already correct — and three when upstream apps remained reachable by IP. The difference was not OAuth complexity but firewall rules and team habit. Treat SSO as a network project with an OAuth front, not purely an identity integration.

Document the happy path login in under thirty seconds for a new engineer. If ProxyJump plus oauth2-proxy plus MFA exceeds two minutes, adoption leaks around the control via shared credentials — worse than before.

Review cookie settings after every security audit. SameSite changes in browsers have broken cross-subdomain setups that worked for years.

Network SSO

Upstream reachable by IP = SSO bypass. Document login <30s.

Decide and move forward without blind spots

  1. Block direct Internet access to upstream app — only the proxy should be publicly reachable.
  2. Configure Secure HttpOnly SameSite cookies — list bypass routes (health, HMAC-signed webhooks).
  3. Restrict OIDC domains or groups — session expiry aligned with HR policy, centralized auth logs.
  4. Test WebSocket end-to-end — trust X-Forwarded-* from proxy only.
  5. Pentest proxy bypass — documented offboarding, cert renewal without mass logout.

Compare hosting suited to SSO stacks via our directory and guides.

Frequently asked questions

oauth2-proxy vs classic reverse proxy?

oauth2-proxy handles OAuth/OIDC flow and sets session cookie; plain nginx does not validate IdP identity without extra modules.

Does the app see the real user?

Via X-Forwarded-User/Email/Groups if configured — app must trust them only from the proxy (network ACL).

WebSockets?

Enable upstream WebSocket on nginx/traefik; oauth2-proxy must allow upgrade routes with same session cookie.

Misconfiguration risk?

Bypass via wide IP whitelist, cookie without Secure/HttpOnly, or app accepting spoofed headers from Internet.


Before announcing "SSO enabled", try reaching upstream without the proxy — if it works, you are not done.

Compare European hosts

Filter by compliance, location and use case — then open the sheets to verify the real scope.

Browse the directory
Blog

Related reading

All articles →