V3 API Application Authorization (with PKCE)

Applications that want to query the Bluescape API must be authorized to do so by an active Bluescape user. Applications obtain this authorization using OAuth2, which enables users to share access to their account without divulging their password.

Once authorized, applications receive access tokens from Bluescape, which enables them to access Bluescape resources on behalf of the authorizing user. Changes made in Bluescape using these access tokens appear in the system as if made by the users themselves. Access tokens inherit the access rights of the user that authorized them, and thus, access tokens only enable applications to access and modify those resources in Bluescape that the user already has access to.

OAuth2

OAuth 2.0 is the standard for securing API access in the modern web. It offers a flexible framework for authentication and authorization, allowing users to grant limited access to their resources to third-party applications.

The primary v3 Bluescape OAuth2 flow is the Access Code Flow. Bluescape also supports Proof Key for Code Exchange (PKCE) to improve security.

Bluescape currently supports the following OAuth2 methods:

OAuth and API URLs

Each Bluescape instance has a standardized set of URLs for OAuth and the API itself. For commercial Bluescape, the base application URL is https://client.apps.us.bluescape.com/ and the v3 API URL is https://api.apps.us.bluescape.com/v3/. For other instances, replace apps.us.bluescape.com with your base URL. (e.g. https://api.bluescape.customer.com/v3/oauth2/token).
See the following Table for more details:

Use Case URL
Base Application https://client.apps.us.bluescape.com/my
CLI Interface https://client.apps.us.bluescape.com/cli
OAuth Code URL (Authorize App) https://api.apps.us.bluescape.com/v3/oauth2/authorize
OAuth Token URL (Retrieve Token) https://api.apps.us.bluescape.com/v3/oauth2/token
GraphQL Playground https://api.apps.us.bluescape.com/v3/graphql/
REST API Swagger Docs https://api.apps.us.bluescape.com/v3/

Authorization Code Flow

This method requires you to obtain an Access Code that is used along with other Application credentials in order to automatically generate an Access Token and Refresh Token.

To successfully obtain an access token and refresh token, use the following steps:

  1. Initiate the authentication process by accessing the client application.
  2. The client application redirects you to the authorization server’s authentication endpoint.
  3. Enters your credentials and grant permission to the client application.
  4. Upon successful authentication and authorization, the authorization server issues an authorization code to the client application.
  5. The client application exchanges the authorization code for an access token by making a request to the authorization server’s token endpoint.
  6. The authorization server verifies the authorization code and, if valid, issues an access token and refresh token to the client application.
  7. The client application can now use the access token to access protected resources on the resource server.

IMPORTANT

In the interest of everyone, developers must treat access tokens with care. Remember that this token allows you to access all the workspaces your user has access to, and to add, modify, and delete elements from those workspaces.

Step 1: Create a Bluescape Application

In order to generate an access token to use Bluescape APIs, you must first create an application to get your clientId, clientSecret, and enter the redirect URI that receives the access token.

Create a new Application

  1. Sign in to your Bluescape account.

  2. Go to your user profile locate your application list.

  3. Click New Application, and enter a name, description, and the OAuth redirect URI.

    This URL redirects the workflow to deliver the access Code, Access Token, and Refresh Token.

  4. Click Save to create the new application

  5. To view the Application settings, click the settings icon image from the application list.

  6. The important data points from this page are the Client ID and Client Secret.

  7. To view the Client Secret, click the eye icon eye.

    Note: It is critical that you keep the Client Secret secure. You can generate a new Client Secret by clicking Renew Secret on the Edit Application page. This operation voids the previous Client Secret. If you renew the secret, you must update the Client Secret in any place where it is being used.

Step 2: Direct the User to Bluescape for Authorization

Once you have created a Bluescape application and have your application credentials, the application requesting an access token should direct users to the authorization page at: https://api.apps.us.bluescape.com/v3/oauth2/authorize

The following parameters should be URL-encoded and passed in the query string:

Name Required? Description
client_id Required Use the Client ID assigned to the application.
redirect_uri Required Use the Redirect URI provided in the application’s settings.
response_type Required Use response_type=code to get the access code.
scope Required This must be scope=v2legacy%20offline_access
state Optional Used to maintain state between the request and callback
code_challenge Optional Used for PKCE authorization
code_challenge_method Optional Hash method, ie: “S256”

The client application must include these parameters in the user authorization redirect:

https://api.apps.us.bluescape.com/v3/oauth2/authorize?response_type=code&client_id=<client_id>&redirect_uri=<redirect_url>&scope=v2legacy%20offline_access

You can also add an optional state parameter which can be a json object, i.e.:
const state = JSON.stringify({"myApplicationState":"init"});

For example (these are just illustration values):

https://api.apps.us.bluescape.com/v3/oauth2/authorize?response_type=code&client_id=70304a04-d522-45fe-8f8e-cba38845a9af&redirect_uri=http://localhost:3001/auth/callback&scope=v2legacy%20offline_access&state={"myApplicationState":"init"}

You can paste this URL into a web browser to verify the settings, but this would normally be called by the client application.

If the query parameters match the Bluescape application credentials, an authenticated Bluescape user is presented with the authorization dialog in their web browser:

When you arrive at the authorization page, if you aren’t already logged in to your Bluescape account, you are asked to log in. By clicking Allow, you are authorizing the application to receive an access code connected to your account. The client application then exchanges the authorization code for an access token for the application. The access token grants access to anyone who holds it to make calls on your behalf (as the user that granted authorization).

After the login and authorization of the application, the authorization code or error is returned to the application’s redirect_uri.

A sample response to redirect_uri (when passing state in initial request):

{
  code: 'o01ed6qdO0p8BZgUXN_HdrrFGlikBQeL6uo7CrZ-d5L',
  state: '{"myApplicationState":"init"}',
  iss: 'https://isam.apps.us.bluescape.com'
}

Step 3: Generate Access Token and first Refresh Token using Access Code

The next step involves using the Access Code and other Application credentials to generate the first Refresh Token to allow for the process of generating new Access Tokens using Refresh Tokens.

The following parameters are required:

Name Required? Description
authorization-token-endpoint Required For this example, use: https://api.apps.us.bluescape.com/v3/oauth2/token. For Private Instances, check your Developer Portal Website > Reference > URLs for the OAuth Authorization URL.
access_code Required Use the Access Code generated in the previous step (Step 2.2.1).
client_id Required Use the Client ID assigned to the application.
client_secret Required Use the Client Secret from your Application (see details in Appendices).
redirect_uri Required Use the Redirect URI provided in the application’s settings.

The client request for Access Token and Refresh Token is as follows:

curl --location <authorization-token-endpoint> \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=authorization_code' \
    --data-urlencode 'code=<access_code>' \
    --data-urlencode 'client_id=<client_id>' \
    --data-urlencode 'client_secret=<client_secret>' \
    --data-urlencode 'redirect_uri=<redirect_url>'

Example Request:

curl --location 'https://api.apps.us.bluescape.com/v3/oauth2/token' \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=authorization_code' \
    --data-urlencode 'code=o01ed6qdO0p8BZgUXN_HdrrFGlikBQeL6uo7CrZ-d5L' \
    --data-urlencode 'client_id=70304a04-d522-45fe-8f8e-cb238845a9af' \
    --data-urlencode 'client_secret=50bccef3a05f5433624ge8eb47a01c5d' \
    --data-urlencode 'redirect_uri=http://localhost:3001/auth/callback'

Example Response:

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6ImF0K2p3dCIsImtpZCI6ImswIn0.eyJ2ZXIiOiIzIiwiYm90X3VzZXJfaWQiOm51bGwsImp0aSI6InViVjFwVmhRNFBmTmRwYU05MnpvbSIsInN1YiI6Ilp1THdWd3R2NTlURjdSc3VwNnVWIiwiaWF0IjoxNjg1NzUwMzI2LCJleHAiOjE2ODU3NTM5MjYsInNjb3BlIjoidjJsZWdhY3kiLCJjbGllbnRfaWQiOiIzMDBhZmVhMS0wYzI2LTQzYjUtYWYyYS1mMWQzZGNkNTJmZmYiLCJpc3MiOiJodHRwczovL2lzYW0uc3RnMS5ibHVlc2NhcGUuY29tIiwiYXVkIjoiaHR0cHM6Ly9zdGcxLmJsdWVzY2FwZS5jb20ifQ.XlWwYS-trReNfHRNaAIjuqOmZJBGhj2ZOUNcOZ7nf9k",
    "expires_in": 3600,
    "refresh_token": "yBPJmJRkVB93ZmyZN1SeJlht1hiNtt6_i7iHp9a81eF",
    "scope": "v2legacy",
    "token_type": "Bearer"
}

You should now have the following items:

  1. access_token: this is the Access Token used as the authentication to run your APIs; it uses JWT format.
  2. expires_in: the token expiration time in seconds.
  3. refresh_token: the refresh token used to get a new access token.
  4. scope: the level of access, i.e.: v2legacy, which mirrors the access to the user that granted authorization.
  5. token_type: Indicates this is the bearer token.

Important points:

  • You can use this Access Token right away with your API scripts.
  • Refresh Tokens do not expire. This means you can generate your new Access Tokens using the Refresh Tokens at any moment, before or after the current Access Token expires.
  • If an Access Token is used after it has expired, you receive a 401 Unauthorized error code. In this case, you must trigger the process to generate a new Access Token using the Refresh Token (as explained in the next section).

Step 4: Generate Access Token using Refresh Token

This step involves using the Refresh Token along with other Application credentials to automatically generate new Access Tokens.

  1. To see if your Access token is still valid, you can either check its expiration time or simply try using it in any valid Bluescape API call.
  2. If you get a 401 Unauthorized error code, then you can trigger an automated process to use the Refresh Tokens to issue a new Access Token. The Refresh Tokens do not have an expiration date.

The following parameters are required to automatically generate the Access Token using Refresh Tokens :

Name Required? Description
authorization-token-endpoint Required For this example, use: https://api.apps.us.bluescape.com/v3/oauth2/token For Private Instances, check your Developer Portal Website > Reference> URLs for the OAuth Authorization URL.
refresh_token Required Use the newest available Refresh Token.
client_id Required Use the Client ID assigned to the application.
client_secret Required Use the Client Secret from your Application.
redirect_uri Required Use the Redirect URI provided in the application’s settings.

The client request for Access Token and Refresh Token is:

curl --location '<authorization-token-endpoint>' \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=refresh_token' \
    --data-urlencode 'refresh_token=<refresh_token>' \
    --data-urlencode 'client_id=<client_id>' \
    --data-urlencode 'client_secret=<client_secret>' \
    --data-urlencode 'redirect_uri=<redirect_url>'
}'

Note: The use of "grant_type":"refresh_token" to indicate this request is to issue a new Access Token and a new Refresh Token.

Example of request to get Access Token using Refresh Tokens:

    curl --location 'https://api.apps.us.bluescape.com/v3/oauth2/token' \
        -H 'Content-Type: application/x-www-form-urlencoded' \
        --data-urlencode 'grant_type":"refresh_token' \
        --data-urlencode 'refresh_token":"yBPJmJRkVB93ZmyZN1SeJlht1hiNtt6_i7iHp9a81eF' \
        --data-urlencode 'client_id":"70304a04-d522-45fe-8f8e-cb238845a9af' \
        --data-urlencode 'client_secret":"50bccef3a05f5433624ge8eb47a01c5d' \
        --data-urlencode 'redirect_uri":"http://localhost:3001/auth/callback'
    }'

The answer to this client request is:

{
    "access_token":"<access-token>",
    "refresh_token":"<refresh-token>",
    "expires_at":<expire-timestamp>,
    "token_type":"Bearer"
}

Step 5: Using the Access Token

At this point, you have your Access Token and are ready to start using it. Access Tokens enable applications to make requests of the Bluescape API. They are intended to be used as Bearer tokens and should be provided in the Authorization header of HTTP requests to the Bluescape API.

Example HTTP request to get session user workspaces:

curl --location --request GET 'https://api.apps.us.bluescape.com/v3/users/me/workspaces' \
--header 'Authorization: Bearer <yourBearerToken>'

Remember that Access Tokens expire 60 minutes after they are issued. Requests made with expired access tokens will receive a 401 Unauthorized response from the Bluescape API. As noted above, if the token is no longer valid, you can use your stored refresh token to get a new Bearer Token and make the API call again.

Access Token PKCE extension

PKCE (pronounced “pixy”) is used for client applications and is designed to prevent an attack where an interceptor might grab the authorization code returned after user authorization, and use it to obtain an access token.

PKCE replaces the OAuth implicit method and has become a best-practice recommendation for all OAuth 2.0 implementations, not just public clients, due to its enhanced security features.

The PKCE method follows the same flow as the code flow, except it uses additional code_challenge and code_challenge_method parameters.

PKCE Code Challenge and Code Verifier

The code_challenge is a URL-safe string created by encoding the output of a cryptographic hash function applied to a randomly generated code_verifier. The purpose of the code_challenge (and its associated code_verifier) is to ensure that the client that requests an authorization code is the same client that exchanges the code for an access token, preventing code interception attacks.

Steps involved:

  1. Generating the code_verifier: Generating a cryptographically random string, which is the code_verifier.
  2. Generating the code_challenge: Derive the code_challenge from the code_verifier:
  • Using the “plain” method: The code_challenge is just the code_verifier. This method is less secure than the following one and is not recommended unless the client cannot perform the hashing.
  • Using the “S256” method (recommended): The client creates a SHA-256 hash of the code_verifier and then encodes the hash in URL-safe base64 format to produce the code_challenge.
  1. Authorization Request: When you redirect users to the authorization server’s authorization endpoint, it includes the code_challenge and code_challenge_method which specifies which method (“plain” or “S256”) was used. The server retains the code_challenge to later verify the client.
  • Example Authorization call with code_challenge and code_challenge_method :

    https://api.apps.us.bluescape.com/v3/oauth2/authorize?response_type=code&client_id=<client_id>&redirect_uri=<redirect_url>&code_challenge=NvwafG6CXdJBF6tF-yh5KGRotC_TxlZGoRsWAw-_hBc&code_challenge_method=S256`

  1. Exchanging the Authorization Code: After obtaining the authorization code, you request an access token from the token endpoint and send along the original code_verifier.
  • Example PKCE Request:
   curl --location 'https://api.apps.us.bluescape.com/v3/oauth2/token' \
   -H 'Content-Type: application/x-www-form-urlencoded' \
       --data-urlencode 'grant_type=authorization_code' \
       --data-urlencode 'code=<userAuthorizationCode>' \
       --data-urlencode 'client_id=<appClient_id>' \
       --data-urlencode 'client_secret=<appClient_secret>' \
       --data-urlencode 'redirect_uri=<AppRedirect_uri>' \
       --data-urlencode 'code_verifier=<clientGeneratedCodeVerifier>'
  1. Verification by the Authorization Server: The server does one of the following, depending on the method specified in the initial request:
  • For “plain”: Compares the received code_verifier with the previously received code_challenge.
  • For “S256”: Hashes the received code_verifier, encodes it in URL-safe base64, and compares this value with the previously received code_challenge.

If the values match, the server issues an access token to the client.

Example NodeJS code to create codeVerifier and S256 codeChallenge

const crypto = require("crypto");
const base64url = require("base64url");
const secureRandomString = require('secure-random-string');

secureRandomString({ alphanumeric: true, length: 64}, function(err, codeVerifier) {

  if (process.env.CODE_VERIFIER) {
    console.log(`Use CODE_VERIFIER: ${process.env.CODE_VERIFIER}`);
    codeVerifier = process.env.CODE_VERIFIER;
  }

  console.log(`codeVerifier=${codeVerifier}`);

  const base64Digest = crypto
  .createHash("sha256")
  .update(codeVerifier)
  .digest("base64");

  console.log(`base64Digest=${base64Digest}`);

  const codeChallenge = base64url.fromBase64(base64Digest);


  console.log(`codeChallenge=${codeChallenge}`);

});

Troubleshooting

If you get an error message when trying to authenticate and authorize, or when trying to generate your Tokens, review the error messages and error codes in the table below.

Error message Description and action to take
“Oops, something went wrong” If you see this message in the step to authenticate and authorize in order to generate an Access Token or an Access Code, verify that the Redirect URL you set in your Application is the same one you are using as the redirect_uri parameter in the URL you are using to generate the Access Token or Access Code.

For example, let’s consider this Application:

For the image above, the correct value for redirect_uri is http://localhost:3001/auth/callback, and the full URL to trigger the Access Token generation would be:

https://api.apps.us.bluescape.com/v3/oauth2/authorize?response_type=code&client_id=d=316ad317-940d-4a91-a558-951a475317f8&redirect_uri=http://localhost:3001/auth/callback&scope=v2legacy%20offline_access

Error message Description and action to take
401 Unauthorized If, for any reason, the Access Token is not refreshed before its expiration date, you will get a 401 Unauthorized response from the Bluescape API.
If you are using the Access Code with Refresh Tokens approach, you will need to trigger a process to use the Refresh Token to generate a new Access Token and a new Refresh Token.
405 Not Allowed If you have not Allowed the application, you will get an error message 405 Not Allowed.

Where to Next?

Not what you were looking for? Reply below or Search the community and discover more Bluescape.