Okta's developer blog covers authentication topics like OAuth, OpenID Connect, JWTs, Paseto, and password security.
HN links it for explainers on OAuth, Sign in with Apple, and Paseto as a JWT alternative, and for breached-password guidance; commenters call Okta a reputable source.
DPoP described in RFC9449 - you can see from the RFC number it's quite new. I don't think there's wide support for it, but at least Okta supports it[1] and I think Auth0 are also working on adding DPoP.
Is it good? I'm not a fan. To use DPoP safely (without replay attacks), you need to add server-side nonces ("nonce") and client-generated nonces ("jti", great and definitely not confusing terminology there).
You need to make sure client-generated nonces are only used once, which requires setting up... wait for it... A database! And if you'll be using DPoP in a distributed manner, with access tokens then, well, a database shared across all services. And this is not an easy-to-scale read-oriented database like you'd have to use for stateful tokens. No, this is a database that requires an equal number of reads and writes (assuming you're not under a DDoS attack): for each DPoP validation, you'd need to read the nonce and then add it to the database. You'd also need to implement some sort of TTL mechanism to prevent the database from growing forever and implement strong rate limitation across all services to prevent very easy DDoS.
It seems like the main driving motivation behind DPoP is to mitigate the cost of refresh tokens being exfiltrated from public clients using XSS attacks, but I believe it is too cumbersome to be used securely as a general mechanism for safe token delegation that prevents "pass-the-token" attacks.
[1]…
I don't like it either (it's just syntactically annoying), but I am pretty sure it's there just for historical reasons: https://developer.okta.com/blog/2019/01/16/history-and-future-of-async-javascript
It's at least cleaner than a bunch of chained .then()s or nested callbacks, which is what we had to do in the old days.
If you don't want to use async/await, you can still do it the old-fashioned ways. But it's not really that difficult to just wrap whatever you're doing in an async call, is it? e.g.
(async () => { await someAsyncThing(); await Promise.all(aFewAsyncThings[]); await someOtherThing(); })(); Will cause all of those to run in sequence as synchronous operations one after another. Promise.all() can help with concurrent async things, or you can use a queuing library like p-throttle/p-limit if there are rate limits to observe.
Yeah, it's a bit of syntactic complexity, but once you get the hang of it, they're not so bad and let you more cleanly think about which operations are synchronous & blocking and which can be async in the background (important for both performance and UX).
The blog mentions right at the start that it's based on OAuth 2.0/OIDC, similar to how you log in to your Google account in Thunderbird for example.
> I always wonder how it will work for someone writing their own client, perhaps a very basic client (or a bot).
For interactive clients, it'll be the standard OAuth 2.0 Authorization Code flow[1]. For non-interactive services they say in the proposal[2] that one uses the existing method but they will implement the standard OAuth 2.0 Client Credentials flow[3], which is effectively like a traditional username/password deal, though the "password" is not the account password.
[1]: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow
[2]: https://github.com/matrix-org/matrix-spec-proposals/blob/0023db90aca5e1e55cc6da0848337e2c3a32bd19/proposals/3861-next-generation-auth.md#application-services
[3]: https://developer.okta.com/docs/concepts/oauth-openid/#client-credentials-flow
Thank you for the reminder! Based on my (very) limited knowledge, OAuth2 can still be used for so-called "pseudo-authentication" [1]. I'm not saying it is as good as SAML/OIDC, but those technologies are a major pain to implement and support for a small team. Pseudo-authentication seems like a good "bang for the buck" tradeoff. A more refined version of my question might be, "Is pseudo-authentication good enough to get past most security teams until you can scale up to SAML/OIDC?" I'm sure it likely isn't good enough for highly regulated industries (or Fortune 100 companies) that have prescriptive compliance regulations, but maybe it is good enough to get going in less rigid circumstances?
[1] https://developer.okta.com/blog/2017/06/21/what-the-heck-is-oauth#pseudo-authentication-with-oauth-20
https://developer.okta.com/blog/2018/06/11/how-to-prevent-your-users-from-using-breached-passwords ("How to Prevent Your Users from Using Breached Passwords") | https://github.com/OktaSecurityLabs/passprotect-js is an example.
Good behavior:
> The new NIST recommendations mean that every time a user gives you a password, it’s your responsibility as a developer to check their password against a list of breached passwords and prevent the user from using a previously breached password.
SP 800-63 specifically: https://pages.nist.gov/800-63-3/ | https://pages.nist.gov/800-63-4/
> I haven't seen a self-discoverable REST API ever in the wild
I'm super cognizant this entire discussion hinges upon semantics, nuance, etc but the Okta API isn't terrible about that
https://developer.okta.com/docs/reference/core-okta-api/#hypermedia
I haven't personally tried `curl https://$
{yourOktaDomain}/api/v1` to see what the bootstrapping process looks like, but I can attest they do return _links in a bunch of their resource responses, and I believe their own SDK uses them, so they're not just lip service