This post was originally published on Identity, Authenticity, and Security.
If you think authentication and authorization is so confusing that you can't even understand what your PM and peers are talking about.
Congratulations, you’ve come to the right place!
Whether you’re building a single-user application, an admin dashboard, or a multi-user product, you likely have encountered the terms authentication and authorization and most likely gotten them confused. What’s worse, developers new to application security oftentimes mistakenly use them interchangeably. What do people mean when they say, “auth”, “authN”, and “authZ”?
In this post, we will clear up all the common misconceptions and make sure you have a clear understanding of what the terms mean, and when to use them.
TL;DR
If you’re in a hurry, here is the takeaway and you may skip the rest of the post:
- Authentication refers to the process of proving who you are.
- Authorization refers to the process of checking what you can do.
Pretty simple, isn’t it?
What are they, exactly?
Authentication, often referred to as "authN" for short, is the process by which a service verifies a visitor’s identity by requiring them to prove their legitimate access through specific methods.
Even if you’ve never heard of the term “authentication”, you have performed the process with almost every service on the internet nowadays (that requires an account). Commonly, visitors use:
- Emails with a password, one-time passcode, magic link, etc.
- Social sign-ins like GitHub, Google, X, or Microsoft, etc.
- Phone numbers with one-time passcode
- Biometrics like touch ID, or face ID, etc.
- Passkeys
In addition, if the visitor’s account has Multi-Factor Authentication (MFA) enabled, an extra verification step is presented and must be completed as part of the same authentication process. Commonly, by:
- Receiving one-time passcodes via email, phone, or authenticator (Google Authenticator, 1Password, Duo, etc.)
- Tapping “Yes, it’s me” on a trusted device
Once the visitors complete the authentication process, we then call them “authenticated users” and use some techniques to “remember” the authenticated state for a period of time (often known as “sessions”), so visitors will not get annoyed by authenticating themselves over and over until they give up using your service.
Authorization, often referred to as “authZ” for short, is the process by which the service backend asserts whether the currently authenticated user has permission to perform the intended action.
This process isn’t as visible as authentication to visitors because the entire process is completed within the service backend. Visitors would only get an error like “access denied” if the visitor is not authorized to perform the intended action (often known as “unauthorized access”).
How does the service backend determine whether an intended action is authorized or not? It heavily depends on the actual business logic and how the service backend chooses to implement its authorization system, but common examples are:
- Whether the authenticated user is an admin for admin actions.
- Whether other users have shared access with the authenticated user for their protected data.
- Whether the authenticated user is on the premium plan for paid features.
What about “auth”, what does it refer to? When people mention “auth” in a conversation, they either mean authentication or both, almost always never solely meaning authorization. Remember, when in doubt, simply ask clarifying questions.
What are the gotchas?
Although authentication and authorization look similar, and sound similar, the way they are being designed and implemented are very different.
The implementation of authentication (other than the UI) is fundamentally the same for most services. Therefore, in addition to the typical email/username sign-in, many open standards have been published and adopted as the go-to solutions. Just to name a few:
- OAuth 2-based sign-ins (although technically OAuth 2 isn’t an authentication protocol, it has been widely adopted since the rise of social sign-ins)
- OIDC, which builds on top of OAuth 2 as a sophisticated authentication protocol
- SAML 2.0, an XML-based protocol widely adopted in enterprise settings
- LDAP, ancient but still widely used, most enterprises use its variant Active Directory from Microsoft
- Passkeys from WebAuthn, the new cool kid in town
On the other hand, the design choice and implementation of authorization in services are almost always heavily dependent on the actual business logic, which makes it harder to adopt any go-to solution. Efforts have been made to provide some standardization around authorization models:
- Role-based access control (RBAC) defines access based on the user’s roles, e.g. site admin, billing manager, and regular users.
- Attribute-based access control (ABAC) allows the service to provide fine-grained authorization, e.g. OAuth 2 token scopes is an application of ABAC.
- Relationship-based access control (ReBAC) was coined by the publication of Google’s Zanzibar, it is the most complex, sophisticated yet flexible way to define authorization models.
Theoretically, both of them need to happen for every single request that would potentially or explicitly access protected data. Although certain techniques can be applied to improve the user experience (UX) and request latency:
- Use sessions or alike to remember the result of authentication for a period of time, typically 7-30 days. Government and financial services are often more stringent, limiting sessions to 15 to 30 minutes.
- Use caching to save the computation results of an authorization evaluation for a short period of time. Usually not recommended, but useful when it is expensive to compute the authorization evaluations of some operations.
Besides the implementation, there are other things to keep in mind:
- Depending on the use case and the nature of the business, not all endpoints of your service have to be put behind authentication. For example:
- Anyone can view any public posts on Substack, but only authenticated users can subscribe to newsletters and manage their paid subscriptions.
- Admin dashboard type of services typically require authentication before any action can be performed.
- Not every service requires complex design and implementation of authentication and authorization:
- The more ways to do the same thing, the more attacks surface from the outside, e.g. if your service doesn’t require LDAP, SAML, or social sign-ins, it is better to leave them out.
- If all you need is to check whether a user is an admin or not, a simple isAdmin helper (and an extra database column like is_admin on your users table) does the perfect job for implementing your authorization system. Do not over-engineer the solution because the more complex the system is, the easier to write (security) bugs.
- A common mistake for developers new to application security is that they implemented authentication and authorization in a layer that visitors can easily bypass. In other words, putting authentication and authorization purely in browsers, mobile apps, or editor extensions is ineffective, and malicious users can always bypass your checks and send requests directly to your service backend and gain unauthorized access.
- With that said, additional authentication and authorization in browsers, mobile apps, or editor extensions can be helpful to enhance the UX, e.g. by not showing certain items if the user has no access to them or only displaying public information when not authenticated.
Because both authentication and authorization are so crucial to get right, it is important to take them into consideration early in your system design, as some design decisions may turn out to be infeasible with security constraints.
Can you walk me through an example?
Sure!
Using Sourcegraph’s public code search as an example (since I was personally involved in designing, building, and maintaining many parts of its authentication and authorization systems throughout my tenure).
- Not all endpoints are behind authentication:
- Anyone on the internet can make code searches across public repositories on Sourcegraph.com, e.g. search for the keyword “gogs” (link).
- Certain features are only available to authenticated users:
- Using the Cody Web chat (https://sourcegraph.com/cody/chat) will prompt for authentication, and visitors will be able to authenticate via their email, Google.com, GitHub.com, and GitLab.com accounts.
- If you look closely enough, when not authenticated, the “Tools” option in the top navbar is not displayed at all.
- Access to site admin features is blocked unless the authenticated user has a site admin role.
- Users can only view and manage their own Cody subscriptions, user settings, UI preferences, etc.
Why should I care?
Having a strong sense and solid defense in application security are as important as having locks on your doors and windows, monitoring surroundings with security cameras, and verifying ID at bank service counters. Authentication and authorization are the first line of defense in the internet era; every developer should have a reasonable level of understanding so we can write more secure code and stop making it so easy to leak people’s personal data online (please, please, please 🙏 Identity theft is so annoying OK?).
Ineffective application security, at the very least, costs your company money and gives away valuable assets; at worst, it will hurt your company's reputation and cause a loss of customer trust and deals.
Every developer needs to be disciplined about application security because it takes a great effort to build the defense but it only takes a tiny crack to fail.
I’m pumped, how can I learn more?
Auth0 provides a rich set of resources on the topics of authentication and authorization (link), while this is not an endorsement nor promotion of their product, you will learn a lot by just playing around.
Thanks for reading thus far, if you find this post interesting, please consider subscribe to my newsletter Identity, Authenticity, and Security ❤️
Top comments (0)