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.comis the Pocket ID UI and OIDC issuer.auth.k8s.example.comserves OAuth2 Proxy endpoints.whoami.k8s.example.comis 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
Comments
No comments yet. Start the discussion.