OAuth2 Proxy is a reverse proxy and static file server that provides authentication using OAuth2. Youβll configure OAuth2 Proxy to secure access to your service. This will add an extra layer of security by requiring users to authenticate before accessing the API.
We’ll configure OAuth2 Proxy to use Google OAuth 2.0 as the Auth Provider. This means that when a user tries to access your FastAPI service, they will be redirected to Googleβs authentication service to log in. Once authenticated, Google will issue an access token that allows the user to access your API.
Google OAuth 2.0 setup
In order to setup OAuth2 proxy we need to have an auth provider, In this project weβre going to use Google OAuth2.0 as our provider.
We need google credentials, generate using these steps:
- You need an existing google project
- Navigate to the
OAuth consent screen
by searching for it in the Google Cloud Console search bar. - Click the
Credentials
button in the left-side menu and create an OAuth 2.0 Client IDs
. - Select the application type as
Web application
and give it a name to identify it. - Add your url - ‘https://auth.citizix.com’ as JavaScript origins.
- Add ‘https://auth.citizix.com/oauth2/callback’ as the redirect URL. Since our NGINX OAuth2 Proxy URL is ‘https://auth.citizix.com/’, the callback URL of the OAuth2 Proxy will be that.
- Create the credential, and it will show you the client ID and client secret. Save it for later usage.
Update server packages and install required packages
Ensure the server packages are updated
Install required packages
1
| sudo dnf install -y nginx docker certbot python3-certbot-nginx unzip
|
Set up docker and docker compose
We will use docker and docker compose to set up gatus.
Start and enable docker
1
2
| sudo systemctl start docker
sudo systemctl enable docker
|
Confirm docker is running by checking its status.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| $ sudo systemctl status docker
β docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: disabled)
Active: active (running) since Sun 2025-03-16 09:20:54 UTC; 33s ago
TriggeredBy: β docker.socket
Docs: https://docs.docker.com
Main PID: 207133 (dockerd)
Tasks: 8
Memory: 31.2M
CPU: 386ms
CGroup: /system.slice/docker.service
ββ207133 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --default-ulimit nofile=32768:65536
Mar 16 09:20:53 auth.citizix.com systemd[1]: Starting docker.service - Docker Application Container Engine...
Mar 16 09:20:53 auth.citizix.com dockerd[207133]: time="2025-03-16T09:20:53.818123871Z" level=info msg="Starting up"
Mar 16 09:20:53 auth.citizix.com dockerd[207133]: time="2025-03-16T09:20:53.893991019Z" level=info msg="Loading containers: start."
Mar 16 09:20:54 auth.citizix.com dockerd[207133]: time="2025-03-16T09:20:54.475192203Z" level=info msg="Loading containers: done."
Mar 16 09:20:54 auth.citizix.com dockerd[207133]: time="2025-03-16T09:20:54.506292402Z" level=info msg="Docker daemon" commit=71907ca containerd-snapshotter=false storage-driver=overlay2 version=>
Mar 16 09:20:54 auth.citizix.com dockerd[207133]: time="2025-03-16T09:20:54.506447357Z" level=info msg="Daemon has completed initialization"
Mar 16 09:20:54 auth.citizix.com dockerd[207133]: time="2025-03-16T09:20:54.598889450Z" level=info msg="API listen on /run/docker.sock"
Mar 16 09:20:54 auth.citizix.com systemd[1]: Started docker.service - Docker Application Container Engine.
|
Add user to docker group so we can run docker without root access.
1
| sudo usermod -aG docker ec2-user
|
Install docker compose
1
2
| sudo curl -L https://github.com/docker/compose/releases/download/v2.33.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
|
Confirm version installed.
1
2
3
| $ docker-compose -v
Docker Compose version v2.33.1
|
Setting up Gatus
Create gatus config directory
1
2
3
| sudo mkdir /etc/gatus
sudo chown -R ec2-user:ec2-user /etc/gatus
|
Create gatus config
Edit file
1
| vim /etc/gatus/config.yml
|
Content
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| metrics: true
storage:
type: sqlite
path: data.db
endpoints:
- name: citizix-healthcheck
url: https://citizix.com/
interval: 1m
conditions:
- "[STATUS] == 200"
- "[RESPONSE_TIME] < 1000"
alerts:
- type: email
to: "admin@citizix.com"
|
create docker compose file
1
| vim /etc/gatus/docker-compose.yml
|
Content
1
2
3
4
5
6
7
8
9
| services:
gatus:
image: twinproduction/gatus:latest
container_name: gatus
restart: always
volumes:
- "/etc/gatus/config.yml:/config/config.yaml"
ports:
- "8080:8080"
|
Start gatus
1
| docker-compose -f /etc/gatus/docker-compose.yml up -d
|
Confirm
1
2
3
4
| $ docker-compose -f /etc/gatus/docker-compose.yml ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
gatus twinproduction/gatus:latest "/gatus" gatus 19 seconds ago Up 18 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
|
Check logs to confirm that it is working
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| $ docker-compose -f /etc/gatus/docker-compose.yml logs
gatus | 2025/03/16 09:29:42 [main.configureLogging] Log Level is set to INFO
gatus | 2025/03/16 09:29:42 [config.LoadConfiguration] Reading configuration from configFile=config/config.yaml
gatus | 2025/03/16 09:29:42 [config.validateAlertingConfig] Alerting is not configured
gatus | 2025/03/16 09:29:42 [config.validateEndpointsConfig] Validated 1 endpoints
gatus | 2025/03/16 09:29:42 [config.validateEndpointsConfig] Validated 0 external endpoints
gatus | 2025/03/16 09:29:42 [controller.Handle] Listening on 0.0.0.0:8080
gatus |
gatus | βββββββββββββββββββββββββββββββββββββββββββββββββββββ
gatus | β Fiber v2.52.6 β
gatus | β http://[::]:8080 β
gatus | β β
gatus | β Handlers ............ 33 Processes ........... 1 β
gatus | β Prefork ....... Disabled PID ................. 1 β
gatus | βββββββββββββββββββββββββββββββββββββββββββββββββββββ
gatus |
gatus | 2025/03/16 09:29:43 [watchdog.execute] Monitored group=; endpoint=citizix-healthcheck; key=_citizix-healthcheck; success=true; errors=0; duration=551ms
|
Set up oauth2_proxy
Download OAuth2 Proxy binary
1
2
3
4
5
| curl -L https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.8.1/oauth2-proxy-v7.8.1.linux-amd64.tar.gz -o /tmp/oauth2-proxy.tar.gz
tar -xzvf /tmp/oauth2-proxy.tar.gz -C /tmp
sudo mv /tmp/oauth2-proxy-v7.8.1.linux-amd64/oauth2-proxy /usr/local/bin/oauth2_proxy
|
Create OAuth2 Proxy config file
1
| sudo vim /etc/oauth2_proxy.cfg
|
content
1
2
3
4
5
6
7
8
9
| provider = "google"
client_id = "<your google client id>"
client_secret = "<your google client secret>"
cookie_secret = "<your cookie secret>"
redirect_url = "https://auth.citizix.com/oauth2/callback"
email_domains = ["citizix.com"]
cookie_domains = "citizix.com"
http_address = "127.0.0.1:4180"
upstreams = ["http://localhost:8080"]
|
Create a systemd service
1
| sudo vim /etc/systemd/system/oauth2_proxy.service
|
content
1
2
3
4
5
6
7
8
9
10
11
| Description=OAuth2 Proxy Service
After=network.target
[Service]
ExecStart=/usr/local/bin/oauth2_proxy --config=/etc/oauth2_proxy.cfg
Restart=always
User=ec2-user
Group=ec2-user
[Install]
WantedBy=multi-user.target
|
daemon reload service to load newly added service.
1
| sudo systemctl daemon-reload
|
start and enable oauth2_proxy
1
2
| sudo systemctl start oauth2_proxy
sudo systemctl enable oauth2_proxy
|
confirm status
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| $ sudo systemctl status oauth2_proxy
β oauth2_proxy.service
Loaded: loaded (/etc/systemd/system/oauth2_proxy.service; enabled; preset: disabled)
Active: active (running) since Sun 2025-03-16 10:11:31 UTC; 21s ago
Main PID: 209916 (oauth2_proxy)
Tasks: 8 (limit: 4565)
Memory: 4.0M
CPU: 13ms
CGroup: /system.slice/oauth2_proxy.service
ββ209916 /usr/local/bin/oauth2_proxy --config=/etc/oauth2_proxy.cfg
Mar 16 10:11:31 auth.citizix.com systemd[1]: Started oauth2_proxy.service.
Mar 16 10:11:31 auth.citizix.com oauth2_proxy[209916]: [2025/03/16 10:11:31] [proxy.go:89] mapping path "/" => upstream "http://localhost:8080"
Mar 16 10:11:31 auth.citizix.com oauth2_proxy[209916]: [2025/03/16 10:11:31] [oauthproxy.go:172] OAuthProxy configured for Google Client ID: 672653194807-qhu0891l5e8adp0>
Mar 16 10:11:31 auth.citizix.com oauth2_proxy[209916]: [2025/03/16 10:11:31] [oauthproxy.go:178] Cookie settings: name:_oauth2_proxy secure(https):true httponly:true exp>
|
To check logs in case of anything
1
| sudo journalctl -fu oauth2_proxy
|
configure nginx
1
| sudo vim /etc/nginx/conf.d/auth.conf
|
content
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| server {
listen 80;
server_name auth.citizix.com;
location /oauth2/ {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
|
Restart nginx
1
| sudo systemctl restart nginx
|
Let’s encrypt ssl cert
1
| sudo certbot --nginx --non-interactive --agree-tos --email eutychus@citizix.com -d auth.citizix.com
|
Now visit auth.citizix.com
on your browser, you will be asked to signin using google.