I did a little testing of the cinder patch with a local devstack, looking for any way I could delete the cinder attachment without going through nova. Unfortunately I found it appears I can bypass the redirect by sending the X-Service-Token header with my regular token. So it looks like we need to do a little more to validate whether it's nova calling. Not sure if we can maybe pull nova's user_id from keystone and then verify that as well or instead? Or maybe there is some other better way? (later) Update: I dug around and found out why it's possible to easily fake a service token and it's because [keystone_authtoken] option "service_token_roles_required" defaults to False since Ocata [1] and remains so today: """ Upgrade Notes Set the service_token_roles to a list of roles that services may have. The likely list is service or admin. Any service_token_roles may apply to accept the service token. Ensure service users have one of these roles so interservice communication continues to work correctly. When verified, set the service_token_roles_required flag to True to enforce this behaviour. This will become the default setting in future releases. """ By default any authenticated user can send their valid token as a "X-Service-Token" and keystone will accept it as a valid service token. If I however set in cinder.conf: [keystone_authtoken] service_token_roles_required = True My below repro attempt will be rejected with: {"error": {"code": 401, "title": "Unauthorized", "message": "The request you have made requires authentication."}} So either way we need a different way to verify whether it is nova calling DELETE /attachments/{attachment_id}. [1] https://docs.openstack.org/releasenotes/keystonemiddleware/ocata.html#new-features Repro steps: Show that user "demo" does not have any service roles: $ source openrc admin admin $ openstack user list -f json [ { "ID": "a34218d9c4774df18a713ee8718eded7", "Name": "demo" } ] $ openstack role assignment list --user a34218d9c4774df18a713ee8718eded7 --name -f json [ { "Role": "member", "User": "demo@Default", "Group": "", "Project": "invisible_to_admin@Default", "Domain": "", "System": "", "Inherited": false }, { "Role": "anotherrole", "User": "demo@Default", "Group": "", "Project": "demo@Default", "Domain": "", "System": "", "Inherited": false }, { "Role": "creator", "User": "demo@Default", "Group": "", "Project": "demo@Default", "Domain": "", "System": "", "Inherited": false }, { "Role": "member", "User": "demo@Default", "Group": "", "Project": "demo@Default", "Domain": "", "System": "", "Inherited": false } ] Begin repro: $ source openrc demo demo $ openstack volume create --size 1 test2004555 -f json { "attachments": [], "availability_zone": "nova", "bootable": "false", "consistencygroup_id": null, "created_at": "2023-03-16T23:22:16.147130", "description": null, "encrypted": false, "id": "d66c2b17-a1ac-4bc8-a543-c36a829a9b7b", "multiattach": false, "name": "test2004555", "properties": {}, "replication_status": null, "size": 1, "snapshot_id": null, "source_volid": null, "status": "creating", "type": "lvmdriver-1", "updated_at": null, "user_id": "a34218d9c4774df18a713ee8718eded7" } $ openstack server add volume testswap0 test2004555 { "ID": "d66c2b17-a1ac-4bc8-a543-c36a829a9b7b", "Server ID": "eac7e045-629c-4ee0-b01f-972b33b0b599", "Volume ID": "d66c2b17-a1ac-4bc8-a543-c36a829a9b7b", "Device": "/dev/vde", "Tag": null, "Delete On Termination": false } $ openstack --os-volume-api-version 3.27 volume attachment list -f json [ { "ID": "c02250bd-0f32-4ef4-b751-72e129a12842", "Volume ID": "d66c2b17-a1ac-4bc8-a543-c36a829a9b7b", "Server ID": "eac7e045-629c-4ee0-b01f-972b33b0b599", "Status": "attached" } ] $ openstack token issue -f json { "expires": "2023-03-17T00:24:30+0000", "id": "", "project_id": "a7f89c260bfd4dd5b3ffa7c70477f91f", "user_id": "a34218d9c4774df18a713ee8718eded7" } $ curl -g -i -X DELETE http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/c02250bd-0f32-4ef4-b751-72e129a12842 -H "Accept: application/json" -H "OpenStack-API-Version: volume 3.27" -H "User-Agent: python-cinderclient" -H "X-Auth-Token: " -H "X-Service-Token: " HTTP/1.1 200 OK Date: Thu, 16 Mar 2023 23:26:23 GMT Server: Apache/2.4.41 (Ubuntu) Content-Type: application/json x-compute-request-id: req-be08e60e-b306-47a8-bb46-c360c759f98d Content-Length: 19 OpenStack-API-Version: volume 3.27 Vary: OpenStack-API-Version x-openstack-request-id: req-be08e60e-b306-47a8-bb46-c360c759f98d Connection: close Check the c-api log: INFO cinder.api.openstack.wsgi [None req-be08e60e-b306-47a8-bb46-c360c759f98d demo demo] DELETE http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/c02250bd-0f32-4ef4-b751-72e129a12842 INFO cinder.api.openstack.wsgi [None req-be08e60e-b306-47a8-bb46-c360c759f98d demo demo] http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/c02250bd-0f32-4ef4-b751-72e129a12842 returned with HTTP 200 [pid: 322179|app: 0|req: 45/125] 192.168.44.11 () {56 vars in 1507 bytes} [Thu Mar 16 23:26:23 2023] DELETE /volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/c02250bd-0f32-4ef4-b751-72e129a12842 => generated 19 bytes in 4837 msecs (HTTP/1.1 200) 7 headers in 285 bytes (1 switches on core 0) Contrasting with a attachment delete request that gets redirected to nova: INFO cinder.api.openstack.wsgi [None req-ba178fe2-5d6f-4478-b861-fff5fd8306cf demo demo] DELETE http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/581a4d93-bee6-4613-8337-af660a53c9d2 /usr/local/lib/python3.8/dist-packages/oslo_context/context.py:100: DeprecationWarning: Policy enforcement is depending on the value of is_admin. This key is deprecated. Please update your policy file to use the standard policy values. warnings.warn('Policy enforcement is depending on the value of ' INFO cinder.volume.api [None req-ba178fe2-5d6f-4478-b861-fff5fd8306cf demo demo] Attachment connected to vm eac7e045-629c-4ee0-b01f-972b33b0b599, checking data on nova INFO cinder.volume.api [None req-ba178fe2-5d6f-4478-b861-fff5fd8306cf demo demo] Redirecting delete attachment 581a4d93-bee6-4613-8337-af660a53c9d2 request to nova as a volume e9e306b0-5136-437a-b86c-36a0d83b0978 detach action on instance eac7e045-629c-4ee0-b01f-972b33b0b599 to prevent leftover devices on compute node INFO cinder.api.openstack.wsgi [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-a12c3854-a8c3-4a93-8c29-d206d9de9551 demo demo] GET http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978 /usr/local/lib/python3.8/dist-packages/oslo_context/context.py:100: DeprecationWarning: Policy enforcement is depending on the value of is_admin. This key is deprecated. Please update your policy file to use the standard policy values. warnings.warn('Policy enforcement is depending on the value of ' INFO cinder.volume.api [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-a12c3854-a8c3-4a93-8c29-d206d9de9551 demo demo] Volume info retrieved successfully. INFO cinder.api.openstack.wsgi [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-a12c3854-a8c3-4a93-8c29-d206d9de9551 demo demo] http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978 returned with HTTP 200 [pid: 322180|app: 0|req: 20/62] 192.168.44.11 () {60 vars in 1609 bytes} [Thu Mar 16 18:58:11 2023] GET /volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978 => generated 1174 bytes in 117 msecs (HTTP/1.1 200) 7 headers in 286 bytes (1 switches on core 0) INFO cinder.api.openstack.wsgi [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-3f51508a-298c-4083-83da-cee13bf7c235 demo demo] POST http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978/action /usr/local/lib/python3.8/dist-packages/oslo_context/context.py:100: DeprecationWarning: Policy enforcement is depending on the value of is_admin. This key is deprecated. Please update your policy file to use the standard policy values. warnings.warn('Policy enforcement is depending on the value of ' INFO cinder.volume.api [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-3f51508a-298c-4083-83da-cee13bf7c235 demo demo] Volume info retrieved successfully. INFO cinder.volume.api [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-3f51508a-298c-4083-83da-cee13bf7c235 demo demo] Begin detaching volume completed successfully. INFO cinder.api.openstack.wsgi [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-3f51508a-298c-4083-83da-cee13bf7c235 demo demo] http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978/action returned with HTTP 202 [pid: 322179|app: 0|req: 24/63] 192.168.44.11 () {64 vars in 1683 bytes} [Thu Mar 16 18:58:11 2023] POST /volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978/action => generated 0 bytes in 51 msecs (HTTP/1.1 202) 7 headers in 289 bytes (1 switches on core 0) INFO cinder.api.openstack.wsgi [None req-abcd2e88-ff81-4149-bbdd-bb32de6f1fed None None] GET http://192.168.44.11/volume// INFO cinder.api.openstack.wsgi [None req-abcd2e88-ff81-4149-bbdd-bb32de6f1fed None None] http://192.168.44.11/volume// returned with HTTP 300 [pid: 322180|app: 0|req: 21/64] 192.168.44.11 () {58 vars in 1337 bytes} [Thu Mar 16 18:58:11 2023] GET /volume/ => generated 388 bytes in 6 msecs (HTTP/1.1 300) 7 headers in 299 bytes (1 switches on core 0) INFO cinder.api.openstack.wsgi [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-fef87ef1-9cd9-451d-b607-ec5d86e04b4d demo demo] GET http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978 /usr/local/lib/python3.8/dist-packages/oslo_context/context.py:100: DeprecationWarning: Policy enforcement is depending on the value of is_admin. This key is deprecated. Please update your policy file to use the standard policy values. warnings.warn('Policy enforcement is depending on the value of ' INFO cinder.volume.api [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-fef87ef1-9cd9-451d-b607-ec5d86e04b4d demo demo] Volume info retrieved successfully. INFO cinder.api.openstack.wsgi [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-fef87ef1-9cd9-451d-b607-ec5d86e04b4d demo demo] http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978 returned with HTTP 200 [pid: 322179|app: 0|req: 25/65] 192.168.44.11 () {62 vars in 1650 bytes} [Thu Mar 16 18:58:11 2023] GET /volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/volumes/e9e306b0-5136-437a-b86c-36a0d83b0978 => generated 1276 bytes in 163 msecs (HTTP/1.1 200) 7 headers in 287 bytes (1 switches on core 0) INFO cinder.api.openstack.wsgi [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-70634663-c3fc-4da9-aec3-0cf7fc89dd1f demo demo] DELETE http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/581a4d93-bee6-4613-8337-af660a53c9d2 /usr/local/lib/python3.8/dist-packages/oslo_context/context.py:100: DeprecationWarning: Policy enforcement is depending on the value of is_admin. This key is deprecated. Please update your policy file to use the standard policy values. warnings.warn('Policy enforcement is depending on the value of ' INFO cinder.api.openstack.wsgi [req-ba178fe2-5d6f-4478-b861-fff5fd8306cf req-70634663-c3fc-4da9-aec3-0cf7fc89dd1f demo demo] http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/581a4d93-bee6-4613-8337-af660a53c9d2 returned with HTTP 200 [pid: 322180|app: 0|req: 22/66] 192.168.44.11 () {64 vars in 1684 bytes} [Thu Mar 16 18:58:13 2023] DELETE /volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/581a4d93-bee6-4613-8337-af660a53c9d2 => generated 19 bytes in 4899 msecs (HTTP/1.1 200) 7 headers in 285 bytes (1 switches on core 0) INFO cinder.api.openstack.wsgi [None req-ba178fe2-5d6f-4478-b861-fff5fd8306cf demo demo] http://192.168.44.11/volume/v3/a7f89c260bfd4dd5b3ffa7c70477f91f/attachments/581a4d93-bee6-4613-8337-af660a53c9d2 returned with HTTP 200