After doing a bunch of research, this is *not* a bug in Keystone. Keystone properly invalidates the token(s) assuming you are not doing a direct update of the database (e.g. with SQL) and using the keystone API to disable the user (such as with the CLI or Curl). What is happening is that keystonemiddleware defaults to caching for ~300 second in-memory. This means that once the token has been used against an endpoint, there is 300 second window where the token will be valid even if the user has been disabled. If the option in nova.conf the [keystone_authtoken] section, the cache time is controlled by the 'token_cache_time' option. I performed the following tests: 1) Get token (for this example, token is 2ee5b4d696da4364800f9a703a316c2e) 2) Get server list from nova (either by curl or by nova cli) succeeds. * curl -i 'http://10.0.2.15:8774/v2/5cef269803424bdca931da8a06190f62/servers/detail' -X GET -H "Accept: application/json" -H "X-Auth-Project-Id: demo" -H "X-Auth-Token: 2ee5b4d696da4364800f9a703a316c2e" * nova --os-auth-token a58ce46932784f569432054a68be86af list 3) Disable user via either keystone cli or curl: * curl -g -i --cacert "/opt/stack/data/CA/int-ca/ca-chain.pem" -X PUT http://10.0.2.15:35357/v2.0/users/5d9ca3899f0f4db3a813990739dcbb52 -H "User-Agent: python-keystoneclient" -H "Content-Type: application/json" -H "Accept: application/json" -H "X-Auth-Token: c1ebb3c3300841d7b63745b3a233e99d" -d '{"user": {"enabled": false, "id": "5d9ca3899f0f4db3a813990739dcbb52"}}' * keystone update-user --enabled false 5d9ca3899f0f4db3a813990739dcbb52 4) Get server list from nova (same as above) works. 5) After 300 seconds the the command now appropriately fails with a 401. If the 'token_cache_time' option is set to 1 in the nova.conf, the above scenario acts more as expected. The token/provider.py explicitly does not check user/tenant enabled as it relies on either the Token Revocation List (a list of invalidated tokens) or the Revocation Event System (a list of events that can invalidate tokens, such as 'invalidate all tokens for user x'). The intent is that Keystone relies on a consistent way to determine if tokens are valid vs. needing to examine the DB for all the details, since there are cases that we need to produce other invalidations (e.g. password change). ===================== If a direct update of the SQL DB is performed, there is currently no direct method for invalidation of all tokens for a user. This could be generally improved to validate where users are query-able. Alternatively we could provide an API that allows for issuing the revocation events that would be expected for disabled users (etc). This is also an issue with LDAP Identity in read-only mode. ===================== In short there are two issues: 1. The default caching in keystonemiddleware produces a sub-optimial experience with cached tokens. 2. The provider validation line should be improved to assert enabled, or at the very least provide an API to indicate a change in state including disabling identity resources. Assignment resources are currently assumed to be managed by keystone (there is no read-only mode) and therefore it is expected that the Keystone API is used to disable the tenant/project (and therefore the revocation event would occur). This means that assert enabled should only need to occur on the user in the case of live-validated tokens.