)]}'
{"id":"openstack%2Fkeystone~997402","triplet_id":"openstack%2Fkeystone~master~I9d7ad5df997dab49e5dabcac72c36a3345a97345","project":"openstack/keystone","branch":"master","attention_set":{"14250":{"account":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"last_update":"2026-07-21 10:01:05.000000000","reason":"Someone else replied on the change"}},"removed_from_attention_set":{},"hashtags":[],"change_id":"I9d7ad5df997dab49e5dabcac72c36a3345a97345","subject":"Fix token chain revocation and add user-scoped revocation API","status":"NEW","created":"2026-07-15 14:29:07.000000000","updated":"2026-07-21 10:01:05.000000000","submit_type":"MERGE_IF_NECESSARY","mergeable":true,"submittable":false,"total_comment_count":0,"unresolved_comment_count":0,"has_review_started":true,"meta_rev_id":"1d802d1e25209b7b8b1a7d1a3e7a21205933df9f","_number":997402,"virtual_id_number":997402,"owner":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"actions":{},"labels":{"Verified":{"recommended":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"all":[{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},{"tag":"autogenerated:zuul:check","value":1,"date":"2026-07-17 09:08:26.000000000","permitted_voting_range":{"min":-2,"max":2},"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}],"values":{"-2":"Fails","-1":"Doesn\u0027t seem to work"," 0":"No score","+1":"Works for me","+2":"Verified"},"description":"","value":1,"default_value":0,"optional":true},"Code-Review":{"approved":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"all":[{"value":2,"date":"2026-07-21 10:01:05.000000000","permitted_voting_range":{"min":-2,"max":2},"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}],"values":{"-2":"Do not merge","-1":"This patch needs further work before it can be merged"," 0":"No score","+1":"Looks good to me, but someone else must approve","+2":"Looks good to me (core reviewer)"},"description":"","default_value":0,"optional":true},"Workflow":{"all":[{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}],"values":{"-1":"Work in progress"," 0":"Ready for reviews","+1":"Approved"},"description":"","default_value":0,"optional":true}},"removable_reviewers":[],"reviewers":{"REVIEWER":[{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"}]},"pending_reviewers":{},"reviewer_updates":[{"updated":"2026-07-15 16:54:55.000000000","updated_by":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"reviewer":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"state":"REVIEWER"},{"updated":"2026-07-21 10:01:05.000000000","updated_by":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"reviewer":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"state":"REVIEWER"}],"messages":[{"id":"8a69380e2f042e8b15c300ad81ffea61e7f2b3d2","tag":"autogenerated:gerrit:newWipPatchSet","author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"date":"2026-07-15 14:29:07.000000000","message":"Uploaded patch set 1.","accounts_in_message":[],"_revision_number":1},{"id":"40bd63dc59c5d83aee694863eb0e95b82f66040e","tag":"autogenerated:gerrit:newWipPatchSet","author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"date":"2026-07-15 15:41:50.000000000","message":"Uploaded patch set 2.","accounts_in_message":[],"_revision_number":2},{"id":"44fba75b1871eee019e6670e817583dd7a33b772","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2026-07-15 16:54:55.000000000","message":"Patch Set 2: Verified-1\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\nand https://docs.openstack.org/project-team-guide/testing.html#how-to-handle-test-failures\n\nhttps://zuul.opendev.org/t/openstack/buildset/e6a7b77ab16246769a80a07cfad3bb1e\n\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/fd145b20c091402dae88764a46118f4c : FAILURE in 17m 29s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/d28bdaa1823049fab9efb8826f14440e : SUCCESS in 5m 41s\n- openstack-tox-py311 https://zuul.opendev.org/t/openstack/build/929110277edb44ae86ba9b0cf1faef3d : FAILURE in 11m 56s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/c3a52348e7e04872a49688d33cf244c7 : FAILURE in 11m 58s\n- openstack-tox-py314 https://zuul.opendev.org/t/openstack/build/4a97104ca18c4fd2a3de0ed84e53e473 : FAILURE in 15m 35s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/74c3f94ac8dd455496dd08a977cb7911 : SUCCESS in 10m 23s\n- grenade https://zuul.opendev.org/t/openstack/build/56b776def17a4634850d5e6460d769ac : SUCCESS in 39m 27s\n- tempest-full-py3 https://zuul.opendev.org/t/openstack/build/5c3277b45d6e4f18a010a9d272db42e0 : SUCCESS in 1h 03m 03s\n- build-openstack-releasenotes https://zuul.opendev.org/t/openstack/build/3726c932b0f44dc2aa18bdf45045d3c3 : SUCCESS in 13m 25s\n- keystoneclient-devstack-functional https://zuul.opendev.org/t/openstack/build/71698355923b4f6e9a6ba02bf3e0e153 : SUCCESS in 20m 21s (non-voting)\n- keystone-tempest https://zuul.opendev.org/t/openstack/build/d39fcbd48b9343ccaaf85060e3de75f3 : SUCCESS in 57m 58s\n- keystone-tempest-fips https://zuul.opendev.org/t/openstack/build/71dd29a7e643471eaba6e9f223e692cf : FAILURE in 22m 17s (non-voting)\n- keystone-tempest-federation https://zuul.opendev.org/t/openstack/build/381f6f41220d49638746cf017daf414c : FAILURE in 27m 17s (non-voting)\n- keystone-tempest-federation-k2k https://zuul.opendev.org/t/openstack/build/18085a81ddb541ae8d2d735a8742cf79 : SUCCESS in 53m 38s\n- keystone-tempest-oidc-federation https://zuul.opendev.org/t/openstack/build/0665b75ef1ce441d95964e70e973d544 : SUCCESS in 50m 48s\n- keystone-tempest-ldap-domain-specific-driver https://zuul.opendev.org/t/openstack/build/52422cdcd8f6471bbf9402b10ab52574 : SUCCESS in 40m 35s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/b3d1602415e34d9db535d5ae57baaac9 : SUCCESS in 36m 47s\n- keystone-protection-functional https://zuul.opendev.org/t/openstack/build/53ff50a4cc554b9f96929eaf6026185c : SUCCESS in 42m 28s\n- codegenerator-openapi-identity-tips-with-api-ref https://zuul.opendev.org/t/openstack/build/552f6135372c40909ada5628cd850c22 : SUCCESS in 7m 42s (non-voting)\n\nWarning:\n  File .ssh/known_hosts.old found in build home directory during playbook opendev.org/opendev/base-jobs/playbooks/base/cleanup.yaml for job keystone-tempest-fips.  Add to preserve-home-paths if safe, or otherwise remove.\n  File .ssh/known_hosts.old found in build home directory during playbook opendev.org/opendev/base-jobs/playbooks/base/post-logs.yaml for job keystone-tempest-fips.  Add to preserve-home-paths if safe, or otherwise remove.","accounts_in_message":[],"_revision_number":2},{"id":"4b692f3a263baf459399d4143547549ecf25d505","tag":"autogenerated:zuul:check-arm64","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2026-07-15 18:26:26.000000000","message":"Patch Set 2:\n\nBuild succeeded (ARM64 pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/3d4b18f487574a0cb5039b52417d4b1e\n\n- openstack-tox-py311-arm64 https://zuul.opendev.org/t/openstack/build/a8fd6eb0ad3c409f9039f185cb29a56c : FAILURE in 13m 42s (non-voting)\n- openstack-tox-py313-arm64 https://zuul.opendev.org/t/openstack/build/a61d3967ec2247e1b87fd783cf81b16f : FAILURE in 19m 57s (non-voting)\n- openstack-tox-py314-arm64 https://zuul.opendev.org/t/openstack/build/f5beaff9fd6349019841831ac5ca3a86 : FAILURE in 29m 30s (non-voting)","accounts_in_message":[],"_revision_number":2},{"id":"1e8c9e9e8d348f8edb921b503edf15155513c6f8","tag":"autogenerated:gerrit:newWipPatchSet","author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"date":"2026-07-17 08:06:27.000000000","message":"Uploaded patch set 3.\n\nOutdated Votes:\n* Verified-1 (copy condition: \"NEVER\")\n","accounts_in_message":[],"_revision_number":3},{"id":"39a1d73d79b19479c3ec89fc52e65b139dc9023f","tag":"autogenerated:zuul:check-arm64","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2026-07-17 08:35:07.000000000","message":"Patch Set 3:\n\nBuild succeeded (ARM64 pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/35b0d02377dc4563b6d082cce1a79110\n\n- openstack-tox-py311-arm64 https://zuul.opendev.org/t/openstack/build/cfb9f176790846efb80dcb25ab9ea923 : SUCCESS in 26m 31s (non-voting)\n- openstack-tox-py313-arm64 https://zuul.opendev.org/t/openstack/build/d712d7b8087c42898470aa8b0ba727c5 : SUCCESS in 20m 52s (non-voting)\n- openstack-tox-py314-arm64 https://zuul.opendev.org/t/openstack/build/928b272b2f4e454194a3b29edbfe30e9 : SUCCESS in 18m 46s (non-voting)","accounts_in_message":[],"_revision_number":3},{"id":"ec61551d6bb46c6c46762f65cef8f262522481c8","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2026-07-17 09:08:26.000000000","message":"Patch Set 3: Verified+1\n\nBuild succeeded (check pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/bebaf5cbce864c52ad364baba391ea2b\n\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/8c783c2bd8c241a79a4656b8f1d390af : SUCCESS in 16m 15s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/3f7f8e256c0c41a5b69332365b2385d1 : SUCCESS in 5m 22s\n- openstack-tox-py311 https://zuul.opendev.org/t/openstack/build/29c2ba893a2f46099b73f13d80dc2606 : SUCCESS in 10m 57s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/e4cc035f98c545b59baa1e6a3b19894c : SUCCESS in 13m 32s\n- openstack-tox-py314 https://zuul.opendev.org/t/openstack/build/ec7064536b794c63802f5ff7939a0330 : SUCCESS in 17m 09s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/70edc4b09c244809858d89e572616202 : SUCCESS in 17m 13s\n- grenade https://zuul.opendev.org/t/openstack/build/5ba5c70cc3af41e58449e2809a84fdb6 : SUCCESS in 43m 02s\n- tempest-full-py3 https://zuul.opendev.org/t/openstack/build/eb9ae7bca1fc48dc8a00ec5d6aa4deba : SUCCESS in 1h 00m 27s\n- build-openstack-releasenotes https://zuul.opendev.org/t/openstack/build/917b267b292b440ebb8a4b18409b3fb1 : SUCCESS in 5m 17s\n- keystoneclient-devstack-functional https://zuul.opendev.org/t/openstack/build/2e6dbb2f24154978a759af680507459b : SUCCESS in 19m 01s (non-voting)\n- keystone-tempest https://zuul.opendev.org/t/openstack/build/3464784e70ed48e29d25837b72641d11 : SUCCESS in 51m 49s\n- keystone-tempest-fips https://zuul.opendev.org/t/openstack/build/939e6f42e74d4b59a21beee76420981d : FAILURE in 13m 37s (non-voting)\n- keystone-tempest-federation https://zuul.opendev.org/t/openstack/build/400f2676aa3245308a167d70ec14e657 : FAILURE in 19m 24s (non-voting)\n- keystone-tempest-federation-k2k https://zuul.opendev.org/t/openstack/build/e292a921a7414bd992373333f39d0a13 : SUCCESS in 31m 12s\n- keystone-tempest-oidc-federation https://zuul.opendev.org/t/openstack/build/fbc6ded9b93340f4a287ba33ec97a984 : SUCCESS in 27m 30s\n- keystone-tempest-ldap-domain-specific-driver https://zuul.opendev.org/t/openstack/build/bfbecf16319b405d8b70041404d0da7b : SUCCESS in 27m 05s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/fda64a85ec1247239639bbaaafc607ae : SUCCESS in 36m 43s\n- keystone-protection-functional https://zuul.opendev.org/t/openstack/build/7ed889abc0f6454789c1c6b4c653f65f : SUCCESS in 23m 38s\n- codegenerator-openapi-identity-tips-with-api-ref https://zuul.opendev.org/t/openstack/build/85488d146ffe46fdbde6b0e68a5720b1 : SUCCESS in 7m 18s (non-voting)\n\nWarning:\n  File .ssh/known_hosts.old found in build home directory during playbook opendev.org/opendev/base-jobs/playbooks/base/cleanup.yaml for job keystone-tempest-fips.  Add to preserve-home-paths if safe, or otherwise remove.\n  File .ssh/known_hosts.old found in build home directory during playbook opendev.org/opendev/base-jobs/playbooks/base/post-logs.yaml for job keystone-tempest-fips.  Add to preserve-home-paths if safe, or otherwise remove.","accounts_in_message":[],"_revision_number":3},{"id":"ed04b7270502d815472336cd600ac809a373d563","author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"date":"2026-07-17 10:33:43.000000000","message":"Patch Set 3:\n\nThis change is ready for review.","accounts_in_message":[],"_revision_number":3},{"id":"1d802d1e25209b7b8b1a7d1a3e7a21205933df9f","author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"date":"2026-07-21 10:01:05.000000000","message":"Patch Set 3: Code-Review+2","accounts_in_message":[],"_revision_number":3}],"current_revision_number":3,"current_revision":"0a902c4ca90f58605156f58bfee0bd70a90ee8b7","revisions":{"a1ae62006023a8ef7c49827b38668f299a0c3093":{"kind":"REWORK","_number":1,"created":"2026-07-15 14:29:07.000000000","uploader":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"ref":"refs/changes/02/997402/1","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/keystone","ref":"refs/changes/02/997402/1","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/1 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/1 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/1 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/keystone refs/changes/02/997402/1"}}},"commit":{"parents":[{"commit":"2513d1dca7aa3d2cfcbe373b166c2ad54116047d","subject":"Fix federation user deletion","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/2513d1dca7aa3d2cfcbe373b166c2ad54116047d"}]}],"author":{"name":"Grzegorz Grasza","email":"xek@redhat.com","date":"2026-05-19 08:42:37.000000000","tz":120},"committer":{"name":"Grzegorz Grasza","email":"xek@redhat.com","date":"2026-07-15 14:27:40.000000000","tz":120},"subject":"Fix token chain revocation and add user-scoped revocation API","message":"Fix token chain revocation and add user-scoped revocation API\n\nThree related improvements to token revocation security:\n\n1. Cascade revocation on DELETE /v3/auth/tokens (default: on)\n\n   Revoking a token now also revokes all tokens derived from it via\n   rescoping (the audit chain). This closes the attack where an\n   attacker steals a scoped token, the victim revokes the parent\n   unscoped token, but the child and all grandchildren remain valid\n   indefinitely via repeated rescoping.\n\n   The existing audit_chain_id mechanism already propagates the root\n   ancestor\u0027s audit_id through the chain, so a single additional\n   revoke_by_audit_chain_id() call covers arbitrary depth.\n\n   The chain revocation event is scope-agnostic (no project_id or\n   domain_id filter) so it matches descendant tokens regardless of\n   whether they were rescoped to a different project.\n\n   A new ?cascade\u003dfalse query parameter opts out of chain revocation\n   for callers that need to revoke only the specific token.\n\n2. Add DELETE /v3/users/{user_id}/tokens\n\n   Revokes all tokens for a user by creating a user_id-scoped\n   revocation event and flushing the token validation cache. This\n   provides self-service session invalidation for users who cannot\n   change their Keystone password (LDAP, federated, OIDC users).\n   Previously these users had no way to invalidate their sessions\n   without admin intervention.\n\n   Policy: rule:admin_or_owner (users can revoke their own tokens,\n   admins can revoke any user\u0027s tokens).\n\n3. Persist revocation event when LDAP-disabled user is detected\n\n   When token validation catches a disabled user via the runtime\n   check (used for readonly backends like LDAP where disabling in\n   the directory does not create a Keystone revocation event), now\n   also calls revoke_by_user() to create a durable revocation event.\n   Without this, re-enabling the account in LDAP would silently\n   revive all tokens issued before the account was disabled,\n   including any stolen tokens the attacker holds.\n\nCloses-Bug: #2152573\nChange-Id: I9d7ad5df997dab49e5dabcac72c36a3345a97345\nSigned-off-by: Grzegorz Grasza \u003cxek@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/a1ae62006023a8ef7c49827b38668f299a0c3093"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/a1ae62006023a8ef7c49827b38668f299a0c3093"}]},"branch":"refs/heads/master"},"0034d603deec870269507329229f466c29cda8dc":{"kind":"REWORK","_number":2,"created":"2026-07-15 15:41:50.000000000","uploader":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"ref":"refs/changes/02/997402/2","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/keystone","ref":"refs/changes/02/997402/2","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/2 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/2 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/2 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/keystone refs/changes/02/997402/2"}}},"commit":{"parents":[{"commit":"2513d1dca7aa3d2cfcbe373b166c2ad54116047d","subject":"Fix federation user deletion","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/2513d1dca7aa3d2cfcbe373b166c2ad54116047d"}]}],"author":{"name":"Grzegorz Grasza","email":"xek@redhat.com","date":"2026-05-19 08:42:37.000000000","tz":120},"committer":{"name":"Grzegorz Grasza","email":"xek@redhat.com","date":"2026-07-15 15:39:11.000000000","tz":120},"subject":"Fix token chain revocation and add user-scoped revocation API","message":"Fix token chain revocation and add user-scoped revocation API\n\nThree related improvements to token revocation security:\n\n1. Cascade revocation on DELETE /v3/auth/tokens (default: on)\n\n   Revoking a token now also revokes all tokens derived from it via\n   rescoping (the audit chain). This closes the attack where an\n   attacker steals a scoped token, the victim revokes the parent\n   unscoped token, but the child and all grandchildren remain valid\n   indefinitely via repeated rescoping.\n\n   The existing audit_chain_id mechanism already propagates the root\n   ancestor\u0027s audit_id through the chain, so a single additional\n   revoke_by_audit_chain_id() call covers arbitrary depth.\n\n   The chain revocation event is scope-agnostic (no project_id or\n   domain_id filter) so it matches descendant tokens regardless of\n   whether they were rescoped to a different project.\n\n   A new ?cascade\u003dfalse query parameter opts out of chain revocation\n   for callers that need to revoke only the specific token.\n\n2. Add DELETE /v3/users/{user_id}/tokens\n\n   Revokes all tokens for a user by creating a user_id-scoped\n   revocation event and flushing the token validation cache. This\n   provides self-service session invalidation for users who cannot\n   change their Keystone password (LDAP, federated, OIDC users).\n   Previously these users had no way to invalidate their sessions\n   without admin intervention.\n\n   Policy: rule:admin_or_owner (users can revoke their own tokens,\n   admins can revoke any user\u0027s tokens).\n\n3. Persist revocation event when LDAP-disabled user is detected\n\n   When token validation catches a disabled user via the runtime\n   check (used for readonly backends like LDAP where disabling in\n   the directory does not create a Keystone revocation event), now\n   also calls revoke_by_user() to create a durable revocation event.\n   Without this, re-enabling the account in LDAP would silently\n   revive all tokens issued before the account was disabled,\n   including any stolen tokens the attacker holds.\n\nCloses-Bug: #2152573\nChange-Id: I9d7ad5df997dab49e5dabcac72c36a3345a97345\nSigned-off-by: Grzegorz Grasza \u003cxek@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/0034d603deec870269507329229f466c29cda8dc"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/0034d603deec870269507329229f466c29cda8dc"}]},"branch":"refs/heads/master"},"0a902c4ca90f58605156f58bfee0bd70a90ee8b7":{"kind":"REWORK","_number":3,"created":"2026-07-17 08:06:27.000000000","uploader":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"ref":"refs/changes/02/997402/3","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/keystone","ref":"refs/changes/02/997402/3","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/3 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/3 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/keystone refs/changes/02/997402/3 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/keystone refs/changes/02/997402/3"}}},"commit":{"parents":[{"commit":"2513d1dca7aa3d2cfcbe373b166c2ad54116047d","subject":"Fix federation user deletion","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/2513d1dca7aa3d2cfcbe373b166c2ad54116047d"}]}],"author":{"name":"Grzegorz Grasza","email":"xek@redhat.com","date":"2026-05-19 08:42:37.000000000","tz":120},"committer":{"name":"Grzegorz Grasza","email":"xek@redhat.com","date":"2026-07-17 08:04:26.000000000","tz":120},"subject":"Fix token chain revocation and add user-scoped revocation API","message":"Fix token chain revocation and add user-scoped revocation API\n\nThree related improvements to token revocation security:\n\n1. Cascade revocation on DELETE /v3/auth/tokens (default: on)\n\n   Revoking a token now also revokes all tokens derived from it via\n   rescoping (the audit chain). This closes the attack where an\n   attacker steals a scoped token, the victim revokes the parent\n   unscoped token, but the child and all grandchildren remain valid\n   indefinitely via repeated rescoping.\n\n   The existing audit_chain_id mechanism already propagates the root\n   ancestor\u0027s audit_id through the chain, so a single additional\n   revoke_by_audit_chain_id() call covers arbitrary depth.\n\n   The chain revocation event is scope-agnostic (no project_id or\n   domain_id filter) so it matches descendant tokens regardless of\n   whether they were rescoped to a different project.\n\n   A new ?cascade\u003dfalse query parameter opts out of chain revocation\n   for callers that need to revoke only the specific token.\n\n2. Add DELETE /v3/users/{user_id}/tokens\n\n   Revokes all tokens for a user by creating a user_id-scoped\n   revocation event and flushing the token validation cache. This\n   provides self-service session invalidation for users who cannot\n   change their Keystone password (LDAP, federated, OIDC users).\n   Previously these users had no way to invalidate their sessions\n   without admin intervention.\n\n   Policy: rule:admin_or_owner (users can revoke their own tokens,\n   admins can revoke any user\u0027s tokens).\n\n3. Persist revocation event when LDAP-disabled user is detected\n\n   When token validation catches a disabled user via the runtime\n   check (used for readonly backends like LDAP where disabling in\n   the directory does not create a Keystone revocation event), now\n   also calls revoke_by_user() to create a durable revocation event.\n   Without this, re-enabling the account in LDAP would silently\n   revive all tokens issued before the account was disabled,\n   including any stolen tokens the attacker holds.\n\nCloses-Bug: #2152573\nChange-Id: I9d7ad5df997dab49e5dabcac72c36a3345a97345\nSigned-off-by: Grzegorz Grasza \u003cxek@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/0a902c4ca90f58605156f58bfee0bd70a90ee8b7"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/keystone/commit/0a902c4ca90f58605156f58bfee0bd70a90ee8b7"}]},"branch":"refs/heads/master"}},"requirements":[],"submit_records":[{"rule_name":"gerrit~DefaultSubmitRule","status":"OK","labels":[{"label":"Verified","status":"MAY","applied_by":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}},{"label":"Code-Review","status":"MAY","applied_by":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"}},{"label":"Workflow","status":"MAY"}]}],"submit_requirements":[{"name":"Verified","description":"Verified in gate by CI","status":"UNSATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Verified\u003dMAX AND -label:Verified\u003dMIN","fulfilled":false,"status":"FAIL","passing_atoms":[],"failing_atoms":["label:Verified\u003dMAX","label:Verified\u003dMIN"],"atom_explanations":{"label:Verified\u003dMAX":"","label:Verified\u003dMIN":""}}},{"name":"Code-Review","description":"Code reviewed by core reviewer","status":"SATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Code-Review\u003dMAX AND -label:Code-Review\u003dMIN","fulfilled":true,"status":"PASS","passing_atoms":["label:Code-Review\u003dMAX"],"failing_atoms":["label:Code-Review\u003dMIN"],"atom_explanations":{"label:Code-Review\u003dMAX":"","label:Code-Review\u003dMIN":""}}},{"name":"Workflow","description":"Approved for gate by core reviewer","status":"UNSATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Workflow\u003dMAX AND -label:Workflow\u003dMIN","fulfilled":false,"status":"FAIL","passing_atoms":[],"failing_atoms":["label:Workflow\u003dMAX","label:Workflow\u003dMIN"],"atom_explanations":{"label:Workflow\u003dMAX":"","label:Workflow\u003dMIN":""}}}]}
