Authentication and Authorization


Introduction to Kloudless OAuth 2.0 

Kloudless uses OAuth 2.0 to authenticate users, and provides your application with an access token to use to perform API requests to that user’s account.

In addition, your application’s confidential API Key can be used to access data for any account connected to your application.

Existing developers using older authentication mechanisms should migrate to OAuth 2.0 as outlined in the migration notes towards the end of this page. Support for older authentication mechanisms was removed on August 31, 2017.


Custom OAuth credentials 

By default, users are authenticated with a set of OAuth keys for the appropriate cloud service owned by Kloudless. This means that they will see that ‘Kloudless Platform’ is requesting access to their account on Dropbox, Box, etc.

It is recommended to configure your own OAuth keys for the cloud services you’d like to support. You can configure this on the developer portal’s Custom OAuth Keys page.


Authorizing API requests 

Prior to detailing how to authenticate users, we will demonstrate how to authorize API requests once user accounts have been connected.

A developer can use an Authorization header to authorize requests for the Kloudless API. Kloudless offers two options for an Authorization header: Bearer for OAuth tokens, or APIKey for application-wide access.

OAuth 2.0 Bearer Token Authorization

Each account connected has an associated Bearer token obtained via the OAuth flow. The token can be used for both client-side as well as server-side requests.

Use a Bearer token in the Authorization header of an HTTP request as shown below:

Authorization: Bearer {token: string}

Here is how you can make a request using cURL:

curl -L -H 'Authorization: Bearer [TOKEN]' https://api.kloudless.com/v0/[RESOURCE]

You can also authenticate requests to multiple accounts by comma-separating the necessary tokens. For example:

curl -L -H 'Authorization: Bearer token_123,token_456,token_789' \
    https://api.kloudless.com/v0/accounts/123,456,789/links

API Key Authorization

Bearer tokens are strongly recommended to use to authorize API requests. However, an API Key is also available.

The API key is automatically generated when a developer creates an application. The API key allows a developer to make requests on behalf of all connected accounts. Therefore, the API key should be kept secret at all times and only used for server-side requests. The API Key can be found on the App Details page.

Only use API Keys with verified accounts. After an account is connected, transfer its ID and Bearer token to the server-side, where an API request should be performed to verify that the user did connect that account. Once verified, the data can be stored, and the API Key can also be safely used to perform requests to that account.

Similar to the Bearer Tokens, use an API Key as shown below:

Authorization: APIKey {api_key: string}

Here is how you can make a request using cURL:

curl -L -H 'Authorization: APIKey [KEY]' https://api.kloudless.com/v0/[RESOURCE]

Here are some example requests:

curl -L -H 'Authorization: APIKey XxijaFsSvrgHa8mDvhQ6DF' \
    https://api.kloudless.com/v0/accounts?active=True

curl -L -H 'Authorization: APIKey XxijaFsSvrgHa8mDvhQ6DF' \
    https://api.kloudless.com/v0/accounts/1/files/fL3Rlc3QucG5n?overwrite=False

curl -L -H 'Authorization: APIKey XxijaFsSvrgHa8mDvhQ6DF' \
    https://api.kloudless.com/v0/accounts/1/links

Authenticating users 

To connect user accounts to your application, use one of several options listed below.

This third-party blog post provides an overview of different OAuth grant flows. Kloudless supports a couple of mechanisms to authenticate users:

  • Authenticator JS library pop-up
    Your app can use the Authenticator JS library to authenticate users via a pop-up. Similar to the OAuth 2.0 Implicit Grant flow, the token is provided on the client-side.

  • OAuth 2.0 Authorization Code Grant flow
    Use this if you can authenticate users via a web server.

  • OAuth 2.0 Implicit Grant flow
    Use this if your app is entirely client-side. e.g. a browser-based JavaScript application without backend server logic. Apps with access to a backend server should attempt to use the Authorization Code grant flow instead. We also provide iOS and Android SDKs that authenticate users with an out-of-band mechanism that does not require a HTTP redirect URI to be registered.

  • OAuth 2.0 Out-of-band flow
    Installed apps, or apps on devices that may not receive a redirect, may use the out-of-band flow to render access token information to the DOM. The app can close the window after obtaining the token information.

The mechanisms above are described in more detail below.

Authenticator JS library

The Authenticator JS library enables your app to open a pop-up that allows the user to choose a service to connect. The pop-up closes once the account has been successfully connected via the OAuth 2.0 Out-of-band flow described in the docs below.

Please see the Kloudless Authenticator GitHub repo for information on how to connect user accounts to your Kloudless app, as well as a full list of configuration options.

OAuth 2.0

To get started, visit the App Details page and register a URL to redirect a user to once they have authenticated their account. Enable the Implicit Grant flow if you’d like to use that.

First Leg

First, re-direct the user to https://api.kloudless.com/v0/oauth with the appropriate query parameters as mentioned below. Kloudless will redirect the user back to a callback URL you provide.

Query parameters:

  • client_id: Required. This is your Kloudless application’s App ID.

  • response_type: Required. This must be code for the Authorization Code grant flow, or token for the Implicit Grant or Out-of-band flow.

  • redirect_uri: Required if more than one Redirect URI is registered in the App Details page. If provided, it must be a URL-encoded version of an absolute URI that exactly matches a registered URI. See notes below for more information.

  • scope: Optional. Describes the services to display, as well as any specific permissions to request. Please see details below on the format of this parameter. Defaults to all.

  • state: Required. An arbitrary string provided by you. Kloudless will include this exact value when redirecting back to you via the redirect_uri. You may include any data you’d like to use to maintain state between this request and the callback, but definitely include a random token that is checked in the callback. This prevents CSRF attacks on your users.

Scopes

The scope query parameter is a space-delimited string of scopes that indicate which services a user can connect, and which permissions to request. The general form of each scope is:

<service_identifier>[:admin].<api>

Service identifiers may be found on our documentation. Examples include box (Box), gdrive (Google Drive) and onedrivebiz (OneDrive for Business). The special identifier any indicates the user can connect any service.

Users can be offered the opportunity to connect admin accounts by suffixing the modifier :admin to a service identifier. The default modifier is :normal, indicating the regular user authentication flow should be used to authenticate users. The :all modifier will display both non-admin and admin connection options where available.

The api segment indicates which API the account should have access to. It defaults to all, which includes the following valid options: storage, crm.

Specifying a scope that resolves to a single service will immediately begin the authentication process for that service and not offer the user a chance to choose which service to connect. e.g. gdrive, box:admin or s3:all.all (all is superfluous here).

Example Scopes:

  • any List all services for regular users to connect an account. This is the default.

  • any:admin List all services that allow admins to log in.

  • any:all List all services, and also list all services that allow admins to log in.

  • any.storage List all cloud storage services.

  • any:admin.crm List all CRM services that allow admins to log in.

  • dropbox Begin the Dropbox authentication flow.

  • box dropbox Prompt the user to choose whether to connect Box or Dropbox.

  • gdrive:admin Begin the Google Drive authentication flow for admins.

  • gdrive:all dropbox:admin box Offer the user the choice of connecting a regular Google Drive account, admin Google Drive account, admin Dropbox account, or regular Box account.

  • salesforce Begin the Salesforce authentication flow for a normal user granting access to Storage (Salesforce Files) and CRM data.

  • salesforce:admin.crm Begin the Salesforce authentication flow for an admin user granting access to CRM data.

  • salesforce:all.storage Prompt the user to connect a normal or admin Salesforce account with access to Salesforce Files data.

Redirect URIs

Redirect URIs must be HTTPS endpoints unless referencing a local machine or secure private network. This prevents an attacker from obtaining a valid code for a user via eavesdropping or a man-in-the-middle attack.

You may also register a custom URL scheme for mobile applications. This enables your mobile application to receive the access token via the Implicit Grant flow.

For installed apps, you may register the URI urn:ietf:wg:oauth:2.0:oob to render data on the callback page’s HTML DOM that would have be sent via the redirect. Your app would need to obtain the data from the DOM prior to closing the window.

Here is an example of a URL to use for the first leg of the OAuth flow:

# Authenticate a user and redirect back to http://localhost:8080/callback
https://api.kloudless.com/v0/oauth/?client_id=APP_ID&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcallback&state=CSRF_PREVENTION_TOKEN

Handling the response from Kloudless

The user will proceed through the authentication process that enables them to grant access to their account to your application.

Authorization Code Grant flow

If a user successfully grants access, Kloudless will redirect back to the redirect_uri provided in the first leg with the state provided earlier and a code. The code is an authorization code that is valid for 5 minutes.

Here is an example URL:

# If the redirect_uri was http%3A%2F%2Flocalhost%3A8080%2Fcallback (http://localhost:8080/callback):
http://localhost:8080/callback?code=ABC123ABC&state=CSRF_PREVENTION_TOKEN

If a user denies access, or there is an error during authentication, Kloudless will instead redirect back with the query parameter ‘error’ in addition to state. A human-readable error message may also be present in error_description. For example:

http://localhost:8080/callback?error=access_denied&error_description=User%20cancelled%20authentication

See the Errors section below for more information on error codes.

Implicit Grant flow

Similar to the Authorization Code Grant flow above, Kloudless will redirect back to the redirect_uri provided. However, Kloudless will provide the access token (OAuth 2.0 Bearer token) in the fragment portion of the URL for access via client-side JavaScript. See the Obtaining an Access Token section below for more information.

Similarly, the error, state and error_description fields will be provided in the fragment if an error occurs. For example:

http://localhost:8080/callback#error=access_denied&error_description=User%20cancelled%20authentication

Out-of-band installed app flow.

A redirect will not occur. Kloudless will instead render the access token data in the HTML DOM. See the Obtaining an Access Token section below for more information.

Similarly, the error, state and error_description fields will be provided via the DOM as well.

Errors

The error code present in error will be one of the following:

  • invalid_request: The request may be missing a required parameter, contain incorrect parameters, or is malformed in some other way.

  • access_denied: The user or service denied access to the user’s account.

  • unsupported_response_type The value of the response_type field is incorrect.

  • invalid_scope: The scope field’s value is malformed.

  • temporarily_unavailable: Your application is being rate-limited, or the service is otherwise unavailable.

Errors with the Redirect URI will instead display an HTML page indicating the issue with the URI, as it would not be possible to transmit the error data via the redirect.

Obtaining an Access Token

The Access Token can be used in the Authorization header to perform API requests to Kloudless. This token provides complete access to the user’s account and must be kept confidential, with only trusted applications and the account owner having access to it.

Authorization Code Grant flow

The Access Token can be obtained by exchanging the authorization code retrieved earlier via a POST request to https://api.kloudless.com/v0/oauth/token with the following parameters in the body:

  • grant_type: Required. Must be authorization_code.

  • code: Required. Must be the code provided via the redirect.

  • redirect_uri: Required if a redirect URI was included in the first leg of the OAuth flow when requesting an authorization code. This must be the same value originally provided.

  • client_id: Required. Must be the Kloudless App ID of the application.

  • client_secret: Required. Must be the Kloudless API Key of the application.

The parameters must be URL-encoded and sent via the “application/x-www-form-urlencoded” format. For example, the body of the request could be:

grant_type=authorization_code&code=ABC123ABC&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcallback&client_id=APP_ID&client_secret=API_KEY

Here is an example of performing the request using cURL:

curl -X POST -d 'grant_type=...the remaining string above' https://api.kloudless.com/v0/oauth/token

If successful, the response to the request will contain a JSON object with the following attributes:

  • access_token: A string representing the access token. Save this securely for use with future API requests to this account.

  • token_type: Will be ‘Bearer’.

  • scope: The scope granted to the access token. As of the current time, this will be the requested scope. In the future, Kloudless may return a subset of the requested scopes if the user grants partial access to their account.

  • account_id: The Kloudless ID of the account that was connected to the application.

  • warnings (Optional): A JSON object containing any warnings encountered when connecting the account. Values are human-readable warning messages. The keys could be any of the following:

    • account_limit: The maximum number of accounts that can be connected is approaching. Only applies if a maximum exists.

If unsuccessful, error data will be provided in the response instead. See the Errors section below for more information.

Implicit Grant flow

If successful, the fragment section of the URL will contain the access token information mentioned below:

  • access_token: A string representing the access token. Save this securely for use with future API requests to this account.

  • token_type: Will be ‘Bearer’.

  • scope: The scope granted to the access token. As of the current time, this will be the requested scope. In the future, Kloudless may return a subset of the requested scopes if the user grants partial access to their account.

  • state: The value provided in the state parameter in the first leg of the OAuth flow.

  • warnings (Optional): A JSON-encoded string containing any warnings encountered when connecting the account. Values are human-readable warning messages. The keys could be any of the following:

    • account_limit: The maximum number of accounts that can be connected is approaching. Only applies if a maximum exists.

Each value will be URL-encoded if necessary. Here is an example:

http://localhost:8080/callback#access_token=ABC123ABC&token_type=Bearer&scope=gdrive&state=CSRF_PREVENTION_TOKEN
Verify the token

For security purposes, it is important to verify that the access token was granted to your application and not another application. Otherwise, your application could be vulnerable to a Confused Deputy attack as described in this section of the RFC.

To validate the token, perform a GET request to https://api.kloudless.com/v0/oauth/token with the header Authorization: Bearer TOKEN where TOKEN is the access token.

For example:

curl -X GET -H "Authorization: Bearer ABC123ABC" https://api.kloudless.com/v0/oauth/token

A valid token will return a response with a 200 status code and a JSON body with the following attributes:

  • client_id: The ID of the application the token was granted to.

  • account_id: The ID of the account the token provides access to.

  • scope: The scope granted to the access token.

You must verify that the client_id matches your Kloudless Application ID exactly. If it does not, do not use the token, and feel free to revoke it. If it does match, you may proceed with using the token in your application.

If you have existing knowledge of the account the token belongs to, please also verify the account_id matches the ID of that account.

If the token has expired, has been revoked or is no longer valid, the response will instead have a 400 status code with the body:

{"error": "invalid_token"}

By design, no other information is provided.

Out-of-band installed app flow

This section is very similar to the Implicit Grant flow above.

However, instead of attributes present in the fragment of the redirected URL, each attribute will be rendered on the DOM in <meta /> elements, with the id attribute of the element identifying the type of data and the data-value attribute providing its value.

There will also be text on the page providing the user with the access token in case you would prefer the user copy it into your application.

For example:

<!DOCTYPE html>
<html>
  <body>
    <meta class="token-data" id="access_token" data-value="ABC123ABC" />
    <meta class="token-data" id="token_type"   data-value="Bearer" />
    <meta class="token-data" id="scope"        data-value="gdrive" />
    <meta class="token-data" id="state"        data-value="CSRF_PREVENTION_TOKEN" />
    <meta class="token-data" id="warnings"     data-value='{"warning-key": "optional warning message"}' />
    <p>
      You have successfully connected your account.
    </p>
    <p>Secret Access Token: <code>ABC123ABC123</code></p>
  </body>
</html>

Similarly, the error, state and error_description fields will be provided via DOM <meta /> tags if an error occurs.

You may close the window or redirect away after obtaining the information from the DOM. There may be other DOM elements present on the page, so it is important to only check for <meta /> elements to obtain information from.

You must validate the access token prior to using it, as mentioned above in the Implicit Grant flow. This avoids security vulnerabilities such as the Confused Deputy problem.

Errors

Unsuccessful requests will result in one of the following error codes returned in the error field, as well as a human-readable error_description if available:

  • invalid_request: The request contains incorrect parameters or is otherwise malformed.

  • invalid_grant: The provided authorization grant (e.g. the authorization code) is invalid or expired.

  • unauthorized_client: The client is not authorized to use this grant type.

  • unsupported_grant_type: An incorrect grant type was used in the request.

  • invalid_scope: The scope requested is invalid or malformed.

Revoking Access Tokens

Once a token is revoked, it can no longer be used for API requests.

To revoke a token, perform a DELETE request to https://api.kloudless.com/v0/oauth/token/, with a query parameter token containing the token to revoke.

For example:

curl -X DELETE https://api.kloudless.com/v0/oauth/token/?token=ABC123ABC

A response with the status code 204 will be returned if the revocation is successful or the token does not exist.


Migration from older protocols 

The previous mechanism of authenticating users was supported for v0 of the API till August 31, 2017. API versions v1 and beyond require OAuth 2.0 to be used.

Please modify your application to use the OAuth 2.0 authentication mechanism to obtain the token instead of the previous authentication mechanism, for all new accounts connected by users. If you previously performed API requests with the authorization header Authorization: AccountKey KEY, the requests would now be Authorization: Bearer TOKEN.

Account Key Authorization will continue to be supported for v0. Account Keys can be converted to Bearer tokens by performing an API request to the token_from_key endpoint. You can try this request from the API Explorer. Please delete the Account Key after you’ve stored the new OAuth token and use the OAuth token for all subsequent requests.

The API Key Authorization scheme will continue to be valid, and can be used instead of OAuth tokens to authorize API requests from the server-side for verified accounts.


Roadmap 

  • Adding support for programmatic Redirect URI management via the Meta API.

  • Updating the SDKs.

  • Updating the demo applications.