Blog Home

Google OAuth

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!