When we let "the industry" set our standards, we get a mess of crap that works for the specific use cases of the giant companies that created it. Meanwhile, actually using these things ourselves leaves out a lot of use cases, adds complexity, and becomes burdensome, to the point you don't even want to use it.
We need the international software development community to have its own standards body outside of massive corporations and creaking old institutions with outsized influence. Standards should represent the majority of people writing and using the code.
I do think it's pretty amazing that a basic modern authorization system essential has a hard dependency on a 20+ million lines of code web browser, even for native apps. And mostly just because we need a central location to store auth cookies. I'd love to see a stripped-down "auth browser" that has no job other than rendering basic style-free forms (maybe even declared in JSON) and storing cookies. Problem is you have to get the big boys to stop requiring JavaScript for their auth flows.
That said, after doing a decent amount of implementing OAuth2/OpenID Connect, the core profiles are actually pretty reasonable and about what you would want to do if you were starting from scratch. The trick is making sense of all the optional stuff. There have been some efforts[0] to improve that.
The part I've never been able to figure out is why does OAuth2 use tokens at all, rather than generating a key pair and sending the public key with the initial auth request, then signing subsequent requests?
I think it mostly just evolved that way. OAuth started on the web and if you're using a browser anyway you might as well take advantage of HTML/JS rendering for the UI and cookies for secure storage.
I would be very interested to see an implementation that doesn't. And I'm not being sarcastic. Even the device flow has you open a browser on another device.
I guess it depends on what we meant when we talk about OIDC, but in system-to-system authentication (e.g. GitHub Actions to ${cloud provider}), there are no browsers involved. But that's a fairly different use-case that happens to be under the OIDC umbrella. https://docs.github.com/en/actions/deployment/security-harde...
You forgot lock in. OIDC is an absolute nightmare for this. Watching everyone delegate all access control to Google and Microsoft is… I don’t even know what to say.
It’s such an obvious trap but it’s convenient and convenience is the only thing anyone cares about.
I’m gonna say I told you so in a few years. Nobody will care.
Even if it isn't total lock-in, OIDC is definitely encouraging consolidation and users have been trained to accept the idea of letting Google or Apple manage their logins.
Identity is next. I think they'll start tying your Google, Apple, etc. account back to your real world ID. It'll be opt-in and they'll give some kind of sucker's reward for it like reduced captchas. It'll be sold to the public with the insinuation the "good guys" use verified IDs and the "bad guys" don't.
> I’m gonna say I told you so in a few years. Nobody will care.
Yep. Auth, identity, etc. are going to get sucked up by big tech and even after it happens we'll have people on HN telling us how awesome it is that we don't have any control over our digital lives because Google, Apple, etc. are "protecting" us. Case in point, the iOS app store.
Passwordless tied back to biometrics is their endgame IMO.
(I'm not even religious, but stuff like that really makes me wonder if Big Tech is taking inspiration from there, like they seem to be doing with 1984 and other dystopian fiction.)
I think Musk is hoping that Twitter can be this. But he should have edged in slowly to make Twitter Auth a trustable product. It now feels like a mess and has less authenticity.
The UK government were going to delegate their age ID system to the porn industry.
Can't say I have ever used Google, Microsoft or Apple ID beyond their own gardens it fills me with ick.
What "lock in"? If I use Google OIDC for my app, there's nothing stopping me from automatically migrating every Google user to a local account pre-populated with their Google claims, or from mapping those users to different identities, and permanently disabling Google OIDC.
Do you allow users to login with any identity provider they want by just providing a URL or do you lock them in to You, Google, and a few other options? You are not the one locked in, your users are.
The original vision for OpenID was for users to own their identity. They could choose their identity provider (including self-hosted) by providing a URL. But it got distorted into Google/MS/FB/Apple owning your identity.
I've never used it, but they can ban your app token, right? So I assume you need to make sure you're keeping your own up-to-date copy of all claims you have access to.
> there's nothing stopping me from automatically migrating every Google user to a local account pre-populated with their Google claims
I wonder your user retention would look like in that situation.
> I've never used it, but they can ban your app token, right? So I assume you need to make sure you're keeping your own up-to-date copy of all claims you have access to.
That's why you should always provide multiple method of authentication.
A simple way is fetching your user email from the OIDC provider, then use it for username/password authn. It's less convenient, but it prevents user from being locked out in case something's wrong with OIDC.
It gets even more depressing when you remember that OpenID was initially meant to allow users to own their identity by self-hosting their identity server or delegating to a trusted entity.
But logging in with a URL was unfamiliar to users and it was easier to click the Google button.
It is so sad that this vision got so distorted by corporate interests into delegating to MS/FB/Google/Apple.
> Watching everyone delegate all access control to Google and Microsoft is… I don’t even know what to say.
Well really, the proper body to issue (digital) identity is the government, which already issues driver's licenses, passports, etc. Google and Microsoft aren't the best bodies to issue identity, they're just the ones that are picking up the ball when the public body best positioned to do so is inactive.
We should be members of a professional institution. In any other profession, it would set such standards, or at least somewhat govern the academic contribution to them.
I am a member of the IET, but it's not strong on CS/SE. Some might be of the BCS (aka Chartered Institute for IT, which says it all IMO) or ACM. The latter is probably the most relevant we have, but it's more publication focussed than professional development/regulation/whistleblowing support/standards providing etc. of traditional bodies.
> most of the internet runs on software not created by a big company
I think you underestimate the amount of sponsorship that carries open-source developers. For example, have a look at the "Most active 6.3 employers" section for contributions to the 6.3 kernel, which amount to over 75% of the lines changed.
Bit off-topic I guess. Had to implement multiple logins with open Id connect of various huge car manufacturers (Korean, Italian, German) and huge oil companies.
Holy croissant is it annoying. Every customer claims to be compliant to the specs, but you end up arguing so much over it.
One of them doesn't tell you how long tokens are valid for, and they are blaming it on their IDP (Salesforce).
One of them just simply doesn't have the possibility for custom schemes (com.example.org://oauth-redirect) and blames their IDP (SAP Gigya).
One of them has their own IDP, even has a debug screen in the html site, never causes any issues. Still requires some locale modification because of Norway's language.
And then they configure it so that users are force-logged out after 1 or 7 days. When users expect to be kept logged in (just like at big apps like Google, Facebook, Instagram, etc). Agggh!
The bizarre one I found is that Facebook is like 90% compatible with the OpenID Connect core profile (happy path at least). If they added token_endpoint to their coniguration[0] it would work, but instead I had to add custom code for FB just for that one thing.
I write SPAs. I use Keycloak OIDC as the authentication layer. I have the SPA set up as a client using the 'Standard Flow' with no Client Authentication[0]. I've carefully set my valid redirect URIs. I use the official Keycloak JS client and the standard JWT authentication implementation in my API server.
To this day I still have no idea if I'm doing everything correctly. I guess I'll have to eventually hire some expensive security consultant to go over everything, but every step of this setup is filled with hidden gotchas:
* There's multiple overlapping standards, each with a dozen different variants. The Keycloak OIDC config refers to OAuth2 over a dozen times.
* There's thousands of blogs and articles, each 1000s of words long and each recommending different things. I have yet to find a concrete guideline for what a 'sane default' set of choices are.
* Am I vulnerable to the issue described in the article? I guess I must be, given I don't see the server-side JWT validator doing anything special beyond validating the signature, so there's no validation of whether the token was generated for my app.[1][2]
* What are best practices for "client scopes"? I notice that the more I add the larger the JWT, but are there any gotchas to watch out for?
I think much of this boils down to there needing to be a published set of recommended defaults for common use cases, alongside some cleanup around deprecated/not-recommended config options.
[0] Given client secrets can be trivially extracted.
[1] Though I guess the fact I'm only using my own auth server and there's only one client means this isn't a problem.
[2] Isn't this how SSO works? One set of tokens to grant access to a bunch of different services?
First, you know which app the access token was issued for, it's the "aud" in the JWT.
Second, you should at least use the "state" parameter on authorization requests so that when you receive the access token via a redirect, you can guaranteee that the user was logging in intentionally and is now completing the flow (rather than coming from an attacker controlled website).
Even better is to use PKCE! It should be common knowledge by now that you must use PKCE[1] if you really want to completely prevent CSRF attacks. OIDC helps with that because it practically makes this a requirement, but you don't need OIDC just for that.
Finally, OIDC is not meant to increase OAuth security as this post tries to imply! It's just a layer on top of OAuth to establish an authentication procedure (OAuth intentionally leaves authentication out of scope as it's focused on authorization protocols). IT does end up improving certain things, but those things can be improved using simple OAuth extensions (like PKCE mentioned), only use OIDC if you actually need user information besides what's in the Access Token.
I think this is a fairly elitist view and I disagree.
I work in application security and still have trouble understanding all the behaviours of oauth and oidc, even after reading the specs multiple times.
If I can’t understand it fully, how are you going to expect some developer who has no security or crypto background implement it correctly when nobody is there to validate the implementation?
I feel like the oauth/oidc are insecure not because of the core logic, but because the design and terminology aren’t easily understood - that complexity IS a vulnerability.
My comment was pointing out mistakes in the claims from OP, I am not sure how you can interpret that as elitist. You may have read something into my comment that I did not say. For example, I didn't say OAuth is simple (though I am still to see a security framework that's better/simpler for the use cases OAuth sets out to solve).
This comment illustrates the issue on a meta level. The GP is a regular developer reaching out for help, raising issues experienced due the complexity of the matter. Very relatable.
Along comes this comment's parent, essentially going "this is wrong in many ways, it's so easy if you just...". Very reminiscent of https://news.ycombinator.com/item?id=8863 .
Authentication and authorization need to be simple (enough) and, most importantly, offer a set of sane defaults. It mustn't require years worth of expertise. It is bound to be misused.
> There's multiple overlapping standards, each with a dozen different variants. The Keycloak OIDC config refers to OAuth2 over a dozen times.
To put it simply, OIDC = OAuth2 + id_token (a standard way for the provider to let your client knows who the user is)
> There's thousands of blogs and articles, each 1000s of words long and each recommending different things. I have yet to find a concrete guideline for what a 'sane default' set of choices are.
There's only one sane default for client-side application: Authorization Code with PKCE
> Am I vulnerable to the issue described in the article? I guess I must be, given I don't see the server-side JWT validator doing anything special beyond validating the signature, so there's no validation of whether the token was generated for my app.[1][2]
The id_token provide by OIDC has the standard field `aud`, which should contain you `client_id`. Match them together and you can check whether the tokens was issued for your app.
> What are best practices for "client scopes"? I notice that the more I add the larger the JWT, but are there any gotchas to watch out for?
Best practice for "client scopes" is as small as possible, the only required scope for OIDC is `openid`, which allows you to fetch the `id_token`. Any other scope like `email`, `profile`, etc... is optional, and provider-specific so should be look up from the provider documents.
As someone who's had to implement these things for our B2B SaaS, I will say it's been a lot less clear how to be as minimally innovative as possible when trying to weave in AuthZ into our product than it is to avoid innovation in something like IaC or CI/CD.
Everything related to AuthZ ends up being so specific to every other decision you make about your infra, and companies that offer solutions tend to charge an arm and a leg so it's not easy to experiment (let's not even talk about vendor lock-in risks).
I've found Cognito + CASL to be an... acceptable middle ground, as Cognito specifically "standardizes" the various OIDC/SAML/OAuth2 integrations such that I can rely on a certain structure within the JWT that apparently (based on this article) isn't consistent! And CASL I at least know how to insert into our infra, though I could see how it might not be the latest-and-greatest...
I just wish I had the time to dive into the theory more. It seems interesting, but it's such a "boring" and "solved" thing that spending time on it doesn't really move the needle when it comes to stuff like customer acquisition.
I'm not quite sure what you're getting at, as OIDC and friends are very standardized when it comes to quite a few of the most important claims you would expect. There's an entire IANA registry [0] devoted to registered claims, in fact.
As for authz choices, you're correct that it's almost always entirely dependent on the application, and subject to frequent change as applications evolve, and as e.g. user and group structure evolves as well. The "managers" group of today might turn into "directors" and "VPs" as the company grows, and "pictures" might soon incorporate "albums" as an optional grouping factor with its own permissions.
In general, I would not really call authentication/authorization boring. There are components of it that are solved, but the reality of today is that people want a "share" link that they can paste in Slack and anybody can use it within seconds, and that kind of speed needs to be accounted for in authz, which is a significant engineering challenge.
Papers like Zanzibar [1] are super interesting to read too. And at least to me, not boring at all.
Yes they are standard, but this is akin to having a 'standard menu' at a restaurant. You're not getting every item on the menu, and for the ones that you do you could make modifications.
OAuth2 and OpenID has many standards documents. A 'standard' OAuth2 server can be written in 30 minutes if you only care about 1 grant type and none of the extra features and 1 flavor.
But it can also take 6 months if you do want support for all the features such as introspection, revokating, multiple grant types, ID Tokens, etc.
Note that this post is only about OAuth2, adding OpenID to the mix blows this problem up further.
The key point is that OAuth2 and OpenID provide a framework for building authentication and identity systems, with a matrix of possible implementation details that often have to be communicated out-of-band. It's still useful as a foundation, but picking an OAuth2 implementation is not as simple as just finding one that is OAuth2 compliant, you might have to dig deep and find out what parts you need and if your server implements them.
I love Auth! It's always the key that unlocks everything else. Chances are that 50% of the "blocked" problems in your company can be solved if you know how their Auth works.
Plus, everyone thinks it's not worth their time to learn so you can be a superhero with just a few weeks of work.
By "boring", I see that as a good thing; you want auth to be boring, is my point. Intellectually stimulating it is in any event (I enjoy learning systems), but I want the process to be me learning how it's done (the "boring"), not having to come up with novel solutions given my problem set (the "exciting").
Well, don't forget it's also a security thing so no matter what DON'T IMPLEMENT IT YOURSELF YOU'LL GET IT WRONG so you sort of _have_ to mostly ignore the spec and start looking for a (probably commercial) implementation.
I think the advice to "not roll your own" is usually in regards to encryption. Other security stuff is more reasonable to take on yourself; I'm not sure it's more likely that you'll use someone elses AuthZ framework any more correctly than you'll implement your own.
Yeah, I'm finding that I also need to understand authentication well enough that I COULD implement it, just to safely and correctly use someone else's implementation.
Thank you for the comment! I have to admit it's hard for me to follow what you're saying, I'm not sure what you mean by "innovation" or "middle ground", or where you're getting that the JWT structure (of an OIDC token?) isn't consistent.
As a startup, I very much do not want to innovate or be in any way "creative" when implementing functionality that isn't my company's core value prop for customers. So for something like AuthZ I want to be as conforming as possible to what "everyone else" is doing, and I want to do that as quickly and seamlessly as I can, so when I say "innovation" here, I'm saying I don't want to build a new library or write a new technology to do AuthN/Z that isn't well-trod ground.
What I've experienced however, is that this isn't as easy as I expected. The "middle ground" here is between "inventing form whole cloth a bespoke library to solve AuthZ" and "do absolutely nothing whatsoever new". Using CASL in my infra's middleware to solve AuthN seems to be working for me. I can write the rules in a way CASL understands, and I was able to quickly implement the middleware without having to do anything crazy.
As for "JWT structure being inconsistent" I mean to say that often I'm asked to "connect" many different providers, e.g. Google social sign-in, Okta, Auth0, etc., all of whom have their own way of structuring their JWT payloads (beyond the standard that is), and using Cognito as an intermediary has been helpful to avoid all of that, as again, I'm trying to do as little as possible myself.
Wow, this is the first comprehensible documentation on OAuth (post 1.0, which I actually did understand) I've ever seen. If the author of the StackOverflow post is on here, please publish a book, I'll buy it.
Wow, thank you so much for that compliment! I have a lot of other ideas / writings I want to try to post to Hacker News that I think people would find interesting, I honestly just posted this particular answer as a test. If you'd like, you can follow me on twitter: https://twitter.com/NathanWailes
> Relying on plain OAuth 2.0 for authentication is dangerous if you (the client) are just trusting ANY valid access token you receive that's associated with that user as a reliable indicator that you're receiving the request from the actual user, without knowing whether that access token was generated by the user trying to log into your site or if it was generated by the user logging into some other (malicious) website/app.
That’s why there’s a “state” param that is passed between the source and the identity provider. It validates that the request indeed came from your system. Combined with prop CSRF protection you can ensure the user willfully logged into the system and the response from the IdP was intended for your system.
The article that is linked in the SO post actually makes exactly that point:
> Some people believe that using the state parameter in OAuth protects against token substitution.
The only binding a browser cookie to state protects against is Cross Site Scripting.
Note that I am not arguing about this point as I don't understand nearly enough about OAuth/OIDC, just pointing out this has been adressed in the article.
I'm pretty confident you're wrong there. The state param mentioned is a part of PKCE to verify to the originating source code that you've received the code. The original source of the request then can use that state and compare it to the starting request (or even use it to look it up) and then generate a verifier code to send to the token endpoint along with the code to exchange for tokens. This attempts to prevent a MITM attack by keeping something secret.
I believe what you are actually wanting to discuss is the aud claim, or rather the audience claim.
I don't understand what's the point of this. So there is an answer that doesn't answer the question in SO, and we glorify because it... is confirmation that yes, it's bad?
OpenID is a specific layer on top of OAuth2. It standardised claims for authentication, scopes it down to the 2 credentials flows it can care about, and that's core in a nutshell. It's complicated, but so is HTTP, which most people don't use directly anyway (and the same should be applied for OpenID, just use a blessed implementation, the OpenID foundation maintains a list of certified libraries you can rely on).
Oh. I remember having to deal with this. What a fucking nightmare.
See, a large part of the problem comes from the fact that there are really two things you want to encapsulate under the word "auth," (authentication and authorization), but OAuth2 only evan attempts one of them, and pretty badly at that.
That isn't to say OpenIdConnect is perfect or anything, but at least when you're doing the dance of encrypting a signed token (which, BTW, is the correct order, because in order to modify the payload and still have it validate, an attacker would need to break the encryption first in order to modify the payload into something malicious), having proper TTLs, and then, on top of that, having a way for the client/user side to signal the server/API resource side that "hey, I'm done with this token a little early, so just ignore it forever now, mmmkay," you reduce the amount of damage an attacker/malicious observer can do by intercepting one valid token.
Oh, but that's only if both the client/user side and the server/API resource side each implement their half of the protocol 100% correctly... which is, of course, nontrivial and full of landmines for you to step on. [0]
Now, I stepped in this particular pile of bullshit because the company I was working for at the time was in health tech, and we had a client who thought they wanted to exchange EPHI (electronic personal health information -- you know, the kind of data that HIPAA makes radioactive with its massive financial penalties) with our servers to do some other random crap I didn't really care about on their side. But, you can end up in the exact same place by replacing "exchanging EPHI" with "accessing any confidential or sensitive data," so don't think you're safe from all this just because you're not in the healthcare space.
Fortunately, in the end, our client realized that they did not, in fact, have the technical expertise and know-how to be able to deal with the security implications of what they were saying they wanted to do. So, our product and sales people talked them down to something that they could handle, and, which, fortunately, did none of give me headaches, cause me to lose sleep, or make me want to strangle people. And, that meant I could go back to paying attention to the things that actually mattered at the time, like making sure our RDS instance wasn't going to keel over, hiring a couple new senior SWEs, and occasionally even leading the team.
I see that turned into a bit more of a rant than I had expected, so I'm just going to cut myself off here. I hope anyone reading this is able to learn from my experience and maybe not drive themselves crazy in the process.
Thank you for the tip! I tried Googling the term but I didn't see anything jumping out at me as being a good resource to read up on it; do you have particular things you'd recommend?
Thank you! Is there a particular book / article / video you recommend? Researching these things can be a nightmare so I find it helpful to ask for recommendations.
One may ask for sources... And the original Q in this case is so simple that even ChatGPT can easily answer it. It is not like there is room for opinions. It is basic CS projected on well known techs.
I do not care about you or why you are here. The answer points to a source that have the correct answer to a very basic question. I have no obligations to you or your hubris. You millennials are really something else. How you even manage to tie your own shoelaces amazes me.
When I was a kid the fundamental crime in knowledge was to actually just tell all the answers. You are whining about a meta discussion on a topic where the original answer should have been just fking Google it.
I've heard that in the context of AWS, but I'm still not familiar with it. Do you recommend any articles in particular that give a good (brief) introduction to it?
I don't think you want ABAC. ABAC is for the cases when a set of attributes will grant access. The more common thing is RBAC. RBAC is that a user have been assigned some roles that comes with access.
A good example with ABAC is if person X uses an IPhone with the latest major updates then access to some wi-fi is granted.
Also, roles comes with a hierarchy. This is important when you work with SOX controlled companies.
Several security consultants will try to sell ABAC as a necessity along with RBAC. It is for sure not.
We need the international software development community to have its own standards body outside of massive corporations and creaking old institutions with outsized influence. Standards should represent the majority of people writing and using the code.