)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"ea04fdb7fcb3c507432360e359f2064353dcd758","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"d886b8f2_847adc20","updated":"2026-08-19 08:48:10.000000000","message":"So the in-line comments were from AI review, but I believe I would actually run into that first one, since I do actually use different profiles like this in my openstack deployment, so I believe it\u0027s a correct catch. Can you (or your agent) confirm that? 😛","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"}],"openstack/config/cloud_region.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"63af91dc4ded52ee279794e314a5dab484e5ef05","unresolved":false,"context_lines":[{"line_number":813,"context_line":"        \"\"\""},{"line_number":814,"context_line":"        assert self._auth is not None  # narrow type"},{"line_number":815,"context_line":""},{"line_number":816,"context_line":"        cache_id \u003d self._auth.get_unscoped_cache_id()"},{"line_number":817,"context_line":"        if not cache_id:"},{"line_number":818,"context_line":"            return None"},{"line_number":819,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"44691561_fced05e4","line":816,"updated":"2026-08-18 22:12:14.000000000","message":"pep8: error: \"BaseAuthPlugin\" has no attribute \"get_unscoped_cache_id\"  [attr-defined]","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"ea04fdb7fcb3c507432360e359f2064353dcd758","unresolved":true,"context_lines":[{"line_number":819,"context_line":""},{"line_number":820,"context_line":"        # Distinct from the scoped entry, which is keyed on get_cache_id(),"},{"line_number":821,"context_line":"        # and recognisable to anyone looking through their keyring."},{"line_number":822,"context_line":"        return f\u0027unscoped-{cache_id}\u0027"},{"line_number":823,"context_line":""},{"line_number":824,"context_line":"    def _fetch_auth_state(self, cache_id: str) -\u003e str | None:"},{"line_number":825,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"ce082464_22727091","line":822,"updated":"2026-08-19 08:48:10.000000000","message":"The ID returned by keystoneauth describes only the plugin configuration; it cannot include the identity selected in the browser. For example, two clouds.yaml profiles could use the same auth URL/IdP/protocol but be intended for different SSO accounts. If work-admin stores Alice\u0027s unscoped token, work-developer currently derives the same key, loads Alice\u0027s token, and skips its browser login. Scoping may fail, or it may silently connect as Alice if she also has access. Please namespace the key with a stable cloud/profile identity (or an explicit auth-cache namespace) so separate profiles cannot share browser-selected credentials. Using another account through the same profile can reasonably remain that profile\u0027s cache behavior.","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"06ef2dd97c862fbbc889cae3213f37d6cbaafb43","unresolved":true,"context_lines":[{"line_number":819,"context_line":""},{"line_number":820,"context_line":"        # Distinct from the scoped entry, which is keyed on get_cache_id(),"},{"line_number":821,"context_line":"        # and recognisable to anyone looking through their keyring."},{"line_number":822,"context_line":"        return f\u0027unscoped-{cache_id}\u0027"},{"line_number":823,"context_line":""},{"line_number":824,"context_line":"    def _fetch_auth_state(self, cache_id: str) -\u003e str | None:"},{"line_number":825,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"74655708_9001643f","line":822,"in_reply_to":"ce082464_22727091","updated":"2026-08-25 15:20:48.000000000","message":"1000759 already adds an optional username to the WebSSO cache ID, so our immediate WebSSO case is covered when that label is configured. A generic namespace still seems useful here because this code also persists other interactive plugins, notably OIDC authorization-code and device flows, which have no equivalent account label. Combining a per-cloud auth_cache_namespace with the plugin hash would let many project profiles intentionally share one login while allowing different accounts to remain isolated, but I guess it isn\u0027t necessarily a blocker.","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"ea04fdb7fcb3c507432360e359f2064353dcd758","unresolved":true,"context_lines":[{"line_number":845,"context_line":"        # any project, domain or system, so it is worth having even when the"},{"line_number":846,"context_line":"        # scoped token it was previously used for has expired or is for"},{"line_number":847,"context_line":"        # somewhere else entirely."},{"line_number":848,"context_line":"        unscoped_cache_id \u003d self._unscoped_auth_cache_id()"},{"line_number":849,"context_line":"        if unscoped_cache_id:"},{"line_number":850,"context_line":"            unscoped_state \u003d self._fetch_auth_state(unscoped_cache_id)"},{"line_number":851,"context_line":"            if unscoped_state:"}],"source_content_type":"text/x-python","patch_set":1,"id":"17790bf0_751d615f","line":848,"updated":"2026-08-19 08:48:10.000000000","message":"Loading is unconditional even though storage below is restricted to interactive_unscoped_auth. All FederationBaseAuth subclasses currently derive the same ID from auth URL/IdP/protocol. Consequently, an entry stored by WebSSO or OIDC device auth can be loaded into a non-interactive OIDC password plugin with the same triple, causing its configured username/password to be skipped in favor of the cached browser identity. At minimum gate loading on interactive_unscoped_auth; the cache key also needs to distinguish the cloud/account and, where needed, the acquisition plugin.","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"06ef2dd97c862fbbc889cae3213f37d6cbaafb43","unresolved":false,"context_lines":[{"line_number":845,"context_line":"        # any project, domain or system, so it is worth having even when the"},{"line_number":846,"context_line":"        # scoped token it was previously used for has expired or is for"},{"line_number":847,"context_line":"        # somewhere else entirely."},{"line_number":848,"context_line":"        unscoped_cache_id \u003d self._unscoped_auth_cache_id()"},{"line_number":849,"context_line":"        if unscoped_cache_id:"},{"line_number":850,"context_line":"            unscoped_state \u003d self._fetch_auth_state(unscoped_cache_id)"},{"line_number":851,"context_line":"            if unscoped_state:"}],"source_content_type":"text/x-python","patch_set":1,"id":"40f8d8e6_fae5d4c0","line":848,"in_reply_to":"17790bf0_751d615f","updated":"2026-08-25 15:20:48.000000000","message":"Update after checking the dependent implementations: the cross-plugin example above is not accurate anymore. WebSSO adds its optional username to the key, while OIDC password adds its user and client credentials, so those entries do not derive the same ID. The remaining concern is generic partitioning for interactive plugins such as OIDC authorization-code and device flows; please treat this comment as withdrawn.","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"63af91dc4ded52ee279794e314a5dab484e5ef05","unresolved":false,"context_lines":[{"line_number":850,"context_line":"            unscoped_state \u003d self._fetch_auth_state(unscoped_cache_id)"},{"line_number":851,"context_line":"            if unscoped_state:"},{"line_number":852,"context_line":"                self.log.debug(\u0027Reusing unscoped authentication from keyring\u0027)"},{"line_number":853,"context_line":"                self._auth.set_unscoped_auth_state(unscoped_state)"},{"line_number":854,"context_line":""},{"line_number":855,"context_line":"        cache_id \u003d self._auth.get_cache_id()"},{"line_number":856,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"0b20b4de_c906b220","line":853,"updated":"2026-08-18 22:12:14.000000000","message":"pep8: error: \"BaseAuthPlugin\" has no attribute \"set_unscoped_auth_state\"; maybe \"set_auth_state\"?  [attr-defined]","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"63af91dc4ded52ee279794e314a5dab484e5ef05","unresolved":false,"context_lines":[{"line_number":878,"context_line":"        # keeping the credential buys a round trip and costs having a token"},{"line_number":879,"context_line":"        # in the keyring that need not be there at all."},{"line_number":880,"context_line":"        unscoped_cache_id \u003d self._unscoped_auth_cache_id()"},{"line_number":881,"context_line":"        if unscoped_cache_id and self._auth.interactive_unscoped_auth:"},{"line_number":882,"context_line":"            unscoped_state \u003d self._auth.get_unscoped_auth_state()"},{"line_number":883,"context_line":"            if unscoped_state:"},{"line_number":884,"context_line":"                self._store_auth_state(unscoped_cache_id, unscoped_state)"}],"source_content_type":"text/x-python","patch_set":1,"id":"e349b817_f63782a0","line":881,"updated":"2026-08-18 22:12:14.000000000","message":"pep8: error: \"BaseAuthPlugin\" has no attribute \"interactive_unscoped_auth\"  [attr-defined]","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"63af91dc4ded52ee279794e314a5dab484e5ef05","unresolved":false,"context_lines":[{"line_number":879,"context_line":"        # in the keyring that need not be there at all."},{"line_number":880,"context_line":"        unscoped_cache_id \u003d self._unscoped_auth_cache_id()"},{"line_number":881,"context_line":"        if unscoped_cache_id and self._auth.interactive_unscoped_auth:"},{"line_number":882,"context_line":"            unscoped_state \u003d self._auth.get_unscoped_auth_state()"},{"line_number":883,"context_line":"            if unscoped_state:"},{"line_number":884,"context_line":"                self._store_auth_state(unscoped_cache_id, unscoped_state)"},{"line_number":885,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3944a225_c1ec2e4e","line":882,"updated":"2026-08-18 22:12:14.000000000","message":"pep8: error: \"BaseAuthPlugin\" has no attribute \"get_unscoped_auth_state\"; maybe \"get_auth_state\"?  [attr-defined]","commit_id":"92d6e42a368a4a996a9dbe5dfe41763f032cef2b"}]}
