[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)
 
web link (stackoverflow.blog)
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)