)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"b477329c015bbf8d64f1822d438b4974036e3206","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"948bfa89_43211fd8","updated":"2026-09-14 15:34:06.000000000","message":"If OAuth2-mTLS rescope was never reported as a bug, then the previous behavior, a project-scoped token that can rescope like any other, was the accepted, intended behavior. This isn\u0027t closing a filed vulnerability — OAuth2-mTLS rescope was never reported. We\u0027re changing the behavior of a shipped feature (RFC 8705 mTLS tokens could rescope, by design) based on a new internal classification. If we believe it should be delegated, that\u0027s a design change to the OAuth2-mTLS feature, and it deserves its own justification and a deprecation path — not a drive-by _ALWAYS_DELEGATED + 503 that breaks operators who currently rely on the existing behavior.","commit_id":"4ed0d9504630af61dd4e66956172452e604dfad0"}],"keystone/api/_shared/delegation.py":[{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"d0880101302630e8688fb2010f77f7f6b429c4b3","unresolved":true,"context_lines":[{"line_number":51,"context_line":"# reclassifying one as primary would silently re-open the rescope path"},{"line_number":52,"context_line":"# the guards block."},{"line_number":53,"context_line":"_ALWAYS_DELEGATED_AUTH_METHODS \u003d frozenset("},{"line_number":54,"context_line":"    {\u0027ec2credential\u0027, \u0027oauth2_credential\u0027}"},{"line_number":55,"context_line":")"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"49a9838c_d783714f","line":54,"updated":"2026-09-11 15:38:17.000000000","message":"I don\u0027t think designating oauth2_credential as _always_ delegated is correct. I don\u0027t know much about this auth method, I wonder if it could be used in horizon and how the project switcher would work in that case.\n\nWe could still make it delegated by default, since we won\u0027t be able to backport this patch anyway (because it breaks custom configs).","commit_id":"d40512828923657edb2689399d5a9de3a3f5f5b2"},{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"bdf84ea664ce21c6e5ef19ea4b5a64c4b2b4b9bc","unresolved":true,"context_lines":[{"line_number":51,"context_line":"# reclassifying one as primary would silently re-open the rescope path"},{"line_number":52,"context_line":"# the guards block."},{"line_number":53,"context_line":"_ALWAYS_DELEGATED_AUTH_METHODS \u003d frozenset("},{"line_number":54,"context_line":"    {\u0027ec2credential\u0027, \u0027oauth2_credential\u0027}"},{"line_number":55,"context_line":")"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"d58f19c3_3382869d","line":54,"in_reply_to":"027da50c_fd04204f","updated":"2026-09-14 10:06:59.000000000","message":"My suggestion is that whatever the use case, it should be configurable, to not break the previous behavior, or at least provide a config to set it as primary. If not, we have to first add a deprecation notice and wait a cycle to make a breaking change like that.","commit_id":"d40512828923657edb2689399d5a9de3a3f5f5b2"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"ac9cd7c7ce2af585fe514cbbc00cc9a974fde267","unresolved":true,"context_lines":[{"line_number":51,"context_line":"# reclassifying one as primary would silently re-open the rescope path"},{"line_number":52,"context_line":"# the guards block."},{"line_number":53,"context_line":"_ALWAYS_DELEGATED_AUTH_METHODS \u003d frozenset("},{"line_number":54,"context_line":"    {\u0027ec2credential\u0027, \u0027oauth2_credential\u0027}"},{"line_number":55,"context_line":")"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"027da50c_fd04204f","line":54,"in_reply_to":"49a9838c_d783714f","updated":"2026-09-11 18:01:07.000000000","message":"what is your suggestion then? oauth2_credential should not be really usable from horizon as of now so I would not bother about that now","commit_id":"d40512828923657edb2689399d5a9de3a3f5f5b2"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"95d4afc7b3334b7ef2ed3f3ccd8475125a1c28af","unresolved":true,"context_lines":[{"line_number":51,"context_line":"# reclassifying one as primary would silently re-open the rescope path"},{"line_number":52,"context_line":"# the guards block."},{"line_number":53,"context_line":"_ALWAYS_DELEGATED_AUTH_METHODS \u003d frozenset("},{"line_number":54,"context_line":"    {\u0027ec2credential\u0027, \u0027oauth2_credential\u0027}"},{"line_number":55,"context_line":")"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"df7867dc_de5fa102","line":54,"in_reply_to":"d58f19c3_3382869d","updated":"2026-09-14 12:22:58.000000000","message":"after further analysis I tend to disagree with you - what we were doing in past CVEs was to try to prevent ec2 and oauth2 logins from rescoping. \n1. It\u0027s a marker, not an authentication. The plugin can\u0027t authenticate (always 401). Classifying it \"primary\" would be a lie about what the token proves: a bearer credential for OpenStack service APIs, minted from an mTLS client-credential exchange — same lineage as EC2/S3/OAuth1 tokens, which is the LP#2153453 precedent this follows.\n2. Reclassification would be strictly worse, not more permissive. Even if an operator forced it into additional_primary_auth_methods, the auth_context guard (auth_context.py:462) checks the marker name, not the delegation class — so the token would still be rejected from authorizing Keystone requests. All they\u0027d gain is passing the is_delegated_method guards at token.py:94 / trusts / app-cred / OAuth1: a token that can mint trusts and rescope itself but can\u0027t even make Keystone API calls. That\u0027s an incoherent, dangerous state, so primary_auth_methods() subtracts _ALWAYS_DELEGATED_AUTH_METHODS (delegation.py:70) to make the knob a no-op.\n3. Deny-by-default is the design. delegation.py:25-32 treats \"not on the reviewed primary allowlist\" as delegated on purpose. oauth2_credential was never reviewed as a primary method, so it stays out until someone deliberately reviews it as one.\nThe legitimate way for an operator to get Keystone API access with OAuth2-adjacent credentials is a different flow (client_secret_basic → application credential, or user/password), not reclassifying the marker.","commit_id":"d40512828923657edb2689399d5a9de3a3f5f5b2"},{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"c10098014f11897995f7c2fbdf25252ad3b189c4","unresolved":true,"context_lines":[{"line_number":51,"context_line":"# reclassifying one as primary would silently re-open the rescope path"},{"line_number":52,"context_line":"# the guards block."},{"line_number":53,"context_line":"_ALWAYS_DELEGATED_AUTH_METHODS \u003d frozenset("},{"line_number":54,"context_line":"    {\u0027ec2credential\u0027, \u0027oauth2_credential\u0027}"},{"line_number":55,"context_line":")"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"e961092b_e88961f2","line":54,"in_reply_to":"df7867dc_de5fa102","updated":"2026-09-14 14:58:49.000000000","message":"What I\u0027ve found out digging into this:\n\nThe oauth2 mtls certificate doesn\u0027t have a verbatim project scope, but in practice, the resulting token which you get by exchanging the cert is always scoped to the default project.\n\nSo the only way, for a user logging with mtls before this release was to exchange that token (using keystone token API) for a token scoped to another project.\n\nWhat happened with our introduction of \"delegated\" type in the current release, is that we blocked this, since it is currently resolving to an empty list.\n\nThis patch, as currently written, doesn\u0027t change that behavior we just introduced, which is why Qwen on your end is so persistent, that it should stay a \"delegated\" token.\n\nBut the real situation is, that we introduced this breaking behavior in this release, and what I\u0027m arguing for now, is that we should make it possible to configure it as a \"primary\" token.\n\nI\u0027m ok with breaking the default behavior, but we should permit it to be designated as primary in the configuration, since without it, the oauth2 mtl auth method may become useless in some applications. That is because you wouldn\u0027t be able to change the users project from their default one.\n\nTLDR: The original implementation doesn\u0027t specify that the mtls certificate is scoped to a project, the scoping to a default project is just the default behavior, and in the past you were always able to change it by exchanging the token. So in previous releases it was always \"primary\".","commit_id":"d40512828923657edb2689399d5a9de3a3f5f5b2"}]}
