Understanding OAuth: Grants

From a practical perspective

Gratus Devanesan
Code Smells
8 min readMay 21, 2019

--

There is a lot written about OAuth and grant types and my goal here is to be a little sparse on complexity and instead provide practical guidance.

I’ve also seen a lot of examples suggesting if Native App use this, if Webapp use this etc. I also don’t think that is the right way to reason about grant types — OAuth are a set of principles and as such can be extended to any type of application and even taken out of the digital realm to physical processes (like signing out a library book).

Instead of talking about native apps and web apps, I want to reason in terms of actual nouns used in OAuth and then provide non digital examples to show the relationships.

But first some vocabulary:

Resource Owner — somewhat self explanatory. The rightful owner

Resource Server — the server that provides access to resources, owned by the Resource Owner.

Authorization Server — this is the server that actually holds your credentials, whatever they may be, and in response can provide some information regarding what you are allowed to access on the Resource Server.

Client — the application that wants to interact with protected resources on a resource server.

Some non digital examples for context:

Your bank is the resource server of your bank account, but you are the resource owner of that account. You are also the client and the client is the resource owner.

The library is the resource owner, resource server of library books, and you are the client. The library is also the authorization server, via the library card.

How to decide which grant type to use?

Flow chart to decide on grant types

The above is a flowchart to help you decide on a grant type. This is not a comprehensive view of what is possible, or how OAuth should be implemented — but rather suggestive of what would be the most ideal flow given a particular situation.

The details of these grants are specified in RFC 6749 — but again this document is more interested in pragmatic choices and less focused on technical implementation details.

Are you a human?

The question here is whether or not you are a human being or a trusted system. The idea is that a trusted system can keep a secret differently form the way a human can keep it, and that System A would not be able to sniff out System B’s secret.

If you are not a human, but some type of automated system, you would choose the Client Credentials Flow. In the Client Credentials flow the assumption is that the client can hold a secret — which means it cannot be a mobile app, but needs to be a protected system, like a backend web server. The client provides a client id and a secret to an authorization server and in return obtains an Access Token which it can use against the resource server.

More importantly, the Authorization Server is aware that it is handing over an access token to an unattended system, and that the Access Token should not have permissions to resources that require the user to be present.

In the non digital world this would be an inter-library loan, where a library requests a book from another library. No patron is present, and libraries have a form of establishing trust and accountability between each other. Library A will provide access to its resources to Library B. Library B will eventually provide access to those resources to some patron, but Library A is not concerned with that. Library A is only concerned with trusting Library B.

Do the Client and the Authorization Server belong to the same owner?

The Password grant type implies that the client can authoritatively capture the user’s credentials. For example, if Twitter wanted to use Google as the identity provider (IDP), the user should not be asked to enter their Google password on a Twitter client — instead they should provide their password only to Google. If Google built an app, and used itself as the IDP, it could request your password right in its app. More simply put, if the authorization server and the client are controlled by the same entity and are recognized by the user as the same entity, a Resource Owner Password Credentials can be employed. This is a simpler flow and reduces maintenance burden and complexity. Practically, this is the normal “password in exchange for access” flow that we are most familiar with, but as part of OAuth you end up with a bearer token instead of a session cookie.

A simple example is your library card. The “client” — which in a non digital institution (i.e. no self checkout) would be the librarian, belongs to the library, and the information related to the library card, used for verification, also is kept with the library. The librarian is then free to ask what your birthdate is and then check if your answer is true or false. There is no loss of confidentiality as the librarian can plainly see your birthdate on your profile.

Do the Client and the Resource Server belong to the same owner?

Here the question becomes a little technical and the issue is one of whether it is acceptable for the Access Token to end up with the client (browser or otherwise). If it is ok for the Access Token to end up with the client, an Auth Code flow is not necessary. However, if the Access Token should not end up on the client, then an Auth Code flow is required.

The situation is one where we are using a 3rd party Identity Provider (IDP), like Google or Twitter, only to establish trust on who the user is. However, we are not interested in accessing Google’s resources directly but are more interested in resolving who the user is, so we can authoritatively give them access to our own resources. In this case we would use the Auth Code Grant Type flow. This flow ensures that the IDP provided Access Token never surfaces to the client, where it can be stolen and abused. Instead, the Access Token would be used only to establish who the user is and the client will be given a session id, cookie, or completely separate token, to maintain an authenticated state between the client and the resource server.

An Auth Code Grant is probably the most abstract and purely digital authentication flow. It is necessitated by three factors: 1) the authorization server cannot trust the client, because it doesn’t know it, 2) the resource server is not capable to validate identity, 3)the authorization server provides a one time use code as a form of acknowledgement that this person’s identity has been verified, which then in turn can be exchanged for a token that has pre-determined set of information, which is not as sensitive as the information the authorization server needed to establish identity.

For example, if I applied for a PhD, the university will ask for a reference. However, it will only accept the reference from the professor directly, and I will simply hand over contact information (email, phone number), and the admission staff will contact the professor directly to obtain the reference. In this case, I call the professor and the acknowledgement allows me to pass on their contact info (access code) to the admission staff, who then will obtain the reference (access token).

Auth Code flow modelled as university admissions steps

Essentially, auth code grant minimizes Confidentiality and Integrity risk. The admission’s committee does not need to snoop around my personal life to establish trust (confidentiality is maintained), and will obtain the reference letter directly from the source (integrity and confidentiality is maintained).

Do the Authorization Server and the Resource Server belong to the same owner?

In the situation where you want to authenticate against Google, so that your application can pull information from Google, belonging to the authorized user, the flow to employ would be an Implicit flow. The user authorizes against an Authorization Server directly and obtains an Access Token which can be used against the Resource Server. Since the Access Token represents claims of the user directly against resources on the Resource Server, and because the client application itself does not have claims to those itself, the token should go directly to the client application without a server side intermediary.

Here again we can look at the example of a library. It issues a library card which then provides access to all the books in the library.

When should I use an implicit flow vs an public auth code flow?

The question comes down to what are you planning to do with the access token?

If the purpose of the access token does not need its own set of scopes against the resource server but is only used to establish identity (and the loss of confidentiality is a low risk — like a user’s playlist on SoundCloud for example), you can use a public client with an auth code flow.

However, if resources belong to the same entity as the authorization server, like accessing your Facebook data, then an Implicit Token, scoped to the specific access the client has permission for, should be used. In this case the possibility of a server side component accumulating Access Tokens, via auth code flow, which can be used in the user’s absence should be prevented.

Using the above example for Auth Code Grant and the PhD admission — a public client would imply the professor provides the references directly to me, and I had it over to the admission’s committee. It would still be possible to maintain integrity and confidentiality (i.e. a sealed letter), but it is significantly easier to manipulate (i.e I could re-seal the letter after modifying it). On the other hand, an Implicit Grant, is more like an acceptance letter directly in response to my application.

Conclusion

These are not exhaustive arguments but I hope can help you orient yourself as to what grant type you should pursue. The use of Client Credentials flow is quite obvious, but deciding between Implicit, Password, and Auth Code on public clients can be quite hairy.

The question always comes down to the relationship between Client, the Resource Server, and the Authorization Server. Sometimes, the same organization can have all 3 but you still need an Auth Code flow — the user may belong to “Digital Banking Company” but the Investment, Commercial, and Retail banking arms may have published their own apps (clients). In that case, although it is the same organization, an Auth Code flow might be preferable, so that passwords don’t proliferate, and a weakness in one app is not used to exploit another. Generally, speaking you want to follow the principle of least access as you apply these general ideas to your particular use case.

--

--