New Authorization Tooling – Improved Usability and Security

More granular control of OAuth access tokens

Reddit
LinkedIn

As our developer ecosystem continues to expand, our partnering developer needs have pushed us to improve our Authorization tooling for a better and more secure experience. This update covers three OAuth Access Token improvements which can be used independently or together - to provide a better experience and improve the security of your applications:

  • Limited Scope OAuth Access Tokens
  • Short Lived OAuth Access Tokens
  • Revoking a Single OAuth Access Token without losing Authorization

Limited Scope OAuth Access Tokens

Problem: When a seller grants developers OAuth access to their account, the resulting Authorization can result in an OAuth Access Token containing a set of permissions which is too powerful to pass around for concrete actions. For example, a merchant can grant a developer, ["MERCHANT_PROFILE_READ","PAYMENTS_READ","PAYMENTS_WRITE","BANK_ACCOUNTS_READ"]" - but the client strictly needs, “["MERCHANT_PROFILE_READ"]” to retrieve the business_name of a merchant. Prior to this update, it was not possible to reduce the scope of an Access token’s Authorization to strictly required permissions needed to accomplish a given task. A token containing all of a seller’s Authorizations presents an inherent security risk, as some permissions are sensitive and used in limited contexts (ex: PAYMENTS_WRITE). An intercepted token containing a full set of seller permissions can be used maliciously - posing an increased security risk.

Solution: As an optional field within the Obtain token endpoint (obtaining an access token from a refresh token), we introduced the scopes field enabling developers to define the set of permissions to be contained within the resulting OAuth Access Token. It is best practice to pass OAuth Access Tokens with strictly required permissions needed to perform a given action; this update enables the creation of an OAuth Access Token with scoped-down permissions.

Example - Assume the following:

  • Merchant has granted an application access to the following scopes:
[
  "MERCHANT_PROFILE_READ",
  "PAYMENTS_READ",
  "PAYMENTS_WRITE",
  "BANK_ACCOUNTS_READ"
]
  • The Developer would like to create a new OAuth Access token strictly limited to the following scopes:
[ "MERCHANT_PROFILE_READ", "PAYMENTS_READ" ]

Example Sandbox Request

curl https://connect.squareupsandbox.com/oauth2/token \
  -X POST \
  -H 'Square-Version: 2020-11-18' \
  -H 'Content-Type: application/json' \
  -d '{
    "scopes": [
      "MERCHANT_PROFILE_READ",
      "PAYMENTS_READ"
    ],
    "grant_type": "refresh_token",
    "refresh_token": "REFRESH_TOKEN",
    "client_secret": "APPLICATION_SECRET",
    "client_id": "APPLICATION_ID"
  }'

Example Sandbox Response

200 Response
{
  "access_token": "ACCESS_TOKEN",
  "token_type": "bearer",
  "expires_at": "2021-01-02T00:14:15Z",
  "merchant_id": "MERCHANT_ID",
  "refresh_token": "REFRESH_TOKEN",
  "short_lived": false
}

What’s included:

  • The ability to generate new OAuth Access tokens with reduced permission scopes.

What’s not included:

  • The API response does not include a list of scopes. If a 200 Response is returned, it can be assumed the scopes have been added to the newly minted OAuth Access Token.

Short Lived OAuth Access Tokens

Problem: The default expiration for access tokens has been 30 days. This has led to errors and outages since the expiring token was not encountered until nearly a month later. The 30 day expiration increases risk of exposure and abuse.

The default expiration for OAuth access tokens was 30 days because credentials were traditionally used from a tightly access controlled environment (e.g. a server). However, our developers are expanding on their use-cases - and credentials are sometimes passed down to loosely controlled access environments (e.g. browser or mobile client). When working within these environments, developers prefer a credential with a shorter lifespan to prevent errors and mitigate risk.

Solution: As an optional field within the Obtain token endpoint, we introduced the short_lived field enabling developers to generate a short-lived OAuth access token which will expire 24 hours after creation. This provides optional flexibility for developers working in loosely controlled access environments.

Example – Assume the following:

  • A Developer would like to create a new OAuth Access token which expires 24 hours after creation.

Example Sandbox Request

curl https://connect.squareupsandbox.com/oauth2/token \
  -X POST \
  -H 'Square-Version: 2020-11-18' \
  -H 'Content-Type: application/json' \
  -d '{
    "grant_type": "refresh_token",
    "refresh_token": "REFRESH_TOKEN",
    "client_secret": "APPLICATION_SECRET",
    "client_id": "APPLICATION_ID",
    "short_lived": true
  }'

Example Sandbox Response

200 Response
{
  "access_token": "ACCESS_TOKEN",
  "token_type": "bearer",
  "expires_at": "2020-12-04T00:16:17Z",
  "merchant_id": "MERCHANT_ID",
  "refresh_token": "REFRESH_TOKEN",
  "short_lived": true
}

What’s included:

  • Ability to generate new OAuth Access tokens with a 24 hour expiration timeframe.

What’s not included:

  • Ability to customize the expiration timeframe.

Revoking a Single OAuth Access Token without losing Authorization

Problem: The default behavior for Square’s Revoke token endpoint will terminate the entire authorization for a given merchant. However, there are reasons to create and expire given OAuth Access Tokens - without terminating the entire merchant authorization. For example, if an OAuth Access Token is compromised, developers would like to revoke this token and generate a new token - without losing merchant Authorizations. We can also create an OAuth Access Token with limited scope, and expire strictly this token whenever needed. Prior to this update, after Revoke token was called - the merchant was forced to go through the OAuth flow again.

Solution: As an optional field within the Revoke token endpoint, we introduced the revoke_only_access_token field enabling developers to terminate the given single OAuth Access Token, without terminating the entire authorization.

Example - Assume the following:

  • A Developer realized her OAuth Access Token has been compromised. She would like to revoke this token without losing merchant Authorizations.

Example Sandbox Request

curl https://connect.squareupsandbox.com/oauth2/revoke \
  -X POST \
  -H 'Square-Version: 2020-11-18' \
  -H 'Authorization: Client APPLICATION_SECRET' \
  -H 'Content-Type: application/json' \
  -d '{
    "access_token": "ACCESS_TOKEN",
    "client_id": "CLIENT_ID",
    "revoke_only_access_token": true
  }'

Example Sandbox Response

200 Response
{
  "success": true
}

What’s included:

  • Ability to revoke an OAuth Access Token without losing a merchant's Authorizations.

What’s not included:

  • Detailed API response, outlining the status of the OAuth Access Token.

Getting Started:

We’re excited to see what you build! If you have any questions about OAuth or anything else with the Square API, please reach out to us in our forums here.