OAuth2 Proxy is a reverse proxy that adds authentication using providers such as Google, GitHub, or GitLab (OpenID Connect). It validates users by email, domain, or group and forwards requests to upstream services with user headers. In this guide you set up one central OAuth2 Proxy in Kubernetes so multiple services share the same authentication flow, using GitLab as the identity provider and NGINX Ingress for external auth.
In this guide you’ll: Create a GitLab OpenID Connect application and get client ID and secret; generate a cookie secret and install OAuth2 Proxy with the official Helm chart; expose the proxy via Ingress and protect other services with NGINX auth annotations.
Prerequisites: A Kubernetes cluster with kubectl and Helm, NGINX Ingress Controller (and optionally cert-manager for TLS), and a GitLab account to create an OIDC application.
How OAuth2 Proxy behaves: Requests are checked for the proxy’s session cookie (or JWT if enabled). Unauthenticated users are redirected to the provider (or get 401 for Accept: application/json). After login, tokens are stored in the session store and the request is forwarded to the upstream with user headers. Why central Ingress auth: One place to configure auth for many services, support for OAuth2/OpenID providers, single sign-on, and one redirect URL in GitLabāOAuth2 Proxy handles per-service redirects.
Table of contents
- Table of contents
- 1. Configure a GitLab OpenID application as identity provider
- 2. Generate a cookie secret
- 3. Install OAuth2 Proxy with Helm
- 4. Protect services with Ingress auth annotations
- Frequently Asked Questions (FAQ)
- Conclusion
1. Configure a GitLab OpenID application as identity provider
Create a GitLab OpenID Connect application first. Open the Applications dashboard (Admin Area or Profile preferences). Click New application and set:
nameis an application label for your referenceredirect_uriis the endpoint to which GitLab should send users after they have authenticated, and should be of the formhttps://<my-cloud-application-url>/oauth2/callbackScopesdefine what level of access the application will have to the GitLab user profile. For most applications, you will want to check openid, profile, and email.
Save the Application ID and Secret; you will use them in the Helm values.
2. Generate a cookie secret
OAuth2 Proxy uses a cookie secret to sign session cookies. Generate a Base64-encoded string for the cookieSecret in your values:
python -c 'import os,base64; print(base64.b64encode(os.urandom(16)).decode("ascii"))'
3. Install OAuth2 Proxy with Helm
Use the official Helm chart. Create a values.yaml (replace YourClientID, YourClientSecret, and the generated cookie secret; use your own domain and issuer):
config:
clientID: "YourClientID"
clientSecret: "YourClientSecret"
cookieSecret: "GenerateMe" # use output from the cookie-secret command above
configFile: |-
provider = "gitlab"
provider_display_name = "GitLab"
redirect_url = "https://oauth.example.com/oauth2/callback" # must match GitLab redirect URI
login_url = "https://gitlab.com/oauth/authorize"
redeem_url = "https://gitlab.com/oauth/token"
oidc_jwks_url = "https://gitlab.com/oauth/discovery/keys"
validate_url = "https://gitlab.com/api/v4/user"
cookie_refresh = 0
cookie_secure = true
oidc_issuer_url = "https://gitlab.com"
set_xauthrequest = true
pass_host_header = true
pass_user_headers = true
request_logging = true
extraArgs:
whitelist-domain: ".example.com"
upstream: "file:///dev/null"
cookie-domain: ".example.com"
email-domain: "*"
cookie-name: "_oauth2_proxy"
ingress:
enabled: true
path: /
hosts:
- oauth.example.com
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod-issuer
tls:
- secretName: oauth-tls-cert
hosts:
- oauth.example.com
Use your OAuth2 Proxy host for redirect_url (same as in GitLab). For other providers see OAuth2 Proxy provider docs.
Add the Helm repo and install:
helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests
helm repo update
To see available chart versions:
$ helm search repo oauth2-proxy
NAME CHART VERSION APP VERSION DESCRIPTION
oauth2-proxy/oauth2-proxy 6.16.1 7.4.0 A reverse proxy that provides authentication wi...
Install (example with chart version 6.16.1):
helm upgrade -i oauth2-proxy oauth2-proxy/oauth2-proxy \
--create-namespace \
-n oauth2-proxy \
--version 6.16.1 \
--wait \
--timeout 300s \
-f values.yaml
Verify the release:
$ helm ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
oauth2-proxy oauth2-proxy 2 2023-09-04 22:45:05.504429 +0300 EAT deployed oauth2-proxy-6.16.1 7.4.0
Confirm the pod is running:
$ k get po
NAME READY STATUS RESTARTS AGE
oauth2-proxy-6ffbcb85d7-mqcdq 1/1 Running 0 9h
Optional: with Helmfile you can define the installation as code. Create a file called helmfile.yaml with the following content:
helmDefaults:
createNamespace: true
wait: false
timeout: 300
repositories:
- name: oauth2-proxy
url: https://oauth2-proxy.github.io/manifests
releases:
- name: oauth2-proxy
namespace: oauth2-proxy
chart: oauth2-proxy/oauth2-proxy
version: 6.16.1
values:
- ./values.yaml
Then you can apply using this command:
helmfile sync oauth2-proxy
The above values result in this Ingress object:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod-issuer
kubernetes.io/ingress.class: nginx
generation: 1
labels:
app: oauth2-proxy
app.kubernetes.io/component: authentication-proxy
app.kubernetes.io/instance: oauth2-proxy
app.kubernetes.io/name: oauth2-proxy
app.kubernetes.io/part-of: oauth2-proxy
name: oauth2-proxy
namespace: oauth2-proxy
spec:
rules:
- host: oauth.citizix.com
http:
paths:
- backend:
service:
name: oauth2-proxy
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- oauth.citizix.com
secretName: oauth-tls-cert
This Ingress exposes the OAuth2 Proxy; the next section shows how to protect other services with auth annotations.
4. Protect services with Ingress auth annotations
For each service you want to protect, add the NGINX auth annotations to its Ingress. Replace oauth.example.com and the namespace with your OAuth2 Proxy host and namespace (e.g. oauth2-proxy):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: alertmanager
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/auth-signin: https://oauth.example.com/oauth2/start
nginx.ingress.kubernetes.io/auth-url: http://oauth2-proxy.oauth2-proxy.svc.cluster.local/oauth2/auth
spec:
rules:
- host: alertmanager.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: alertmanager
port:
number: 9093
tls:
- hosts:
- alertmanager.example.com
secretName: tls-cert
Visiting https://alertmanager.example.com in a browser will redirect to the GitLab login page when not authenticated.
auth-signin: URL where users are sent to log in (your OAuth2 Proxy Ingress).auth-url: Internal URL NGINX uses to check the session (OAuth2 Proxy service in its namespace).
After successful login, OAuth2 Proxy redirects users back to the protected service. You only need one redirect URL in your GitLab OIDC client (https://oauth.example.com/oauth2/callback); OAuth2 Proxy handles per-service redirects.
Frequently Asked Questions (FAQ)
What is OAuth2 Proxy?
OAuth2 Proxy is a reverse proxy that adds OAuth2/OpenID Connect authentication in front of HTTP services. It supports Google, GitHub, GitLab, and other providers, and can validate users by email, domain, or group. It is often used with NGINX Ingress auth-url and auth-signin for central auth in Kubernetes.
Can I use Google or GitHub instead of GitLab?
Yes. Use the OAuth2 Proxy provider docs and set provider, redirect_url, login_url, redeem_url, and any provider-specific options in configFile and extraArgs in your Helm values.
Why use one central OAuth2 Proxy?
One proxy means one OIDC application and one redirect URL in your identity provider. You protect many Ingress hosts by adding the same two annotations and point them at the central proxy. Session and cookie configuration live in one place.
Where should I store the client secret?
Store the GitLab client secret in a Kubernetes Secret and reference it in your Helm values (e.g. config.existingSecret). Do not commit the secret to Git.
Conclusion
You set up one central OAuth2 Proxy in Kubernetes with GitLab as the identity provider: created a GitLab OIDC application, generated a cookie secret, installed the proxy with the official Helm chart and a custom values.yaml, and protected another service by adding NGINX Ingress auth-signin and auth-url annotations. This reduces authentication complexity and keeps a single redirect URL in GitLab. For protecting internal sites with Google Auth outside Kubernetes, see How to set up OAuth2 Proxy to protect internal sites with Google Auth.