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
middleware on each token instead of within Keystone to generate the list
of token IDs that are revoked.
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.
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
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
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-TOKENheader with the short-hash-id.
APIs that do policy enforcement based upon data derived from the token in the
X-AUTH-TOKENheader will return the appropriate 401 (invalid token) if the short-hash-id is used (same result as using any invalid token).
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
Other End User 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.
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
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.
- Primary assignee:
Morgan Fainberg (mdrnstm)
- Other contributors:
Adam Young (ayoung)
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.
This spec depends (for validation code path) on https://blueprints.launchpad.net/keystone/+spec/api-validation
This spec depends on full revocation event support in auth_token middleware.
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 on deploying with revocation events and non-persistent PKI token provider will need to be included (configuration changes).