Authorization Code Flow

In the Authorization Code Flow, a Remote Company Admin (resource owner) authorizes an API Partner to manage its resources through the API. All operations performed by the API Partner are on behalf of the Company Admin who authorized the integration. Therefore the access_token obtained through this flow only allows managing the company itself.

The flow is extensive but enables Remote and the API Partner to exchange tokens securely. At the end of the process, the API Partner can fetch a valid Access Token on behalf of an existing Remote Company without exposing the tokens to the external world.

Flow overview

The flow described below enables an existing Remote Company to grant permissions for an API Partner (through the partner's Client Application) to manage its resources. This sequence diagram shows a visual of the flow described below.

!https://cdn.api-assets.remote.com/api-docs/authorization_code_flow.png

💡 Passing the `access_token` in the Authorization header is the only way to act on behalf of a Company Admin via the Remote API.

Initiating the flow - Steps 1 and 2 in the diagram above

The first step is to redirect the user to the authorization page. This page is in the Authorization Server. Usually, it is done when the user clicks a button or a link. The link should be built like this:

https://gateway.remote-sandbox.com/auth/oauth2/authorize?<configuration query strings>
💡 When you’re ready to release your integration, replace the domain with `https://gateway.remote.com`

Here are the allowed configuration query strings:

  • client_id: It's a required param. API Partners should provide their CLIENT_ID in plain text. This is the same client ID used in the Client Credentials Flow. Please, notice that the CLIENT_SECRET should never be exposed externally. The CLIENT_ID is the sole piece of information that must be used in this case.
  • redirect_uri: It's a required param. In the process of registering the API Credentials, API Partners are asked about the redirect URIs. For security reasons, we only allow URIs that exactly match one of the provided during Client Registration.
  • state: It's a required param. This param is crucial for security. The API Partner must generate a random string and pass it on the state param. When the Remote API redirects the user to the provided redirect_uri, it will include the untouched state value so that the API Partner can ensure the request's origin is trustful.
  • scope: It's an optional param. The scope tweak which permissions are being granted with the authorization. For now, the only valid value is https://gateway.remote.com/company.manage which grants permissions for managing the company data and its employments. The value doesn't change if you are using the sandbox domain.

Example of how to build a valid authorization URL

$ echo $CLIENT_ID
9c62f10ef475f55c982328eaa8f64fa8

# Using openssl to generate a random string with 16 bytes.
$ openssl rand -hex 16
c97b8fa15f7f8ba064b338779b8eecab

https://gateway.remote-sandbox.com/auth/oauth2/authorize?client_id=9c62f10ef475f55c982328eaa8f64fa8&redirect_uri=https://example.com/callback&state=c97b8fa15f7f8ba064b338779b8eecab
💡 When you’re ready to release your integration, replace the domain with `https://gateway.remote.com`

Company Admin is presented with the authorization page - Steps 3-8 in the diagram above

Sign-in is required

If the Company Admin user is not signed in, the Authorization Server redirects the browser session to the sign-in page in Remote UI. After signing in, the session is redirected back to the authorization page.

!https://cdn.api-assets.remote.com/api-docs/remote_login_page.png

Signed-in user is not a Company Admin

If the signed-in user has a role other than Admin, a page with a 403 status (Forbidden) is displayed for the user. In order to prevent this error, Client Applications can instruct their users to ask for authorized personnel to perform it.

Signed-in user is a Company Admin

If all the params provided in the authorization URL are correct, the Company Admin is presented with the following page:

!https://cdn.api-assets.remote.com/api-docs/authorization_page.png

The Company Admin is able to perform one of two actions: approve or deny the authorization.

The Company Admin approves the integration - Steps 9 and 10 in the diagram above

After clicking Approve, the Authorization Server redirects the Company Admin to the URL provided in the redirect_uri param. It will, however, add additional query parameters to indicate that the request was successful. They are:

  • state: it contains the same value passed for the authorization endpoint described in section 1.
  • code: this is a token that must be exchanged for the authorization's refresh_token. This token doesn't need to be stored as it is for one-time use and expires within 5 minutes.

The redirect URL would look like this:

https://example.com/callback?state=c97b8fa15f7f8ba064b338779b8eecab&code=dc518e245b9157d6e658a45d7b3c1188e67bc37c...

Although it looks like this is the end of the process, it is not. The code parameter needs to be exchanged for a refresh_token. Learn how to perform it in the following section.

Client Application exchanges the authorization code - Steps 11-13 in the diagram above

After receiving a successful callback, the Client Application needs to exchange the authorization code for a refresh token. A refresh token, as the name says, is able to retrieve a valid access token after it expired.

The exchange happens in a POST request to the Authorization Server as follows:

  • Send a POST request to https://gateway.remote-sandbox.com/auth/oauth2/token
  • Include the authorization header with basic authentication encoded with Base64:
    • Generate the Base64 with both credentials separated by a colon (:) as shown here — <client_id>:<client_secret>
    • Use the header Authorization: Basic <client_id_and_client_secret_encoded_in_base64>
  • Include the Content-Type: application/x-www-form-urlencoded header in the request
  • In the payload, you need to tell the grant type and the code:
    • grant_type filled with authorization_code — it's a constant value
    • code filled with the value in the callback's query string (in the 2a step)

Assuming your CLIENT_ID=your_client_id and CLIENT_SECRET=your_client_secret, an example of what your request should look like is shown below.

$ echo -n "your_client_id:your_client_secret" | base64
eW91cl9jbGllbnRfaWQ6eW91cl9jbGllbnRfc2VjcmV0

$ curl --location \
       --request POST 'https://gateway.remote-sandbox.com/auth/oauth2/token' \
       --header 'Authorization: Basic eW91cl9jbGllbnRfaWQ6eW91cl9jbGllbnRfc2VjcmV0' \
       --header 'Content-Type: application/x-www-form-urlencoded' \
       --data-urlencode 'grant_type=authorization_code' \
       --data-urlencode 'code=dc518e245b9157d6e658a45d7b3c1188e67bc37c...'
💡 When you’re ready to release your integration, replace the domain with `https://gateway.remote.com`

The response to this request should look like the following JSON:

{
  "access_token": "eyJraWQiOiIrRHF3Y1A4TU80bEMrN1NxSVQxSVcHHL6LLZH0o_xWvoUG...",
  "company_id": "3718b8ba-55d3-4fa6-ae45-91cd43b67997",
  "refresh_token": "84224550-dc8f-4153-a7cd-4f38c7ef90da",
  "expires_in": 3600,
  "token_type": "Bearer",
  "user_id": "e25c2e12-be43-4964-ac00-40ddfbd896c4"
}

The response payload returns a valid access_token of the type Bearer. It also includes the refresh_token. This information must be stored securely by the Client Application and used to fetch access tokens as described in the next section. The response payload also includes the user_id and company_id which won’t change so the client application can also store this for future reference.

💡 The access token will be valid for 3600 seconds (one hour), so we recommend that the caller fetch a new access token before the current one expires (e.g. every 55 minutes). Please note that there is no limit to the number of access tokens that can be used at the same time. Please refer to the [Refresh Token Flow](https://www.notion.so/Refresh-Token-Flow-7ce74a665fcd4106b8943a0e1d6fd6cf?pvs=21) article for instructions on issuing a valid access token.

Client Application fetches a valid Access Token - Steps 14 and 15 in the diagram above

When the access_token expires, the Client Application needs to request a new one. Follow the Refresh Token Flow instructions in order to obtain it.

If the Company Admin denies the integration, an alternative flow is used.

This sequence diagram shows a visual of the alternative flow described below.

!https://cdn.api-assets.remote.com/api-docs/authorization_code_alternative_flow.png

During steps 8 and 9, the Company Admin can either approve or deny the integration. If the Company Admin clicks "Deny", the Authorization Server redirects the session to the provided redirect_uri with three query strings. They are:

  • error: the value is always “denied.”
  • error_message: the value is "The authorization was denied."
  • state: it contains the same value passed for the authorization endpoint described in section 1.

The redirect URL would look like this:

https://example.com/callback?state=c97b8fa15f7f8ba064b338779b8eecab&error=denied&error_message=*The%20authorization%20was%20denied*

At this point, the Client Application can display an error telling the User that the integration was denied.

Notice that the code parameter is not added to the redirect URL, which means the Client Application won't be able to exchange it for a refresh token. The flow ends after it but the User may restart the process at any point. However, a new state must be provided when sending the user to the authorization page.

Frequently Asked Questions

The authorization code expired before I could exchange it for a refresh_token. What should I do?

The authorization code expires in 5 minutes. If for some reason the Client Application takes more than that to exchange for a refresh token, the whole flow needs to be restarted.

How should I fill the state query parameter?

The state query parameter must be a random and unique string. It doesn't have any length specifications. We recommend it to have at least 8 characters. You can use MD5, SHA1, UUID, or another algorithm to generate those random strings.

I got the authentication code. What should I do?

With the authentication code in hand, you need to exchange it for a refresh_token. The authentication code is valid for five minutes. After the expiration, you need to restart the flow.

Refresh tokens must be stored by the Client Application securely and used to issue new access tokens.

If you don't exchange your authentication code for a refresh token, the process is not complete. It means the Client Application won't be able to manage the company and employment resources of the user.