Protect Kubernetes Services with OAuth2 Proxy, Gateway API, Traefik, and Pocket ID
DEV Community

Protect Kubernetes Services with OAuth2 Proxy, Gateway API, Traefik, and Pocket ID

My previous guide used ingress-nginx annotations to put internal Kubernetes services behind OAuth2 Proxy. It was written for an ingress-nginx setup. That controller is being retired, and Gateway API is the direction Kubernetes recommends for new traffic management work. This post rebuilds the same authentication flow with Gateway API, Traefik, OAuth2 Proxy, and Pocket ID.

Why Traefik? Gateway API standardizes Gateway and HTTPRoute, but it does not standardize browser-based OIDC login or an external-auth filter. This setup uses Traefik's Middleware CRD for those pieces. With Envoy Gateway, Kong, Cilium, or another implementation, the Gateway API resources can stay, but the authentication adapter must change.

What We Are Building

This setup exposes three HTTPS hostnames below one domain:

  • pocket-id.k8s.example.com is the Pocket ID UI and OIDC issuer.
  • auth.k8s.example.com serves OAuth2 Proxy endpoints.
  • whoami.k8s.example.com is a protected demo service.

One parent domain lets OAuth2 Proxy use a narrowly scoped shared session cookie, such as .k8s.example.com. Do not set the cookie domain to a wider parent domain when unrelated applications use it.

sequenceDiagram
    autonumber
    participant B as Browser
    participant T as Traefik Gateway
    participant O as OAuth2 Proxy
    participant P as Pocket ID
    participant S as whoami
    B->>T: GET whoami.k8s.example.com
    T->>O: ForwardAuth /oauth2/auth
    O-->>T: 401 (no session)
    T-->>B: 302 /oauth2/sign_in?rd=...
    B->>O: Start sign-in
    O->>P: OIDC authorization request
    P-->>B: Authenticate with passkey
    P-->>O: Callback with authorization code
    O-->>B: Set session cookie and redirect back
    B->>T: Repeat original request
    T->>O: ForwardAuth /oauth2/auth
    O-->>T: 202 + identity headers
    T->>S: Forward authenticated request
    S-->>B: Protected response /oauth2/auth only checks a session: it returns 202 when one is valid and 401 otherwise. Traefik's Errors middleware turns that 401 into the browser redirect to OAuth2 Proxy. That separate redirect step is the most important difference from the old ingress-nginx annotations.

Before You Start

Before you start, I verified the authentication flow on a local K3s cluster. The commands below use standard Kubernetes and Helm commands, so they are not tied to that local environment. Start with a running cluster, kubectl, and Helm.

You also need DNS for `*.k8s

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.