OAuth2 Proxy is a reverse proxy that adds OAuth2 authentication in front of any HTTP service. Unauthenticated users are redirected to the provider (e.g. Google); after sign-in, they can access the upstream app. In this guide you set up OAuth2 Proxy with Google OAuth 2.0 in front of an internal app (we use Gatus as the example; you can use any service on a local port). Traffic flows: NGINX → OAuth2 Proxy (auth) → your app (e.g. Gatus on port 8080).
In this guide you’ll:
- Create Google OAuth 2.0 credentials (client ID and secret) and set the redirect URI
- Install NGINX, Docker, Certbot, and the OAuth2 Proxy binary
- Run an example internal app (Gatus) with Docker Compose, then configure OAuth2 Proxy and a systemd service
- Configure NGINX with
auth_requestto enforce sign-in and obtain a Let’s Encrypt certificate
Related: OAuth2 Proxy for central authentication in Kubernetes
Prerequisites
- A Linux server (this guide uses RHEL/Rocky/Alma with
dnf; adapt for Ubuntu/Debian withapt). - A domain name pointing to the server (e.g.
auth.example.com) for NGINX and Google redirect URI. - A Google Cloud project and access to Google Cloud Console.
Table of contents
- Prerequisites
- Table of contents
- 1. Google OAuth 2.0 setup
- 2. Update server and install packages
- 3. Set up Docker and Docker Compose
- 4. Example: Run an internal app to protect (Gatus)
- 5. Set up OAuth2 Proxy
- 6. Configure NGINX and TLS
- Frequently Asked Questions (FAQ)
- Conclusion
1. Google OAuth 2.0 setup
You need a Google OAuth 2.0 Client ID and Client Secret. Use the same domain you will use for OAuth2 Proxy (e.g. https://auth.example.com).
- Open Google Cloud Console and select (or create) a project.
- Go to APIs & Services → OAuth consent screen. Configure the consent screen if you haven’t (e.g. User type: External, App name, support email).
- Go to APIs & Services → Credentials → Create Credentials → OAuth client ID.
- Application type: Web application. Give it a name (e.g. “OAuth2 Proxy”).
- Authorized JavaScript origins:
https://auth.example.com(replace with your OAuth2 Proxy host). - Authorized redirect URIs:
https://auth.example.com/oauth2/callback(must match exactly). - Create the credential and copy the Client ID and Client secret; you’ll use them in the OAuth2 Proxy config.
2. Update server and install packages
Update the system and install NGINX, Docker, Certbot (for Let’s Encrypt), and unzip:
| |
3. Set up Docker and Docker Compose
Start and enable Docker (required for the example Gatus app; skip if you already use another upstream):
| |
Confirm docker is running by checking its status.
| |
Add your user to the docker group so you can run Docker without root (replace ec2-user with your username):
| |
Install Docker Compose (check releases for the latest version):
| |
4. Example: Run an internal app to protect (Gatus)
We use Gatus (a health-check dashboard) as the upstream app. OAuth2 Proxy will sit in front of it; you can replace Gatus with any service listening on a local port (e.g. 8080).
Create the config directory and a minimal Gatus config:
| |
Create /etc/gatus/config.yml:
| |
Create /etc/gatus/docker-compose.yml:
| |
Start Gatus:
| |
The app listens on localhost:8080. OAuth2 Proxy will use this as the upstream.
5. Set up OAuth2 Proxy
Download the OAuth2 Proxy binary (see releases for newer versions):
| |
Create the config file /etc/oauth2_proxy.cfg. Generate a cookie secret with openssl rand -base64 32 and replace placeholders with your Google Client ID, Client Secret, domain, and upstream (e.g. http://localhost:8080 for Gatus):
| |
Restrict sign-in to a single domain (e.g. your company): set email_domains = ["example.com"]. Use * to allow any Google account.
Create a systemd unit /etc/systemd/system/oauth2_proxy.service (replace ec2-user with the user that should run the proxy):
| |
Reload systemd, start and enable the service:
| |
You should see active (running) and a log line like mapping path "/" => upstream "http://localhost:8080". For debugging: sudo journalctl -fu oauth2_proxy.
6. Configure NGINX and TLS
NGINX will terminate TLS, use auth_request to enforce OAuth2 Proxy sign-in, and proxy /oauth2/ to OAuth2 Proxy and / to your upstream.
Create /etc/nginx/conf.d/auth.conf (replace auth.example.com with your domain):
| |
Reload NGINX and obtain a Let’s Encrypt certificate:
| |
Visit https://auth.example.com. You should be redirected to Google to sign in; after authentication you’ll see the upstream app (e.g. Gatus).
Frequently Asked Questions (FAQ)
What is OAuth2 Proxy?
OAuth2 Proxy is a reverse proxy that adds OAuth2/OIDC login in front of HTTP services. Unauthenticated requests get redirected to the provider (e.g. Google); after login, the proxy sets a cookie and forwards requests to the upstream. It supports many providers (Google, GitHub, Azure AD, etc.).
Why use auth_request with NGINX?
auth_request runs a subrequest to /oauth2/auth for each request. If it returns 401, NGINX serves error_page 401 = /oauth2/sign_in, which sends the user to the OAuth2 Proxy sign-in page. This keeps authentication logic in OAuth2 Proxy and NGINX only enforces it.
How do I restrict sign-in to my organization?
Set email_domains in the OAuth2 Proxy config to your domain (e.g. ["example.com"]) so only Google accounts from that domain can sign in. For Google Workspace you can also use google_admin_email and google_group to restrict by group.
Can I use a different upstream than Gatus?
Yes. Change upstreams in /etc/oauth2_proxy.cfg to your app’s URL (e.g. http://127.0.0.1:3000). Ensure the app listens on localhost or an address OAuth2 Proxy can reach.
Conclusion
You set up OAuth2 Proxy with Google OAuth 2.0 in front of an internal app: created Google credentials, installed NGINX and OAuth2 Proxy, ran an example app (Gatus) on port 8080, configured the proxy and systemd, and used NGINX auth_request plus Let’s Encrypt so only signed-in users can access the site. For the same pattern in Kubernetes, see OAuth2 Proxy for central authentication in Kubernetes.