ROPC: Not the Login API You're Looking For!
This week, Jacob Ideskog, CTO at Curity, wrote an excellent article explaining the need for a hypermedia login API. He told about how many resort to Resource Owner Password Credential (ROPC) flow to perform API-based login. This limits authentication to a single-factor (a password) that is susceptible to various attacks. It also means that third-party applications come in contact with the user's credential, he writes.
In the article, Ideskog also explains that the use of ROPC is motivated by a desire to create award-winning apps. Till now, standards bodies, Ideskog, myself, and many, many others have fought with ambitious mobile app developers to convince them to do login in the browser for security's sake. Product owners and app developers have resisted this. Usually, they prefer an easy-to-use login process where they have complete control over the user experience then they do of bullet-proof security. To codify their choice, they often use ROPC or some shoddy invention of their own.
This is understandable, honestly. People don't use an app just to login. I get it, but ROPC and insecure APIs are not the solution. We, the community, need something that will enable app developers to achieve their goal of delivering excellent user experiences while keeping users safe. OAuth, OpenID Connect, OAuth for native apps, CIBA, and PAR are part of the solution, but more is needed.
In his article, Jacob explains that hypermedia is the architectural pattern that lends itself to successfully overcoming this challenge. He points out that authentication is a state machine. As a user logs in, they transition from state to state until an error occurs or their identity is verified. (Remember that HATEOAS thing none of us could pronounce? It's that again.) Hypermedia APIs -- or those REST APIs that have ascended to to level 3 -- are ones that tell the client what to do next. They keep the client app dumb, and maintain the state of a client's journey through a process server-side.
Keeping state on the server is critical in a login process because authentication is a dog's dinner. It's a real mess! You got all kinds of authentication providers ranging from smartcards to Integrated Windows Authentication (IWA) to federation with SAML and OpenID Connect to social login with Google, GitHub and others to the hip new San Francisco startup's "password killer" technique that is totally bespoke. This host of authentication option is only the start. We also have registration; each of these authentication options does something different for signup. They also have different stories for account and credential management.
Once logged in, some additional action almost always needs to be taken (that may or may not involve user interaction). Is this authenticated user a customer? Are they subscribed to premium services? Are they in the expected geographical location? Are they on a new device that they've never used before? Have they accepted the updated terms of service? Depending on the answer to these questions, various actions have to be taken. The server, not the client, needs to drive this because it's the one that controls the requirements and configuration.
There's also consent. We might need the user to provide explicit consent after login. Additional authentication factors may also be required to positively identity the user depending on if the client is provided by the same organization that controls the login server (a first-party) or if it's from a trusted third-party provider (TPP). Ensuring that the client app hasn't been cloned is also important, Ideskog, says. Depending on contextual information (e.g., the current threat level), additional proofs of identification may be required that normally wouldn't be.
See? A real dog's dinner! So, we can't recode this complex logic into every front-end. It's too much. We need to keep this server-side, and expose it via a hypermedia API that obscures this complexity from the mobile and single-page apps. It's also not possible to solve using the simple API provided by ROPC since login is much more involved than a single request/response and strong authentication is needed. Instead, clients should only process the resource representation returned by the server, collect user inputs and follow links. In other words, they should be hypermedia clients, like browsers.
At Curity, we're working every day in this space, so we have a growing list of information available. You can find a collection of resources in my subsequent post. If you want to learn more about this API besides what's covered in those or have comments, contact me on Twitter or LinkedIn.