How to Set Up OAuth2 Proxy for Central Authentication in Kubernetes with GitLab

Use one central OAuth2 Proxy in Kubernetes with GitLab as the identity provider. Install via Helm, configure NGINX Ingress auth annotations, and protect multiple services with a single OIDC app and redirect URL.

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

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:

  • name is an application label for your reference
  • redirect_uri is the endpoint to which GitLab should send users after they have authenticated, and should be of the form https://<my-cloud-application-url>/oauth2/callback
  • Scopes define 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.

OAuth2 Proxy uses a cookie secret to sign session cookies. Generate a Base64-encoded string for the cookieSecret in your values:

1
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):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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:

1
2
helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests
helm repo update

To see available chart versions:

1
2
3
4
$ 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):

1
2
3
4
5
6
7
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:

1
2
3
4
$ 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:

1
2
3
4
$ 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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:

1
helmfile sync oauth2-proxy

The above values result in this Ingress object:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy