Non-Persistent Tokens

With the addition of the revocation events system it is now possible to implement a token provider that does not require the ability to lookup a token ID based upon data contained within the token (e.g. revoking all tokens issued to a specific User ID). The new revocation event uses data values from a class of tokens (e.g. User ID, Domain ID, Project ID) to determine if a token is revoked instead of relying on an explicit list of token IDs generated by Keystone. The new revocation matching is performed within the auth_token middleware on each token instead of within Keystone to generate the list of token IDs that are revoked.

bp non-persistent-tokens

Problem Description

Currently there is significant overhead in managing the persistence backend for the Token data. This administrative and performance overhead manifests in a number of ways:

  • SQL Backend sees significant bloat in the DB causing poor performance, significant consumption of processing and storage resources.

  • Memcached (and largely all Key-Value-Store backends) show poor handling of the required enumeration of each user’s tokens to handle revocations under the Token Revocation List. Even with the revocation events, the overhead in running the backing store can be significant while providing little added value.

Proposed Change

The change will be to eliminate the need to persist tokens to any form of stable storage. When using the new non-persistent token provider, UUID and short-hashed versions of PKI tokens will not be supported. The UUID and standard PKI token providers will not be deprecated in the Juno development cycle. Deprecation of the original PKI token providers (PKI and PKIZ) will occur as early as the K cycle; this delay in deprecation allows for operators and deployers to adopt the new non-persistent tokens before it becomes the default deployment model. The UUID token provider will be evaluated for deprecation based upon how many deployments continue to utilize UUID over PKI tokens.

Alternatives

  • Incremental improvement to the storage backend drivers could be used instead of the non-persistent tokens. However, these incremental improvements would not ease the administrative or resource overhead as simply not requiring any persistence of the token. Long term, these incremental improvements would drive towards non-persistent tokens, as that becomes the simplest/most maintainable solution (no risk of data loss or data corruption in the backing store, no long-term memory/storage overhead, etc).

  • Expand the reuse of valid tokens. It is currently advocated that tokens should be reused where possible, however, there are a number of cases where token reuse isn’t implemented, implemented poorly, or partially implemented. Even with solid token reuse, the bloat and overhead of managing the persistence backend is not eliminated.

Data Model Impact

The general data model for the token (in-memory) will change to be a token version agnostic memory construct. This will be a departure from the current Python dictionary that is used (and varies in structure based upon token version). This change will eliminate some of the more complex conditional code that is used to support the different token versions now. This change to the in-memory structure for tokens is to ensure ease of understanding code rather than having an ever expanding set of conditional code to handle the variations on token structure across an increasing number of versions. Both v2 and v3 tokens have significant structural differences that will add significant complications to the code-base when eliminating the calls to .get_token.

The new in-memory token model will be serialized as closely as possible to the SQL token backend’s schema to eliminate the need for a DB migration. Other token persistence backends will do in-place (seamless) handling of the differing token-formats. The persistence backend changes are required for a seamless upgrade path to non-persistent tokens.

JSON Schema for each token version will need to be developed for complete validation as part of the conversion from the versioned-token-format to the internal token object.

REST API Impact

When the new provider is used (non-persistent-token-provider) only PKI tokens will be issued, and the short-hash version of the token cannot be used to interact with Keystone.

REST APIs that deal directly with the token resource will be modified:

  • V2.0 Token APIs will return a TokenNotFound (HTTP 404) if the short-hash-id is used. This will impact HTTP GET, HEAD, and DELETE for token APIs (Validation, Check, Revoke).

  • V3 APIs will raise a Forbidden (HTTP 403) if the token short hash is used. This is consistent with the use of the X-SUBJECT-TOKEN header with the short-hash-id.

  • APIs that do policy enforcement based upon data derived from the token in the X-AUTH-TOKEN header will return the appropriate 401 (invalid token) if the short-hash-id is used (same result as using any invalid token).

Security Impact

The internal token format will be changed to be consistent. Externally facing use and format of the token should not be impacted.

All cases of PKI tokens will be decoded (in a similar fashion to auth_token middleware) in memory instead of referencing data stored in the token DB persistence store. The ability to use the token backend for auditing will no longer be available. Instead audit will rely exclusively on the CADF authentication notifications.

Notifications Impact

None

Other End User Impact

None

Performance Impact

Generally speaking this change should reduce load on the system and resource consumption by not requiring persistence of token data. Tokens will need to be decoded via CMS, raising the CPU cost of handling GET and HEAD (validate and check) mechanisms on tokens in the v2.0 Idenity API. This change is due to the data not being stored outside of the PKI signed token data.

Other Deployer Impact

To leverage the non-persistent tokens deployers will need to do the following:

  • Use revocation events instead of token revocation list

    • auth_token middleware will need to be configured to use revocation events. This will be added to the deployment docs for OpenStack. No other changes to auth_token middleware will be needed.

  • Set the token provider to the new non-persistent token provider

No new configuration options will be added.

Developer Impact

All references to token_api.get_token (excluding use in the UUID token provider) will need to be removed. Direct lookup of token data without decoding the PKI token (when PKI tokens are used) will not be available.

Any interaction with token data will be done in a consistent manner through the new uniform token object, eliminating the need for specific code handling a versioned token dictionary.

Implementation

Assignee(s)

Primary assignee:

Morgan Fainberg (mdrnstm)

Other contributors:

Adam Young (ayoung)

Work Items

  • Token version agnostic object development

  • Token Validation / Conversion to new token object

  • Keystone AuthContextMiddleware updated to always do CMS decode of PKI tokens.

  • Elimination of all calls to token_api.get_token except when using the UUID token provider.

  • Implementation of non-persistent-PKI-token-provider

    • Code to detect mis-configuration will be required. Non-Persistent tokens require revocation events and disabling revocation by id.

    • Implement a new consistent configuration error exception for Keystone.

    • If revocation events are not enabled and/or revoke-by-id is enabled the new configuration exception will be raised.

Dependencies

Testing

  • A Tempest scenario will be needed to test the non-persistent token provider deployment.

  • Unit tests will be required to exercise the non-persisted provider independent of the UUID backend.

  • Initially an alternate test scenario will be needed to validate the non- persistent token provider. Once revocation events becomes the default deployment method, the non-persistent provider should become default as well.

Documentation Impact

Documentation on deploying with revocation events and non-persistent PKI token provider will need to be included (configuration changes).

References