If you’re someone who builds software, no matter if you’re on the backend or frontend or even on the product side, sooner or later you have to concern yourself with securing the thing. Or you realize that data privacy laws are very real and you must have a strategy for user data sharing. So you want to implement some sort of authentication. More likely, you’re looking for a solution, open-source or otherwise, that will solve this problem for you. And here comes confusion.
The auth space is currently very active, with new players joining and old players repositioning themselves (with or without changing what they offer). They each use a different language on their landing pages. Or worse, they use the same words to mean different things. With this article, I hope to bring some clarity on what parts of auth and data security are relevant if you’re building software, and how to think about the space.
I’ll clarify the terminology around it, list the most important considerations when picking a solution, and mention any caveats or pitfalls you may hit along the way.
If you’re looking for concrete recommendations, feel free to jump straight to the end.
In many places, I list example solutions. These are not exhaustive lists and there are many other products out there, each with their pros and cons. I picked the examples based on what popped up most often in my user research, and I only list those where people were saying good things. Last but not least, as a founder, I’m always going to be rooting for our own solution, Authress, and it is a good reminder to do your own research based on your exact needs.
When most people hear “auth”, they think login. Login is authentication, or auth-N for short. It’s the first step of securing your software.
Even if you’re making a small side project just for yourself, as soon as you host it somewhere outside of your machine, you want to implement some sort of authentication. The days when obscurity that saved your little inconsequential personal website or crawler from DDOS attacks are long gone. It’s really simple - if it runs on the internet, it has to require login. Unless it’s just a static website, but let’s not be pedantic.
Good news is, it’s really easy to add login to your software and it will cost nothing if you play it right. Bad news is, it can get really complicated and expensive unless you spend a moment to think about what you need exactly.
Username and password
Username and password may seem like the easiest, most basic thing to do - just plop a form, maybe use a library to support it, and you have your login. Wrong. This is a trap.
First of all, it puts you on the hook for storing and processing personal identifiable information (PII). That’s because for this to work you need to collect and store a user’s email address. Why? Because sooner or later someone will forget their password, or will want to change their existing one. To facilitate it, you need an email - and just like that, you now have to comply with local regulations surrounding PII: GDPR, CPRA, CPPA, LGPD, PDPA, the list goes on... You really don’t want to do that unless you absolutely have to and have the resources to do so.
If that’s not enough to convince you, there’s still the matter of user experience. Remembering passwords is not fun. If your users are smart, they will use a password manager. If they’re lazy, they’ll reuse their passwords. Either way, you’re adding friction right at the start of your process.
Social login a.k.a. federated login
When you want to add login functionality to your project quickly, use a social login. This is also known as federated login provider, and it is the way to go. It’s free, fairly painless to configure (although there are caveats) and you won’t have to worry about handling personal identifiable information - the provider will do that for you.
Login with Facebook, Google, Microsoft, Github, …the list goes on and on. Theoretically, all those implement the same standard, OpenID. And theoretically, integrating them into your software will be consistent across all of them. In practice, there are two types of engineers - those who follow the spec and those who get creative. It seems that the majority of federated login providers employ the latter kind. This means that for most of the providers, you’ll have to jump through a few hoops to get it working.
If you stick to a single provider, integration ranges from super easy to manageable, but as soon as you want to support multiple options, it may be easier to use an Identity aggregator or a login box solution. Those usually aren’t free.
SSO (single sign-on)
If your software is used by other companies, and your users are their employees, you want to allow those users to login via their standard corporate login. There are multiple standards here and each company will have their own authentication format - SAML, OpenID, OAuth, or something custom. And just like the federated login providers, they too are usually creative with their implementations.
It gets complicated real quick, that’s why you probably want to go with one of the identity aggregators or a full featured auth SaaS. If you’re after enterprise customers, you likely have other requirements that mean you really can’t just cobble something together on top of your existing solution. It’s worth paying for the convenience and peace of mind in this case. On the other hand, some solutions will make you pay the enterprise tax for no good reason, so make sure to compare different providers and read what’s really included.
It’s worth noting that this is different than using SSO internally at your own company. You can’t extend your own SSO to your customers. Solutions dedicated to providing access to enterprise employees, such as Google Workspace, Okta or Azure AD, aren’t the ones that will help you add such functionality into the software you’re building, it’s an entirely different category.
Login box and identity aggregation
If you know your users will need multiple options for login or you simply don’t want to worry about the whole authentication part, there are quite a few providers that offer a login box you can simply drop into your website. These also act as identity aggregators - they will accept whatever login method you have configured, or your customers want to configure, and return a consistent token that your software can consume directly. Convenient.
When picking a solution, make sure that all the login options your users will care about are supported, that may include things like passkey, WebAuthn, or passwordless login, on top of the most common social logins. Also check if there’s an enterprise tax and whether you have to pay extra for SSO integration. Some providers charge for the number of users and also for the number of customers and each extra SSO integration you add.
There are a few potential gotchas here. Sometimes an aggregator promises support of all the different login providers but when you go ahead and try to integrate, you end up having to do all the hard work yourself. That’s something you can only evaluate through a proof of concept. Most of the open source frameworks fall into this category. There’s usually multiple extra packages, and whole sets of additional configuration to set up.
Another thing to look for is reliability - you need an SLA that’s at least as good as the one you plan on offering yourself. If login is down, your software is down.
What also happens is that some aggregators will make it easier for themselves to integrate with all the different identity providers and use a security standard that’s a lowest common denominator. This means that sometimes an identity provider offers a more secure standard to login, but it’s not utilized by your aggregator. For instance, some providers offer EdDSA token signatures, but most aggregators only provide RS256. It’s not something that’s easy to tell by just looking at their website, as obviously no one will advertise this. If you care about security, you’ll have to poke around documentation and code samples to find out the real story.
Now that your users can log in, let’s talk about the hard part - the actual authorization, auth-Z for short. Historically, this was lumped together with login - the scope of what a user could do was determined solely by whether or how they are authenticated. It turns out this is not good enough, especially if your software involves any sort of data sharing. That’s where authorization, or access control comes into play.
Solutions range from classical sticking the claims into a user token, to fully fledged authorization decision engines which can support even the most sophisticated cases.
Sadly, which one is the “easy way” is a strong case of “it depends”.
If all your users can do exactly the same things in your software, or if you’re building it just for yourself, the quickest way to secure access is by piggybacking on the access tokens. This means sticking the resources that a given user should have access to directly into the token using claims.
This works when you have a simple access model - users can see and do everything in your software, nasty bots can’t. It may also work if your model is slightly more nuanced, as long as all your users follow the same pattern. It breaks as soon as you have a lot of users, your users can have multiple roles, or your resource hierarchy is a little more complex than a very short list. That’s when simple becomes simplistic. In some cases you’re not even able to rely on this method, as you easily exceed the maximum field or token size.
This is where many login box providers, such as Auth0 and FusionAuth, fall short - they only offer simple authorization as of now. If that’s sufficient for your use case and you’re happy with their pricing for the other features you need, no need to look further.
Even 5 years ago, if you wanted something more robust, you had to build your own authorization engine. Everyone who’s ever built software in the B2B space knows this very well. It may seem like a simple thing, just a single database with some simple checks - 5 months later you’re still tweaking and fixing and cursing. It’s a death by a thousand cuts. In the past, there was no choice. Nowadays there are multiple providers you can choose from with much better developer experience, tighter SLAs, more features, and at a fraction of your own cost.
These days, you really don’t want to build your own, unless you’re a masochist and have extra time and money to throw away.
Authorization as a service
There are many SaaS solutions that offer the authorization decision engine as a service. They will handle all the complexity, reliability, and security, and you only have to map your permissions model to theirs.
With growing awareness on security and data privacy, this is a quickly growing space, and new startups are popping up to solve the problem seemingly every other month. This is good for you as the user, but also confusing, as everyone thinks about it slightly differently and uses different words to talk about it.
There are a few things to consider when picking your solution. The main one is obviously the features - other than providing a structured way to model your permissions, you may also want intelligent integrations with things like machine to machine authentication, permissions for service clients, and login that complements what you were planning on using. Also think whether you want to be running the solution yourself - you probably don’t, unless it doesn’t have to be very reliable, but you may have no choice if you’re working in a highly regulated environment. If you have specific requirements for data residency, also make sure your selected solution will accommodate it.
Another consideration is the ease of getting started and overall developer experience. Is there documentation? How quick can you get support if you have a question? Is support provided by technical people or an offshore customer support center on the other side of the world? Do you even need support, or is everything clear enough for you to have something running within hours?
Then there’s the ease of use once you’ve set everything up. Software rarely stands still and your permission model will evolve. How easy is it to change it once you have hundreds of thousands users in production relying on a given authorization system? Is the model inherently flexible and extensible?
There’s also a matter of pricing. There are a few strategies that providers use. Most common one is based on the number of active monthly users, which also means you can easily estimate how much it will cost you. This is a good approach if your unit of value directly corresponds to an active user. It gets expensive if you offer a free tier, your users use your software only a couple of times a week, or you often run marketing campaigns that result in spikes of new logins that don’t fully convert. A few providers offer metered pricing, similar to how your cloud provider charges you. This is a bit more tricky to estimate your actual cost, but in the grand scheme of things, it usually ends up cheaper than per-user pricing. Some providers will want you to pay a monthly minimum. Most offer some sort of volume discount. If you consider authorization engine a part of your infrastructure, metered pricing is a good fit.
All you’ve read so far was about application-level security - all the things that make your software secure for your users. When people hear “security” though, they usually think “infrastructure security” - all the things that make your software secure to build and run.
This is a complex topic of its own and only tangential to what this article is about, but auth is an important part of it, so let’s include it for the sake of completeness.
If you’re hosting your software in the cloud, which is most likely the case when you’re building something new, then you most certainly want to secure that infrastructure, if only to prevent someone else’s bitcoin miners running at your expense.
Luckily, all cloud providers offer plenty of options for you to do so. First thing you want to look at is to use your cloud provider’s IAM to configure access policies for your account. There are many other things you could do for cloud security, so if you work in the cloud a lot, invest in learning about it.
Most cloud providers offer some sort of tool that may look like it will let your users login into your app - AWS Cognito, Azure AD, or Firebase. It may be tempting to try and use these. Thing is, these are good choices if you’re building something for yourself or to be used by your own developers, or family members, as they will be the ones with access to your cloud account. When you need something to handle your end users’ identity, cloud native options just don’t cut it.
Securing your APIs consists of two main parts. It is analogous to securing your application by forcing your users to log in in order to authorize them.
First part is the machine-to-machine authentication - you don’t want to let just any service call your API after all. Your options are plaintext API keys, mTLS, public/private key pairs, or a combination of them - there are libraries in each major language that should help with these. Or you could use one of the SaaS solutions that handles machine to machine authentication as a first-class concept, such as Authress or Ory.
Authenticating your clients is better than nothing, but if you leave it at that, you’re still open to Broken Object Level Authorization (BOLA) vulnerabilities. This means that if you want your API to be public at any reasonable scale, you need to consider the second part - an authorization layer on top of the authentication. If you’re using a SaaS for access control, see if they offer the same functionality for service clients.
At the time of writing, Authress and Ory are the only providers that do this in a straightforward manner, but the space is evolving rather quickly, so new solutions may have come out by the time you’re reading this.
Sometimes you want to securely share credentials (if sharing credentials can ever fall in the category “secure”). You may need to share a login to a particular piece of software, e.g. if you’re paying per seat or for whatever other reason. If so, you’re looking for a password manager for business. That’s what solutions like 1Password or Zoho Vault are for. LastPass is another solution worth mentioning if only for their inability to keep your passwords secure.
Then there’s the separate matter of using secrets by your services in production, to access a third party integration. This is what AWS Secrets Manager and Hashicorp Vault enable. If you’re running your software in the cloud however, there is a more secure way of handling it though, by encrypting your credentials and using your cloud provider’s Key Management Service.
Employee access control
If you’re a big company, you may want to manage access to all your third party applications that you have licenses for - Figma, Salesforce, Zendesk, etc. You probably also already have an employee directory such as Azure AD, Google Workspace, Microsoft AD, Rippling or the likes. In that case, you can hook up your directory to something like Okta to let your employees use their single sign on to login into the apps. This is less about security and more about convenience of managing your software licenses, especially if you pay per seat.
Summary and recommendations
If you’ve read this far, you hopefully have a good understanding of what types of problems exist in securing your software and your user’s data, and what are some of the software products that address them. Here is a visual summary of what all the different providers I mentioned offer:
If all the above is too much to read, or you have no time to think about all the nuances, let me make things really simple by providing recommendations for most common scenarios. These are opinionated and don’t include all the intricacies of your individual situation, so use these as a starting point and do your own research.
Side project, personal use
When you’re building a small side project, or something just for yourself, friends and family, you don’t want to overcomplicate things and you want things cheap, if not free. For login, use one of the social logins, like Facebook or Google. This is a standard OAuth implementation, which you should get familiar with anyway, and most languages have libraries that help.
You want to run the thing in the cloud rather than your own machine - it’s super easy, comes with a lot of security options out of the box, and it costs peanuts.
If you need to restrict access to specific resources (e.g., your mom can delete her own data, but she can’t delete yours), use claims and the simple authorization access control in the access token to save this information.
MVP for public use
When you want to build a product quickly to validate it, you may need something slightly more robust, especially if you’re going to share it with the wider public. If you can get away with a single social login, great. If not, use any provider that offers a login box cheaply. Authress or Auth0’s free tier fit the bill.
If you have a monolithic app and don’t need SSO, Auth0 should be good enough. If you are building microservices and you need machine to machine authentication, Auth0 gets expensive real quick. You should be able to work around this using your cloud provider’s Key Management Service and storing your encrypted keys in git.
If you build something intended for consumers (individuals rather than businesses) at any reasonable scale, you shouldn’t cut corners regarding the login experience. Use a well-established login box provider, such as Auth0 or Clerk.
If your software involves any sort of data sharing, you can use Auth0 if you only have one or two simple permissions. For fine-grained access control, use Authress or Ory. The latter two also include login box support. Which one to use depends on how complex your use case is - you don’t want to spend weeks configuring and tweaking if things are simple, but you also don’t want to rewrite your stuff after finding out your initial approach doesn’t scale.
If your software is meant to be used by companies, regardless if we’re talking about small businesses or enterprises, you absolutely have to support SSO. Some login box providers offer this: Auth0, Clerk, FusionAuth, Ory, or Authress, although most of them charge an absurd amount of money for the privilege. Still, if you’re selling to enterprises, this may pale in comparison to your other costs, but it could land you in a spot on SSO tax.
Proper access control is essential in B2B, because most companies will have a notion of user roles with different levels of access and different data visibility depending on who’s logged in. If you would like a solution that only handles access control, use Oso or Permit. If you want one solution that also handles sign-on, machine to machine auth, monitoring, and auditing, use Authress or Ory. If, for whatever reason, you really want to host the solution yourself, both Oso and Ory offer that as an option.
When your product is an API, you don’t have all that much choice. You want to go with a solution that supports API security as a first-class notion, that is, Authress or Ory. This will give you machine to machine authentication, as well as resource-based access control, to protect yourself from BOLA.
And that's it - all you need to know before adding auth to your project.