May 13, 2025
I spent the past few days wrestling to get Google OAuth working (and it finally does!!).
I want to expose as much of what I'm doing on this project as possible to my friends, coworkers, and anyone else who wants to look. But I recognize that things like Grafana or Prometheus have high abuse potential in the wrong hands. So I decided a reasonable short-term compromise would be to allow open access while requiring some basic user authentication. This should rule out any bots (or at least any simplistic ones), and also gives me the ability to track who is logging in to these applications (at least in theory).
I started with Grafana, because it has built-in Google OAuth integration. I created a
new OAuth Client in the
Google Cloud Console, dropped the info
into Grafana, and gave it a spin in a new private tab. It went through the correct
redirect flow at first - I went to
grafana.jamesmassucco.com and was
redirected to login with Google. But since it was a private tab, it didn't remember my
username, so I had the brilliant idea to go back to my main tab, LOG OUT of Grafana, and
then go through the auth flow. The first issue emerged, which was that instead of
redirecting back to grafana.jamesmassucco.com after successful auth, it took me to
localhost:3000 - and just like that, I was locked out of Grafana. Thankfully, the
solution was simple. I just needed to add GF_SERVER_ROOT_URL
to my Grafana
environment variables and restart the container, and I was in.
But once I was in, a second issue emerged - I was no longer logged in as
admin
, I was logged in as James Massucco
, who was just a
regular "Viewer" user. I couldn't do administrative functions anymore on my own
instance! To correct this, I had to get a bit more creative. With the help of ChatGPT, I
installed sqlite and then probed the live Grafana DB (the one where it stores all its
settings) and found my user account. Once I was in there, it was fairly simple to modify
the DB to grant myself admin priveleges. And from there, I elevated the rest of my
priveleges within the Grafana UI. Crisis averted!
The next stage of the saga was much longer and more drawn out. It's honestly a bit
painful to think of how many hours I spent SO CLOSE to the final solution without
getting it. But I'm getting ahead of myself. What was I even doing for those hours?
Well, for applications like Prometheus and Traefik, which are more simplistic
dashboards, there was no built-in support for Google OAuth, so I had to go a different
route. I found an application called oauth2-proxy
which can server a
dual-role, either as a dedicated reverse-proxy with authentication, or as a so-called
"middleware" that provides authentication services to another reverse-proxy (like
nginx
or, in my case, traefik
). I decided to start with just
putting the Traefik dashboard behind oauth and got to work with a basic config, with
help from ChatGPT. It didn't work, so I tried again. That didn't work either, so I tried
again... Fast forward to, like, 10 hours later when I'm still just not getting it. Why
was it so hard? Well, not really for any technical reason. It's just that the
documentation was dense and hard to parse. I mostly ended up relying on examples from
oauth2-proxy
, but they were written in a totally different config style
than I was using (they used a traefik yaml config, whereas I'm using docker-compose to
define the traefik config). I even tried switching to the traefik.yaml style just so I
could more easily copy-paste their example, but that broke too because the environment
variables I was passing to Traefik for Cloudflare API access didn't work once I tried to
move those configs to the YAML...
Anyways, there really aren't too many useful insights in here, I just spent a lot of
time flailing and needed a little bit of the catharsis that comes from ranting about a
frustrating experience. I did finally get it working, and it felt a little extra sweet
because I did most of the heavy lifting without any help from ChatGPT (mostly because it
was clear ChatGPT did not know how to use oauth2-proxy
very well - but
still). And the one cool thing was that once I got the auth working for
traefik
, it literally took like 30 seconds to get it working for
whoami
and prometheus
. Just like that, I had authentication!
Check out how I configured it in the networking/docker-compose.yml
if
you're curious what the fruits of that labor look like!