I have several services deployed and exposed on my Kubernetes cluster. Some of them need to be publicly accessible, while others should remain private. On top of that, I don’t fully trust the built-in security of some apps, so I decided to add an extra layer of protection with OAuth2-Proxy.
Setup
I already had a Zitadel instance running, along with an Ingress controller and Cert-Manager.
The first service I wanted to secure was the Kubernetes Dashboard. I deployed OAuth2-Proxy and configured it. At first, I mistakenly set up an internal upstream. This worked fine for the dashboard itself, but not for other apps - since OAuth2-Proxy only supports a single upstream.
That’s when I realized I had configured OAuth2-Proxy as a reverse proxy, instead of just as an authentication layer. I removed the upstream setting and instead defined allowed domains.
One important detail: when setting domain values, you must include the leading dot (e.g., .domain.tld). Without it,
subdomains won’t be allowed through OAuth2-Proxy.
Here’s my final configuration:
| |
You also need to provide the following environment variables. While you could set them directly in the config file, I prefer to keep them in 1Password and sync them into my namespace as Kubernetes secrets — for better security and easier management:
| |
Note: If you’re using Let’s Encrypt staging certificates, you’ll need to set ssl_insecure_skip_verify = true.
Once you switch to production certificates, you can (and should) set it back to false.
Adding OAuth2-Proxy to Ingress
Once OAuth2-Proxy was properly configured and I could log in with my Zitadel account, I integrated it with my Ingress. After a bit of trial and error, I ended up with this setup, which now works reliably across all my services:
| |
Depending on the service, I sometimes add these extra annotations:
| |
This setup is based on the official Ingress NGINX OAuth2-Proxy guide, with a few tweaks to fit my use case.