Using Claims in APIs

Using Claims in APIs

develop

Using Claims in the API

Overview

Even though the Client is the one requesting scopes and claims, the API is one of the primary recipients of the claims. Very often the OAuth server and the API belong to the same organization, but the client does not. Therefore it's common that the access token contains more claims that are internal to the organization while the ID Token does not. The Client part of the claims infrastructure is discussed in Client and Claims article, which is a good starting point.

This article highlights what can be done to create a claims based architecture for the APIs and Microservices.

If you haven't read the Claims Explained article it's a good starting point before diving into this section.


Designing APIs for Claims or Claims for APIs

In a RESTful microservice architecture each API is independent and each request should contain all data needed to perform the request. Ideally the API rarely should have to contact other services to retrieve the information it needs to authorize the request.

By carefully designing the Access Token it's possible to achieve a high level of containment for the services.

Authorization

Much of what the API will need to figure out is: Is the Client and the User allowed to perform this request.

Broadly speaking this involves figuring out the following:

  • Is the client authorized to call the API at all
  • Is the user authenticated
  • Does the user have enough permissions
  • Does the data the request operates on belong to the user
  • If not, is the user allowed anyway

Many times system designers wants a few levels of access. User access, Admin Access and possible Customer Support access. With a claims based architecture using OAuth it's possible to achieve these levels system wide without making custom solutions in each API.

Authorizing the Client

As discussed in the Scope article, the Scope can be used for coarse grained access control. From the APIs perspective the API should validate that the Access Token contains the desired scopes. The OAuth server will not issue scopes to a client that is not entitled to get them. So the API can simply rely on that fact.

Microservice Example with Scopes

Consider the following service that allows a client to send SMSs. It consists of three APIs. An invoice API where internal clients can create invoices, and external clients can read them, an SMS API where the external Clients can send SMSs and a Status API where it's possible to see the system status for the service.

API Scope Example

Lets assume we create the scopes: invoice-read, invoice-write, sms and status. A client needs to be authorized with these scopes to be able to contact the API. So it's easy for the API to determine if it should let the request through the door.

However to actually perform anything it needs to know more. What account-nbr does the user have, where the billing should occur. When sending SMS it needs to know what account-type is it: premium or standard, to know what rate limits apply, and also the account-nbr to know where to increase the bill.

This creates the following scope to claims mapping

Claims Example

As you can see, that status API is agnostic to the user, it is open to all requests that have the status scope. It doesn't involve user specific operations.

The invoice-read and the sms scope have overlapping claims, since both need the account-nbr. This is ok and preferable since it reduces the number of scopes the client needs. If all it wants to do is send SMS, it doesn't need the invoice scope.

The Contract

The contents of the access token becomes a contract between the OAuth server and the API. If the sms scope is present, the API can rely on that the account-nbr and account-type claims will be present with values in the token data.

{
  "sub" : "johndoe",
  "scope" : "sms",
  "account-nbr": "XYZ-123",
  "account-type": "premium",
  ...
}

Conclusion

The claims and scopes form the contract with the API. The OAuth server can issue claims it knows a certain API needs based on the Scope of access. This simplifies management and foremost makes the basis for Authorization decisions in the API easy. Using something like Attribute Based Access Control (ABAC) follows naturally since the token contains the context needed.

Was this page helpful?