Antipattern: Set no expiration time for OAuth tokens

You're viewing Apigee Edge documentation.
Go to the Apigee X documentation.
info

Apigee Edge provides the OAuth 2.0 framework to secure APIs. OAuth2 is one of the most popular open-standard, token-based authentication and authorization schemes. It enables client applications to access APIs on behalf of users without requiring users to divulge their username and password.

Apigee Edge allows developers to generate access and/or refresh tokens by implementing any one of the four OAuth2 grant types - client credentials, password, implicit, and authorization code - using the OAuthv2 policy. Client applications use access tokens to consume secure APIs. Each access token has its own expiration time, which can be set in the OAuthv2 policy.

Refresh tokens are optionally issued along with access tokens with some of the grant types. Refresh tokens are used to obtain new, valid access tokens after the original access token has expired or been revoked. The expiration time for refresh tokens can also be set in the OAuthv2 policy.

This antipattern is related to the antipattern of setting a long expiration time for OAuth tokens.

Antipattern

Setting no expiration time for a refresh token in the OAuthv2 policy leads to accumulation of OAuth tokens and increased disk space use on Cassandra nodes.

The following example OAuthV2 policy shows a missing configuration for <RefreshTokenExpiresIn>:

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn> <!-- 30 minutes -->
    <!--<RefreshTokenExpiresIn> is missing -->
    <SupportedGrantTypes>
      <GrantType>password</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>

In the above example:

  • The access token is set with a reasonably low expiration time of 30 minutes.
  • The refresh token's expiration is not set.
  • Refresh token persists in data store (Cassandra) forever, causing data accumulation.
  • A refresh token minted without an expiration can be used indefinitely to generate access tokens.
  • If the traffic to this API is 10 requests per second, it can generate as many as 864,000 tokens in a day.

Impact

  • If the refresh token is created without an expiration, there are two major consequences:
    • Refresh token can be used at any time in the future, possibly for years, to obtain an access token. This can have security implications.
    • The row in Cassandra containing the refresh token will never be deleted. This will cause data to accumulate in Cassandra.
  • If you don't use the refresh token to obtain a fresh access token, but instead create a fresh refresh token and access token, the older refresh token will remain in Cassandra. As a result, refresh tokens will continue accumulating in Cassandra, further adding to bloat, increased disk usage, and heavier compactions, and will eventually cause read/write latencies in Cassandra.

Best Practice

Use an appropriately low expiration time for both refresh and access tokens. See best practice for setting expiration times of refresh and access tokens. Make sure to specify an expiration configuration for both access and refresh token in policy. Refer to the OauthV2 policy documentation for further details about policy configuration.

Best practices specifically for Edge for Private Cloud customers

The section describes best practices specifically for Edge for Private Cloud customers.

Specify a default refresh token expiration

By default, if a refresh token expiration is not specified in a policy configuration, Edge creates a refresh token without any expiration. You can override this behavior by the following procedure:

  1. On a message processor node, edit or create the configuration override file $APIGEE_ROOT/customer/application/message-processor.properties. Make sure this file is readable by the apigee user.
  2. Add the following line to the file:
    conf_keymanagement_oauth_refresh_token_expiry_time_in_millis=3600000
    This will set the default refresh token expiration, if none is specified in a policy, to 1 hour. You can change this default value based on your business needs.
  3. Restart the Message processor service:
    apigee-service edge-message-processor restart
  4. Repeat the above steps in all message processor nodes one by one.

Best practices in Cassandra

Try to upgrade to the latest version of Apigee available publicly. Apigee continues to release fixes and enhancements which continue to improve and optimize management of tokens within Apigee. In Apigee, access and refresh tokens are stored in Cassandra within the “kms” keyspace. You should ensure that the compaction strategy of this keyspace is set to LeveledCompactionStrategy. You should check that the following indices are not present:
  • kms.oauth_20_access_tokens.oauth_20_access_tokens_organization_name_idx#f0f0f0 and
  • kms.oauth_20_access_tokens.oauth_20_access_tokens_status_idx

You can also reduce gc_grace_seconds in the table kms.oauth_20_access_tokens from the default 10 days to a lower value (such as 3 days) to ensure tombstones generated due to tokens being deleted are purged from the data store faster.

Further reading