[HN Gopher] The complete guide to protecting your APIs with OAuth2
       ___________________________________________________________________
        
       The complete guide to protecting your APIs with OAuth2
        
       Author : mooreds
       Score  : 153 points
       Date   : 2022-04-12 16:34 UTC (6 hours ago)
        
 (HTM) web link (stackoverflow.blog)
 (TXT) w3m dump (stackoverflow.blog)
        
       | tptacek wrote:
       | It'd be useful to capture why OIDC exists (it addresses actual
       | vulnerabilities that crop up when you try to do OAuth as a
       | single-signon scheme rather than just as a way of delegating out
       | the ability to schedule a tweet with a 3rd party service), and to
       | pull out JWT --- you may not be able to avoid JWT if you're doing
       | OIDC, but it's helpful to know what problems JWT addresses and
       | what ones it doesn't, because if you can avoid JWT, you'll almost
       | certainly be better off.
        
         | paxys wrote:
         | The only real advantage of OIDC is that it enforces a strict
         | user structure, so different services can understand common
         | fields like id and email. The security aspects of it can all be
         | implemented with plain OAuth2 as well without the added OIDC
         | layer.
        
       | abraae wrote:
       | > In general, use the Authorization Code grant if there is a
       | human being involved and the Client Credentials grant if you are
       | performing server to server communication.
       | 
       | This is the crux of the article.
       | 
       | We're integrating with a vendor now that has imo chosen
       | incorrectly to use auth code instead of client credentials.
       | 
       | This leads to several problems. One is that we need to store
       | their refresh tokens, which go stale after 2 weeks. Since it's
       | theoretically possible that the customer doesn't use the
       | integration for 2 weeks, we need to preemptively use the refresh
       | tokens ourselves behind the scenes every 2 weeks to prevent this.
       | When the vendor changes tech behind the scenes, they just chuck
       | away all existing tokens, so we then need to contact all
       | customers asking them to log in again in order to get new refresh
       | tokens. It sucks and it's brittle as hell.
       | 
       | Tldr; don't use auth code grants (the ones most people think
       | oauth is) for server to server integrations.
        
       | weinzierl wrote:
       | For another quick way to get started with OAuth2, I can recommend
       | reading the 2.1 spec draft[1].
       | 
       | For a spec it is quite readable and pretty short. One reason for
       | this is that it _" [..] is an in-progress effort to consolidate
       | and simplify the most commonly used features of OAuth 2.0."_ [2]
       | 
       | It does away with most of the complicated grants/flows of
       | previous version and basically boils down to just two[3]:
       | 
       | - Authorization Code Grant
       | 
       | - Client Credentials Grant
       | 
       | Authorization Code Grant (which now implies PKCE) is what you
       | most probably want in most cases. So instead of complicated
       | decision trees[4] for most people it will be:
       | 
       | "Learn one grant and be done".
       | 
       | [1] https://datatracker.ietf.org/doc/html/draft-ietf-
       | oauth-v2-1-...
       | 
       | [2] https://oauth.net/2.1/
       | 
       | [3] There is also the Refresh Token Grant, but it cannot be used
       | alone. There is also an extension mechanism to define new grants
       | and we will have to see if it is used.
       | 
       | [4] https://alexbilbie.com/images/oauth-grants.svg
        
         | mooreds wrote:
         | Author here.
         | 
         | Yes, I think that reading the OAuth 2.1 spec is a great place
         | to start. They've taken 10ish years of real world learning and
         | condensed it down. I first wrote about it 2 years ago[0] but
         | have been following along on the email list and they seem to be
         | getting closer and closer. I don't think it is at 'last
         | comment' yet, but I know they've done a lot of work.
         | 
         | I am also excited about GNAP, which is a 'from scratch' attempt
         | to solve much the same problem. They've made some great
         | progress[1].
         | 
         | I briefly cover both of those in the article, in the "OAuth's
         | future" section
         | 
         | 0: https://fusionauth.io/blog/2020/04/15/whats-new-in-oauth-2-1
         | 
         | 1: https://justinsecurity.medium.com/the-gnapathon-57ee110508ac
        
       | kache_ wrote:
       | I've got Opinions and Thoughts on OAuth2 (& all those other
       | protocols, SAML/OIDC)
       | 
       | They all model sharing trust over to untrusted boundaries using
       | signed messages generated by one signing authority. There's
       | always a client, different clients have different properties,
       | they're trying to access a resource, and there is a privileged
       | signatory.
       | 
       | Lots can be learned from their specs, but please don't limit
       | yourself to them, and don't even worry about following the spec
       | accurately (no one really does). Just know WHY the spec is
       | designed the way they are so that you avoid the same security
       | pitfalls. And understand WHAT you're doing: granting signed
       | assertions based on some user interactions
       | 
       | Not only that, but just because it got through the IETF gauntlet
       | doesn't mean they don't have problems. These specs slide around
       | like crazy. My OAuth is different from your OAuth. The antidote?
       | Just write Good Docs and provide good libraries for your
       | integration path. A smart kid in a vacuum solving the same
       | problem OAuth solves will come up with OAuth. Try to emulate that
       | smart kid. And understand why certain concessions are made on the
       | protocols you're taking inspiration from because you might
       | actually not need to make those concessions
       | 
       | This stuff hasn't been fully figured out, so push the needle
       | forward and don't be limited by the past. All protocols are
       | incorrect given a large enough time span.
        
         | mooreds wrote:
         | > A smart kid in a vacuum solving the same problem OAuth solves
         | will come up with OAuth. Try to emulate that smart kid. And
         | understand why certain concessions are made on the protocols
         | you're taking inspiration from because you might actually not
         | need to make those concessions.
         | 
         | I have a different perspective. I work for an auth company now,
         | but before I did, I didn't want to think about this at all.
         | 
         | I wanted to get some code shipped and build differentiating
         | features.
         | 
         | I agree that the IETF and other standards bodies are not
         | perfect (there are specs that get published that never get
         | implemented widely and standards that are implemented that are
         | retrofitted specs).
         | 
         | I do think that building on top of a spec is a great way to
         | "stand on the shoulders of giants", get access to people's
         | experience in use cases you haven't seen yet, and accelerate
         | your development effort.
         | 
         | Also, there are a lot of folks who've written client libraries,
         | docs, and tutorials around OAuth that people can leverage. How
         | many devs will have experience with your "antidote"? I dunno,
         | but my guess is the number rounds to zero.
        
         | paxys wrote:
         | A smart kid implementing encryption from scratch could come up
         | with RSA or PKCS or EdDSA on their own. What's more likely is
         | that they will have major holes in their implementation that
         | decades worth of research in the area has already addressed.
         | 
         | Similarly, while it is good to understand the various OAuth2
         | RFCs and why certain decisions were made, you should also just
         | follow them instead of rolling your own auth exchange
         | mechanism.
        
           | kache_ wrote:
           | it would be great if everyone did "just follow them", but I
           | haven't seen a single spec compliant implementation in all my
           | years
        
         | lijogdfljk wrote:
         | I'm often frustrated by no clear OAuth-like system for non
         | general auth. Ie you have a server and a clientside JS app. How
         | do you secure it? Cookies are the obvious thing to reach for,
         | but in general i was never clear on exactly what the options
         | are. What are pros and cons of various types of
         | implementations? What are the do's and don'ts? And even if i
         | use something i often felt i was implementing all of it (due to
         | obscure languages choices frequently), but the specifics of the
         | impl were often difficult to find.
         | 
         | It's embarrassing to say but auth has always confused me. And
         | of course managers always instantly say "Just use OAuth" -_-
        
           | mooreds wrote:
           | > you have a server and a clientside JS app. How do you
           | secure it?
           | 
           | I'd love to hear what others have to say, but I'd suggest
           | encrypted session cookies. This is what some frameworks
           | support out of the box (rails has docs here:
           | https://guides.rubyonrails.org/security.html#sessions ).
           | Would store the session in an HttpOnly secure cookie.
           | 
           | If you need to scale your server side horizontally, you'd use
           | redis, a database or something similar for your session
           | store.
           | 
           | This feels like a problem usually solved at the framework
           | level (and has been for years) so maybe that's why there are
           | not as many "best practices" docs around?
           | 
           | This OWASP document may be a useful read too: https://cheatsh
           | eetseries.owasp.org/cheatsheets/Session_Manag...
        
       | laerus wrote:
       | Wasn't there an on the making successor to OAuth2 from the same
       | people that was supposed to be a totally different take? I
       | remember hearing something about it but I cannot recall or find
       | the source.
        
         | mooreds wrote:
         | I think you are thinking of GNAP. The doc is still in progress,
         | you can see the 9th draft here:
         | https://datatracker.ietf.org/doc/draft-ietf-gnap-core-protoc...
         | (scroll down).
         | 
         | I looked at it a year ago and wrote up some of the benefits:
         | https://fusionauth.io/blog/2021/01/07/gnap-next-gen-oauth
        
       | methyl wrote:
       | I think oauth is abused as a way of protecting your API. Often
       | it's just an unnecessary complication which makes your API harder
       | to use and your libraries bloated.
       | 
       | If Stripe can get away with just public and secret key pair,
       | there is a big chance it's enough for you as well.
        
         | yoavm wrote:
         | I totally agree with you and so I'll put a shameless plug here:
         | I've created OAuth Hopper[0] exactly for this reason.
         | 
         | It essentially takes a resource behind OAuth, strips OAuth from
         | it and exposes it with Basic Access Authentication. I'm using
         | it to let clients that don't support OAuth access services that
         | force it.
         | 
         | [0] https://github.com/bjesus/oauth-hopper/
        
         | [deleted]
        
         | gscott wrote:
         | Twilio as well
        
         | pbreit wrote:
         | Amen! I do not understand the rash of OAuth-style
         | authentication mechanisms for pure server-to-server
         | applications.
        
         | tremon wrote:
         | What user authentication does Stripe handle? As a user I've
         | interacted with Stripe's services a lot, but I've never needed
         | to authenticate myself to them.
        
           | pbreit wrote:
           | https://stripe.com/docs/api/authentication
           | 
           | Even pure server-to-server applications with "no user
           | involved" are starting to use OAuth authentication which I
           | don't quite understand.
           | 
           | https://www.verygoodsecurity.com/docs/payment-
           | optimization/a...
        
       | pbreit wrote:
       | Can someone explain the increasing usage of Oauth credentials for
       | pure server-to-server applications (like Stripe payment
       | processing)?
        
         | mooreds wrote:
         | I haven't worked with Stripe recently, but if I had to guess,
         | I'd say it is some combination of:
         | 
         | * Time limited (rotation built in).
         | 
         | * If using signed tokens, integrity of contents can be
         | verified.
         | 
         | * Lots of libraries and knowledge around how to use it.
         | 
         | * Tokens allow for more interesting/useful payloads than an API
         | key.
        
       | brap wrote:
       | As someone who has never used OAuth2 before, this article was not
       | helpful at all. Calling it a "complete guide" is a total
       | overstatement.
        
         | hotfixguru wrote:
         | I have also made an attempt at writing an article for
         | developers that want to implement Oauth2.[1] Not a complete
         | guide, but a short(8min) read that aims to get you started.
         | 
         | [1]https://engineering.intility.com/article/implementing-
         | oauth2...
        
         | mooreds wrote:
         | Author here.
         | 
         | @brap, sorry it wasn't helpful. It's aimed at folks who want to
         | protect APIs, but maybe I missed the mark.
         | 
         | This article (which I co-authored) may be more helpful:
         | https://fusionauth.io/learn/expert-advice/oauth/modern-guide...
         | 
         | It was also discussed here on HN, if you want some different
         | perspectives: https://news.ycombinator.com/item?id=29752918
        
           | treve wrote:
           | Maybe calling it an introduction instead of a 'complete
           | guide' might quell some of this.
        
           | brap wrote:
           | I do appreciate the effort, and sorry for being a dick with
           | my earlier comment (bad mood). I do feel though that this
           | lacked concrete examples, and maybe should have taken a step
           | or two back to explain the more basic concepts. For example,
           | who owns the authentication service, is it me (the todos
           | developer) or a 3p? What exactly is the difference between
           | all of these different tokens? What's the actual protocol for
           | issuing and using them? Etc. I think something like a "Todos
           | API with OAuth2 from scratch with code snippets" could have
           | been super helpful for noobs like myself.
        
             | Traubenfuchs wrote:
             | Your sentiments and questions are all perfectly valid. I
             | believe the majority of developers implementing oauth2 on
             | their servers or integrating another service they need
             | oauth2 for have not fully understood what they are doing. I
             | know that's the case for me and I successfully implemented
             | solutions for OIDC, saml, three-legged oauth2 and two-
             | legged oauth2 on both the server and client. It's all an
             | overengineered mess.
             | 
             | A "complete guide" to this is still sorely lacking -maybe
             | because it just is that complicated and can not be dumbed
             | down?
        
           | magicalhippo wrote:
           | Not op, but I found it a bit lacking given the title. From
           | the article:
           | 
           |  _While I'll dive further into how you actually use OAuth to
           | protect an API in your system below, including code examples,
           | [...]_
           | 
           | I failed to find much concrete around how to use OAuth to
           | protect an API, and no code samples. Is this a part one in a
           | series? If so, it should be more clear about that perhaps.
           | 
           | edit: For example, I just had to secure my non-Azure API
           | using access tokens issued by Azure AD. Lot of details[1]
           | about how to verify that they're valid, actually issued by
           | Azure AD (one does not simply download a certificate), and
           | it's issued for the right thing.
           | 
           | That said, I found the why and standards section very nice,
           | and the grant selection sections were helpful.
           | 
           | [1]: https://docs.microsoft.com/en-us/azure/active-
           | directory/deve...
        
             | mooreds wrote:
             | > I failed to find much concrete around how to use OAuth to
             | protect an API, and no code samples.
             | 
             | I think this may have been an oversight during the final
             | editing process. I ended up having to split this up into
             | two articles, as you surmised.
             | 
             | The second one is a blow by blow of the authorization code
             | grant (and how an API should validate a token) and will be
             | published later this week.
             | 
             | But I should have caught that we promised the code in the
             | intro and removed that.
        
             | magicalhippo wrote:
             | Just to expand a bit on my criticism. It's called a
             | "complete guide to protecting your APIs with OAuth", yet
             | there's no discussion of:
             | 
             | - Authorization server, roll your own, run your own (like
             | Ory Hydra), or use third-party (like Azure AD)?
             | 
             | - Tokes, if you can choose, should you go with opaque
             | tokens, JWT or something else? What about token lifetimes?
             | 
             | - When you get a token from a client, how do you validate
             | that the token is valid?
             | 
             | There's probably more, but I feel at least these points
             | should be included in a "complete guide".
             | 
             | Change the title and it's a fine OAuth blog post. edit: for
             | example, add ", part 1 - introduction".
        
       | tbirdny wrote:
       | I can see the benefit of OAuth if you have an API that multiple
       | customers will use since it allows your customers to manage the
       | security themselves, to create and revoke tokens. I'm wondering,
       | is there any benefit to OAuth if the web service is for your own
       | company, between your own servers, even if the traffic goes over
       | the internet, compared to using a simple token in a header that
       | you generate by hand and the api checks for a match?
        
         | paxys wrote:
         | Between your own servers - not really. For that use case OAuth2
         | will be just as effective as a single shared secret.
        
       | z3t4 wrote:
       | Am I the only one who thinks Oath is over-complicated bordering
       | to security through obscurity and vendor lock-in ?
       | 
       | The protocol could be as simple as this (using password)
       | app => auth-server (can user:pass login to app?)         auth-
       | server => app (no | yes)
       | 
       | Or using "crypto":                   app => auth-server (can user
       | login to app ?)         auth-server => app (only if user can
       | solve challange=XXXX with answer=YYYY)
       | 
       | Asking for capabilities:                   app => auth-server
       | (what permissions do user have on app ?)         auth-server =>
       | app (user has access to: X, Y, Z)
        
         | paisawalla wrote:
         | First scenario: user's password can be captured and stored by
         | the app.
         | 
         | Second scenario: could work if we're talking about a trusted
         | third party app (e.g. Authy) generating the response. Otherwise
         | presumably you enter your secret into the app, where the OTP is
         | derived. This has the same problem as above.
         | 
         | Third scenario: no authentication required to query for
         | capabilities? _Puts on black hat_ Ok let me quickly check
         | [A-Z]{1,18}@whitehouse.gov and see which accounts I 'm most
         | interested in.
        
         | mooreds wrote:
         | Sure, if all you need to know is "can this user login" and you
         | don't have multiple servers that want to authorize the user,
         | you probably don't need OAuth. You can use sessions and
         | cookies. See my comment elsewhere in this post about this:
         | https://news.ycombinator.com/item?id=31007003
         | 
         | Interestingly, your first scenario is the resource owner
         | password credentials grant:
         | https://datatracker.ietf.org/doc/html/rfc6749#section-4.3
         | 
         | The second scenario is, I believe, the JWT bearer grant:
         | https://www.rfc-editor.org/rfc/rfc7523
         | 
         | Of course in the OAuth grants, the auth-server returns a token
         | to be presented to other resources instead of a "yes" or "no"
         | answer.
        
       | z3t4 wrote:
       | I was expecting how to implement OAuth2 in pseudo code or
       | JavaScript...
        
       | intrasight wrote:
       | Authentication is just one piece of the "protecting your APIs"
       | puzzle. Other pieces including rate-limiting and billing. Those
       | are more challenging.
        
         | suyash wrote:
         | Yes, also don't forget securing API credentials properly. As a
         | matter of fact, I have a blog post coming about this topic
         | soon.
        
           | mooreds wrote:
           | Would love to see it. Whether tokens or API keys, I'm always
           | interested in how folks recommend securing them.
           | 
           | There's also some interesting stuff around token binding
           | happening. DPoP is moving towards becoming a standard:
           | https://datatracker.ietf.org/doc/html/draft-ietf-oauth-
           | dpop-...
        
       ___________________________________________________________________
       (page generated 2022-04-12 23:00 UTC)