How to search and revoke OAuth2 Access Tokens manually on some conditions

Not applicable

Hi Team,

A customer has questions about the use cases of OAuth Token search and revoke.
On their business process access token is used to grant access to the resource on their system.

In addition to the normal use cases of grant/revoke of the token in the OAuth flow, they want to have the use case of manually revoke it by operators in Auth server communicating with an operator at API management system where access tokens are stored.

This is the case when the end users request to terminate contract telling the Auth server operator by phone calls or email as illustrated on the attached business process use case diagram.

6476-business-flow2.png

Then there seems to be some problems due to the current design restriction of Apigee Edge OAuth features.

1. Tokens cannot be searched by App End User ID with Management API

  • Access token which was expired (Expires in 10 to 15 minutes)
  • Refresh token even before expiration (Expires in 1 to 6 months)

So, in the most of the cases search doesn't work for retrieving the status (approved/revoked/expired) for all the tokens which are stored on DB. But this is required for the operators to check the status and revoke it as requested.

2. Tokens cannot be revoked with being hashed

In the customer's use case Token hashing is used for the security of the business requirements.
Then the restriction that only passing tokens without being hashed can be revoked. That means only the API client side who knows the tokes before hashing can do revoke it, but API management platform operators cannot revoke the tokens as requested.

Therefore we need to investigate the workaround against the above 2 problems of current restrictions of Apigee Edge.

As it doesn't seems to be customer specific requirements but required in similar business processes, I would like to have advices for some possible solutions.

Regards,
Toshi

1 11 1,426
11 REPLIES 11

Not applicable

Hi @Toshihiro Shibamoto,

Assuming that 'App End User ID' has been enabled and working fine except above specified scenarios.

1. Search: I believe, Retrieve management API is used to retrieve associated tokens.

Providing list of expired token may not be a good idea as such list may be quite huge. However, list of unexpired tokens, access and refresh tokens, should be available as part of the response.

As you have found that list of unexpired refresh token is not provided, I would suggest to raise a Jira ticket. Having said that I think this may not be a blocker as main business requirement is to revoke tokens (both access and refresh token types) associated with an 'App End User Id'. Have you faced any issue with revocation of refresh token?

2. For revocation of hashed tokens, is standard management 'Revoke' api not working? If not, A jira ticket need to be raised.

@Dino, What do you suggest?

Thanks,

Rajesh

Hi @rajeshdoda,

Thank you for the response with useful advice.
For the search of tokens we can retrieve information anyway by exporting the SSTable with sstable2json command, etc.

So, the problem we need to solve with priority is that currently we don't support hashed Access Token for the status change of Access Token.

Approve or Revoke OAuth 2.0 Access Token
https://api.enterprise.apigee.com/v1/organizations/{org_name}/oauth2/accesstokens/{access_token}
The issue is as mentioned above - the service provider who only has hashed token cannot call because we have no mapping info of user ID and the raw access tokens.
I'll open a jira case and track it for the fix or feature request in the upcoming release/patch as you suggested.

For now the customer needs some kind of solution to enable the launch coming soon.

Firstly can you check and advise us if we can revoke the hashed tokens by some steps, modify the currently implemented process or manage anyhow with cqlsh commands, etc. to enable it?

If it's not available, there are some other options we can look into as follows;

1. Using BaaS with mapping user ID and Access Tokens to call the API
- The tokens are encrypted by users for security
- Are there any concerns or any cases where BaaS is used for the similar purpose?

2. Using RDBMS like PostgreSQL for the same
- Is there any constraints on jdbc driver - trieme-jdbc, etc.?

3. Using Cassandra DB with adding the extra columns of the mapping data
- There seems to be a performance concern since user ID has no index for SELECT that makes inefficient search.

- and aslo compatibility issue of upgrading Edge in future?


There should be some more options.

Could you give advices on what can be the most recommended options for the customer?

Regards,

Toshi

Not applicable

Hi @Toshihiro Shibamoto,

Technically, Revoke API should disable all tokens including hashed token associated with 'App End User Id'. Could you pl try following curl command (corresponding to Revoke API by End User Id) and confirm if it works or not.

curl -X POST --header "Authorization: Basic XXXXX" --header "Content-Type: application/x-www-form-urlencoded;charset=utf-8" "https://api.enterprise.apigee.com/v1/organizations/{orgname}/oauth2/revoke?enduser=end_user_name"

Note: This feature is not enabled for my trial org and so not able to confirm it.

Storing access token (without hashing) will defeat the purpose of applying hashed token approach apart from adding latency to response.

Lets first test if above command revokes hashed token or not. If not, we need to devise a solution based on scale and TTL of tokens (access and refresh tokens).

Regards,

Rajesh Doda

Hi @rajeshdoda,

I tested this on the environment with configures; 'features.isOAuthRevokeEnabled = true' and found;

/oauth2/revoke?enduser=end_user_name
doesn't work wit the "Authorization: Basic XXXXX" where the access token XXXXX is hashed.

On the same condition, I also found;
/oauth2/refreshtokens/{refresf_token}?action=revoke&cascade=true

works and the status of Access token and Refresh token both changed to 'revoked' status.

So, it seems that this is the restriction of Edge correct?

Also regarding the condition of using expired access token I found;

/oauth2/refreshtokens/{refresf_token}?action=revoke&cascade=true

doesn't work and it fails in with the message:

"code" : "keymanagement.service.access_token_expired",
"message" : "Access Token expired",
So, could you advise what can be the measures we can take for the purpose of revoke refresh token, when the token is hashed and expired.

Or if there are not anything, could you advice what is the recommended alternative way as we store the token separately by either of the followings?

  1. Using BaaS with mapping user ID and Access Tokens to call the API
  2. Using RDBMS like PostgreSQL for the same
  3. Using Cassandra DB with adding the extra columns of the mapping data

Regards,
Toshi

Not applicable

Hi @Toshihiro Shibamoto,

Assuming that access token was hashed when access and refresh tokens were revoked by executing 'revoke' command on refresh token. Pl confirm.

Also, could you test if (hashed) access and refresh tokens can be revoked by 'App ID'. If this works successfully that means Edge configuration is incomplete for revoke operation by 'App End User Id'.

Revoke to OAuth2 tokens by 'App End User Id' requires specific configuration at Edge. Some of these steps can be performed by Apigee support team if it's Apigee cloud instance. For private cloud, these steps need to be performed by orgadmin or opsadmin of Edge. At high level; there are two main aspects:

1. Edge configuration => Generally performed by orgadmin or opsadmin

2. OAuth2.0 policy configuration during token generation => Generally performed by API proxy developer. This can be verified by analyzing the policy of token generation or verifying the response having 'app_enduser' field.

Could you confirm that all these steps have been performed.

Regards,
Rajesh Doda

Hi @rajeshdoda,

After multiple trials I confirmed the behaviors as follows.

Before access token is expired;

  • Revoke OAuth2 Access Token by End User and App ID both work but the status of access tokens only are changed to 'revoked'
  • Revoke Refresh Tokens by /oauth2/refreshtokens/{refresh token}?action=revoke&cascade=true will revoke both access tokens and refresh tokens
    Note: This only works for using {refresh token} before hashing and if hashed token is specified, the error is returned:
  "code" : "keymanagement.service.invalid_refresh_token",
  "message" : "Invalid Refresh Token",
  "contexts" : [ ]

After access token is expired;

  • Revoke by the above two options will not change status.


To your suggested points they are configured rightly;

  • The features isOAuthRevokeEnabled, isOAuth2TokenSearchEnabled and isOAuthTokenHashingEnabled are all configured as 'true'.
  • OAuth2.0 policy configuration looks ok as the above result working for before expiration.

So, there seems to be following issues:

  1. 'Revoke OAuth2 Access Token by End User and App ID' will leave refresh token status unchanged.
  2. After expiration of access token the status cannot be changed by Revoke APIs to 'revoked' and the refresh tokens are still 'approved' and valid.

So, this can cause a security problem by referring to the RFC:
https://tools.ietf.org/html/rfc6749#section-1.5

which describes 'Refreshing an Expired Access Token' means the possibility of expired access token can be refreshed by the design specification.

This means that if refresh tokens are not revoked for the users with expired access token and need to be revoked by authorized server operators, still the access token can be refreshed on the above restriction where we cannot revoke refresh token once the access token is expired.

Could you advise what we can manage this issue by some workaround?

Regards,
Toshi

Not applicable

Hi @Toshihiro Shibamoto,

Thanks for executing scenarios and providing details.

Issue 1: 'Revoke OAuth2 Access Token by End User and App ID' will leave refresh token status unchanged.

[Rajesh Doda] Could you pl confirm if access token can be generated from such refresh token. My intuitive guess is such 'Refresh Token' should be in unusable state.

In case, access token can be generated then alternative option is to configure 'InvalidateToken' operation of OAuth2 policy as specified below. A separate proxy can be developed and made available to Admin.

<OAuthV2 name="InvalidateToken">
	<Operation>InvalidateToken</Operation>
	<Tokens>
		<Token type="accesstoken" cascade="true">accesstoken_var</Token>
	</Tokens>
</OAuthV2>

Issue 2: After expiration of access token the status cannot be changed by Revoke APIs to 'revoked' and the refresh tokens are still 'approved' and valid.

[Rajesh Doda] I agree with you that refresh token associated with expired access token need to be revoked as well. Such scenario can be avoided once 'Retrieve' API can provide list of refresh token along with access tokens as discussed earlier. Pl add this finding to the corresponding Jira ticket and prioritize it.

Regarding custom solution; could you provide information in terms of scale e.g. token generation frequency, number of end users, TTLs of access and refresh tokens.

Regards,
Rajesh

Hi @rajeshdoda,

Thank you for the comments.
Issue 1: with the information shared by @VijayaKumar

/oauth2/refreshtokens/{refresh token}?action=revoke&cascade=false
will revoke the refresh token even after the access token is expired.

And the Management API doesn't accept hashed token - it's confirmed as a current design limitation and need feature request in the upcoming release.

To your questions the customer shared the information as follows:
  • token generation frequency: 50 tokens per second
  • number of end users: 1350,000 users
  • Access token expires in 10 to 15 minutes
  • Refresh token expires in 1 to 6 months

I would appreciate your providing advices on the options from BaaS/RDBMS/Cassandra, etc. - which one to be recommended for storing the tokens on their own as a workaround.

Regards,
Toshi

Not applicable

Hi @Toshihiro Shibamoto,

Custom solution based on BaaS/ RDBMS/Cassandra, etc is my last preferred soln because of:

1. This would introduce higher latency due to network hop.

2. Cost of custom soln is high due to infrastructure (HA is recommended) and higher development effort as compare to recommended soln.

3. This soln being temporary one and need to be removed once raised request is complete.

My preferred solution would be to utilize Cache and Encrypted KVM. Detail is:

1. Custom encrypt access token and store it in Cache having cache entry TTL same as of access token.

Note: There could be multiple valid access tokens for a user; store them (comma separated) as part of same cache entry.

2. Store encryption related info (cipher, algorithm) as part of the Encrypted KVM.

3. Refresh tokens can also be stored as a separate entry (due to difference of TTL) in Cache. As TTL is longer, this would require storage for longer time.

I would suggest not to store refresh token. Instead, add user validation check to Authorization server when generating access token as part of refresh token flow. On invalid user credential, don't generate access token even refresh token is a valid one.

Note:

1. User credentials will be invalidated by operator at Authorization server.

2. As discussed, grant_type used is password.

3. Recommend to encrypt user credentials before associating them with tokens.

4. Cache provides automatic removal of entry on expiry of TTL.

Estimated space required for access tokens based on given traffic:

= Token generation frequency * TTL of access token * Size of cache entry

= 50 / sec * 600 sec * 100Bytes

= 3MB

Note: Space requirement will become 4.5MB if TTL of access token is configured as 15 minutes.

Regards,
Rajesh Doda

Hi @rajeshdoda,

Thank you so much for the elaborated suggestion of the workaround which the customers can take.
They are advised on these points and are now investigating and planning.
Then they are supposed to come back with if any queries for clarification, etc.

Regards,
Toshi

Hi @rajeshdoda,

I have some questions.

1. The number of total cache entries is supposed to be 50/sec * 600sec = 30,000 entries. Is it ok to store this large number of cache entires as environment cache?

2. To the description:
---------
Instead, add user validation check to Authorization server when generating access token as part of refresh token flow. On invalid user credential, don't generate access token even refresh token is a valid one.
---------

My understanding is that the above validation on Authorization server is done as ignoring the request with the refresh token linked to a specific app end user ID who should be revoked.
Then is such list of users stored by Authorization server and kept until the refresh token is expired? How do we know the timing to delete it? And where are the up to 1350,000 entries to be stored?

3. Anyway this seems to be a big changes required on Authorization server side. Are there any other simple way to revoke the users in a way implemented only by API proxy level?

Regards,
Toshi