When I was a newer engineer, I was managing the infrastructure for an online platform. I built most of the infrastructure from scratch on GCP - a Kubernetes deployment, a few databases, some object storage buckets, and some PubSub-connected services. This online platform needed to centralize authentication between its various services.

How hard could it be?

"How difficult could it possibly be to write an OAuth provider?" I asked myself. Naturally, as any young engineer would discern, there were no difficult obstacles in the way of building my own. This was a mistake.

I spent a few weekends developing this new SSO platform - called Indra. I built it with scaling in mind, so it was a stateless service that offloaded sessions to a central Redis database, and could support multiple domains as independent identity providers. I wanted to open source it, and release it into the world, so people wouldn't have the same issues I did.

This went poorly

I learned quite quickly that the OAuth spec is difficult to implement. The document itself is over 400 pages, and has plenty of gotchas and easy-to-miss technicalities. So, needless to say, I did not implement the spec correctly.

This incorrect implementation grew in scale, until eventually, it required a suite of software to maintain it properly - and it still needed raw database queries to administer. It turned into a nightmare, and still runs to this day, with bugs in the codebase that have not yet been solved.

The fact that the project is still on life support is something I consider to be a terrible mistake on my part. I could have done more research, I could have implemented it better, or I could have not written it at all. But, it gave me a desire to learn more about SSO solutions, and, years later, led me to create Authproject.

What I learned

I learned a few key things from Indra.

Key Learning 1: Don't roll your own auth

I know this is somewhat ironic, given that I am now running an authentication platform. However, the experience instilled me a deep respect for those that write cryptographic libraries, those that implement difficult technical specifications, and the projects that truly power the world. I have specifically avoided writing my own code for Authproject as much as possible, and am leaning heavily on well-vetted libraries in the existing Go ecosystem (all of Authproject's services are written in Go), such as crypto/rsa, golang-jwt, and golang/oauth2.

Key Learning 2: Stick to the spec

This may seem obvious, but when you are implementing a specification, stick to it. Don't try to create something new. Chances are, someone has already solved this problem - and published an RFC about it - so you don't have to. You can use the groundwork laid by giants to create ultimately a better customer experience. People want things to "just work," and having to write your own client libraries does not count towards things that "just work."

Key Learning 3: User experience is paramount

This is also fairly obvious - but it is not always followed. Not only are the people who sign in and sign out using your platforms your users, but the engineers who integrate with your platform are your users, too. They need to have a good experience, almost more so than the users themselves - because if the people buying your software won't like it, or can't use it, they won't renew.

What does this mean for the future?

I learned a lot from writing Indra - far more than I have documented here. I have taken those learnings and built them into Authproject - along with many things I've picked up along the way. I can confidently say that what has been built here is far better than it would have been had I not failed at this very task years before.

With that, I hope you enjoy using our platform. And if you are debating, simply contact us on our site, and we will show you why we're amazing.

--E

The Worst Mistake of My Early Career