OAuth2
A guide on how to implement an OAuth2 flow for authenticating our REST API.
Overview
This guide aims to provide the basic understanding and ability to authenticate a Service Account for REST API integrations. Core concepts about the OAuth2 authentication flow are briefly explained, and an example implementation is provided. The implementation is tested using the returned access token to send a request to the REST API to list all available projects.
Prerequisites
Service Account Credentials A Service Account must be created with a membership in the target project. Any role will suffice.
Example Code
The provided example code can be summarized by the following points.
A JSON Web Token (JWT) is constructed and signed with a secret.
The JWT is exchanged for an access token.
The Access token is used to authenticate the REST API.
The implemented OAuth2 authentication flow is based on the RFC7523 specification.
Environment Setup
If you wish to run the code locally, make sure you have a working runtime environment.
The following packages are required by the example code and must be installed.
pyjwt==2.7.0
requests==2.31.0The Disruptive Technologies Python API can be installed through pip.
pip install --upgrade disruptiveThe following modules are required by the example code and must be installed.
npm install [email protected]
npm install [email protected]The following packages are required by the example code and must be installed.
go get -u github.com/golang-jwt/jwt/[email protected]Add the following environment variables as they will be used in the authentication flow.
Source
Our Python API implements the OAuth2 flow for you, requiring no further action.
Authentication Flow
Authenticating a client is a 3 step process, as illustrated below. Using both the figure and example code, the following sections will explain in more detail what each step entails.
Create the JWT
A JSON Web Token (JWT) contains three fields:
Header: Token type and signature algorithm.
Payload: Claims and additional data.
Signature: A signature calculated of the entire JWT + a private secret.
Before being sent, these fields are each Base64Url encoded. They are combined in a compact dot format in the form Base64Url(header).Base64Url(payload).Base64Url(signature), which is what we will refer to as the encoded JWT.
Using your Service Account credentials, construct the JWT headers and payload. Here, iat is the issuing time, and exp the expiration time of a maximum 1 hour after iat.
The simplest way of Base64-encoding and signing our JWT is to use some language-specific library. This is available in most languages but can be done manually if desired.
Exchange for Access Token
The encoded JWT is exchanged for an Access Token by sending a POST request to the same endpoint used to construct the JWT, namely https://identity.disruptive-technologies.com/oauth2/token.
The POST request header should include a Content-Type field indicating the format of the body. Additionally, the POST request body is Form URL-Encoded and contains the following fields:
"assertion" - Contains the encoded JWT string.
"grant_type" - Contains the string
"urn:ietf:params:oauth:grant-type:jwt-bearer". This specifies that you want to exchange a JWT for an Access Token.
It is important to note that the data has to be Form URL-Encoded. Like Python's requests, some libraries do this by default and require no further input by the user. This is, however, not the norm and likely requires an additional step before sending the request. The URL Form Encoded data should have the following format.
The header, payload, and signature are found in the previous step.
The access token response can be expected to have the following format. It will be valid for 1 hour only. To get a new token, perform the previous steps again.
Check the Common Errors section at the bottom to troubleshoot errors.
Access the REST API
Once you have the Access Token, you need to include this with every call to the API. This can be achieved by including the Authorization header in the form shown in the snippet below.
Common Errors
This section covers the most commonly encountered errors while setting up Service Account authentication using OAuth2.
Note that all errors returned from the oauth2/token with an HTTP status code of 400 indicates that there is something incorrect in your implementation. The specific errors returned from this endpoint might change in the future, so you should avoid writing logic to try to figure out which type of error you got. Instead, you should log out the response body you got back to see what's wrong and update your implementation accordingly.
For an overview of all REST API errors, see the Error Codes reference page.
Timing Error
There is something incorrect with either the issue time (iat) or the expiration time (exp) claims in your JWT. Make sure that both claims are set, and have the correct values according to the documentation above.
Here are some typical reasons why you might receive this error:
Either the
iatorexpclaims (or both) are missing in the JWT.The
iatclaim is too far in the past or future compared to "now".The
expclaim is more than 3600 seconds pastiator beforeiat.
Untrusted Entity Error
This might be caused by one of the following reasons:
Either the audience (
aud) claim or issuer (iss) claim are missing.The
audclaim is not set tohttps://identity.disruptive-technologies.com/oauth2/token.The
issclaim is not set to the email of the Service Account.
Signature Error
The JWT has not been signed correctly. Make sure you have used the correct secret to sign the JWT. It should be the secret of the Service Account Key that corresponds to the key id used in the kid field of the JWT header.
It's recommended to use a library to do the heavy lifting of signing the JWT for you. Check out jwt.io for a selection of recommended libraries in many different languages. If you're writing the JWT signature implementation yourself, check out this guide for more information on how to do this.
Unsupported Grant Type
This might be caused by one of the following reasons:
The
Content-TypeHTTP header is not set toapplication/x-www-form-urlencoded.The
grant_typefield is missing from the POST request body.The body of the POST request is not Form URL-encoded.
Other
This might be caused by one of the following reasons:
The Service Account doesn't exist.
The Service Account key doesn't exist.
The
assertionfield of the request (the encoded JWT) is missing or malformed. Make sure that the JWT is formatted correctly, and that the entire request body is Form URL-encoded as described in the documentation above.
403 Errors From REST API
If you get a 403 HTTP status code from the REST API when using the access token you just generated, it's likely not an issue with the authentication. The most common reason for this is that the Service Account you are authenticating as does not yet have access to the resource you're trying to access. Before a Service Account can use the API it needs to be a member of either a project or an organization. See the Managing Access Rights page for more information about how to add a Service Account as a member. The Organizational Structures page gives some guidance for when to add Service Accounts as members on a project vs. on an organization.
Next Steps
You are now familiar with the OAuth2 authentication routine, but it must still be refreshed every hour for integrations that run continuously. For this, see our example on Refreshing Access Token.
Last updated
Was this helpful?