)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"cbd0b215_65259205","updated":"2026-09-16 11:45:36.000000000","message":"I know this is WIP but I\u0027ve a few comments regardless","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"}],"keystoneauth1/identity/v3/external_oauth2.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import abc"},{"line_number":20,"context_line":"import time"},{"line_number":21,"context_line":"import typing as ty"},{"line_number":22,"context_line":"import uuid"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"import jwt"}],"source_content_type":"text/x-python","patch_set":7,"id":"27e97f77_46b5d7c9","line":21,"updated":"2026-09-16 11:45:36.000000000","message":"Let\u0027s import the objects we need directly from `typing`","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class ExternalOAuth2(base.BaseAuth, metaclass\u003dabc.ABCMeta):"},{"line_number":34,"context_line":"    \"\"\"A plugin for authenticating via an external OAuth2.0 \"Authorization server\"."},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    :param string auth_url: keystone authorization endpoint."},{"line_number":37,"context_line":"    :param string token_endpoint: The endpoint for access token API. (Required)"},{"line_number":38,"context_line":"    :param string scope: The scope` that the access token can access. (Required)"},{"line_number":39,"context_line":"    :param string audience: The Audience should be the URL of the Authorization"},{"line_number":40,"context_line":"        Server\u0027s Token Endpoint. The Authorization Server will"},{"line_number":41,"context_line":"        verify that it is an intended audience for the token."},{"line_number":42,"context_line":"    :param string auth_method: The auth_method must use the authentication method"},{"line_number":43,"context_line":"        specified by the Authorization Server."},{"line_number":44,"context_line":"        (Required, default: \u0027client_secret_basic\u0027)"},{"line_number":45,"context_line":"    :param string client_id: The OAuth 2.0 Client Identifier valid at the"},{"line_number":46,"context_line":"        Authorization Server. (Required)"},{"line_number":47,"context_line":"    :param string client_secret: The OAuth 2.0 client secret. When the auth_method is"},{"line_number":48,"context_line":"        client_secret_basic, client_secret_post, or client_secret_jwt, the value is"},{"line_number":49,"context_line":"        used, and otherwise the value is ignored."},{"line_number":50,"context_line":"    :param string jwt_key_file: The jwt_key_file must use the certificate key file"},{"line_number":51,"context_line":"        which has been registered with the Authorization Server. When the auth_method"},{"line_number":52,"context_line":"        is private_key_jwt, the value is used, and otherwise the value is ignored."},{"line_number":53,"context_line":"    :param string jwt_algorithm: The jwt_algorithm must use the algorithm specified"},{"line_number":54,"context_line":"        by the Authorization Server. When the auth_method is client_secret_jwt,"},{"line_number":55,"context_line":"        this value is often set to HS256. When the auth_method is private_key_jwt,"},{"line_number":56,"context_line":"        the value is often set to RS256, and otherwise the value is ignored."},{"line_number":57,"context_line":"    :param integer jwt_bearer_time_out: This value is used to calculate the"},{"line_number":58,"context_line":"        expiration time. If after the expiration time, the access token cannot be"},{"line_number":59,"context_line":"        accepted. When the auth_method is client_secret_jwt or private_key_jwt, the"},{"line_number":60,"context_line":"        value is used, and otherwise the value is ignored. (Default: 3600)"},{"line_number":61,"context_line":"    \"\"\""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    def __init__("}],"source_content_type":"text/x-python","patch_set":7,"id":"636384a8_a6107b6a","line":60,"range":{"start_line":35,"start_character":1,"end_line":60,"end_character":74},"updated":"2026-09-16 11:45:36.000000000","message":"Can you remove the type information from this docstring?\n\n\n\n```suggestion\n\n    :param auth_url: keystone authorization endpoint.\n    :param token_endpoint: The endpoint for access token API. (Required)\n    :param scope: The scope` that the access token can access. (Required)\n    :param audience: The Audience should be the URL of the Authorization\n        Server\u0027s Token Endpoint. The Authorization Server will\n        verify that it is an intended audience for the token.\n    :param auth_method: The auth_method must use the authentication method\n        specified by the Authorization Server.\n        (Required, default: \u0027client_secret_basic\u0027)\n    :param client_id: The OAuth 2.0 Client Identifier valid at the\n        Authorization Server. (Required)\n    :param client_secret: The OAuth 2.0 client secret. When the auth_method is\n        client_secret_basic, client_secret_post, or client_secret_jwt, the value is\n        used, and otherwise the value is ignored.\n    :param jwt_key_file: The jwt_key_file must use the certificate key file\n        which has been registered with the Authorization Server. When the auth_method\n        is private_key_jwt, the value is used, and otherwise the value is ignored.\n    :param jwt_algorithm: The jwt_algorithm must use the algorithm specified\n        by the Authorization Server. When the auth_method is client_secret_jwt,\n        this value is often set to HS256. When the auth_method is private_key_jwt,\n        the value is often set to RS256, and otherwise the value is ignored.\n    :param jwt_bearer_time_out: This value is used to calculate the\n        expiration time. If after the expiration time, the access token cannot be\n        accepted. When the auth_method is client_secret_jwt or private_key_jwt, the\n        value is used, and otherwise the value is ignored. (Default: 3600)\n```","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":70,"context_line":"        client_secret: str,"},{"line_number":71,"context_line":"        jwt_key_file: str,"},{"line_number":72,"context_line":"        jwt_algorithm: str,"},{"line_number":73,"context_line":"        auth_method: str \u003d \u0027client_secret_basic\u0027,"},{"line_number":74,"context_line":"        jwt_bearer_time_out: int \u003d 3600,"},{"line_number":75,"context_line":"        *,"},{"line_number":76,"context_line":"        trust_id: ty.Optional[str] \u003d None,"}],"source_content_type":"text/x-python","patch_set":7,"id":"d18d315b_bc8d462b","line":73,"updated":"2026-09-16 11:45:36.000000000","message":"Can we use a `Literal` here? There are only 5 potential options here, right?","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":72,"context_line":"        jwt_algorithm: str,"},{"line_number":73,"context_line":"        auth_method: str \u003d \u0027client_secret_basic\u0027,"},{"line_number":74,"context_line":"        jwt_bearer_time_out: int \u003d 3600,"},{"line_number":75,"context_line":"        *,"},{"line_number":76,"context_line":"        trust_id: ty.Optional[str] \u003d None,"},{"line_number":77,"context_line":"        system_scope: ty.Optional[str] \u003d None,"},{"line_number":78,"context_line":"        domain_id: ty.Optional[str] \u003d None,"},{"line_number":79,"context_line":"        domain_name: ty.Optional[str] \u003d None,"},{"line_number":80,"context_line":"        project_id: ty.Optional[str] \u003d None,"},{"line_number":81,"context_line":"        project_name: ty.Optional[str] \u003d None,"},{"line_number":82,"context_line":"        project_domain_id: ty.Optional[str] \u003d None,"},{"line_number":83,"context_line":"        project_domain_name: ty.Optional[str] \u003d None,"},{"line_number":84,"context_line":"        reauthenticate: bool \u003d True,"},{"line_number":85,"context_line":"        include_catalog: bool \u003d True,"},{"line_number":86,"context_line":"    ):"}],"source_content_type":"text/x-python","patch_set":7,"id":"490cef58_b04ca4a2","line":83,"range":{"start_line":75,"start_character":10,"end_line":83,"end_character":53},"updated":"2026-09-16 11:45:36.000000000","message":"Let\u0027s avoid using `Optional`\n\n```suggestion\n        *,\n        trust_id: str | None \u003d None,\n        system_scope: str | None \u003d None,\n        domain_id: str | None \u003d None,\n        domain_name: str | None \u003d None,\n        project_id: str | None \u003d None,\n        project_name: str | None \u003d None,\n        project_domain_id: str | None \u003d None,\n        project_domain_name: str | None \u003d None,\n```","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":135,"context_line":"        :rtype: :class:`keystoneauth1.access.AccessInfo`"},{"line_number":136,"context_line":"        \"\"\""},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        try:"},{"line_number":139,"context_line":"            if self.auth_method \u003d\u003d \u0027tls_client_auth\u0027:"},{"line_number":140,"context_line":"                http_response \u003d self._get_token_by_tls_client_auth(session)"},{"line_number":141,"context_line":"            elif self.auth_method \u003d\u003d \u0027client_secret_post\u0027:"},{"line_number":142,"context_line":"                http_response \u003d self._get_token_by_client_secret_post(session)"},{"line_number":143,"context_line":"            elif self.auth_method \u003d\u003d \u0027client_secret_basic\u0027:"},{"line_number":144,"context_line":"                http_response \u003d self._get_token_by_client_secret_basic(session)"},{"line_number":145,"context_line":"            elif self.auth_method \u003d\u003d \u0027private_key_jwt\u0027:"},{"line_number":146,"context_line":"                http_response \u003d self._get_token_by_private_key_jwt(session)"},{"line_number":147,"context_line":"            elif self.auth_method \u003d\u003d \u0027client_secret_jwt\u0027:"},{"line_number":148,"context_line":"                http_response \u003d self._get_token_by_client_secret_jwt(session)"},{"line_number":149,"context_line":"            else:"},{"line_number":150,"context_line":"                raise exceptions.ClientException("},{"line_number":151,"context_line":"                    \u0027Provided auth_method is not supported.\u0027"},{"line_number":152,"context_line":"                )"},{"line_number":153,"context_line":"            if http_response.status_code !\u003d 200:"},{"line_number":154,"context_line":"                msg \u003d http_response.json().get(\u0027error_description\u0027)"},{"line_number":155,"context_line":"                raise exceptions.ClientException(msg)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"            access_token \u003d http_response.json().get(\u0027access_token\u0027)"},{"line_number":158,"context_line":"            if not access_token:"},{"line_number":159,"context_line":"                raise exceptions.ClientException("},{"line_number":160,"context_line":"                    \u0027Failed to get an access token.\u0027"},{"line_number":161,"context_line":"                )"},{"line_number":162,"context_line":"            self.access_token \u003d access_token"},{"line_number":163,"context_line":"        except ("},{"line_number":164,"context_line":"            exceptions.ConnectFailure,"},{"line_number":165,"context_line":"            exceptions.DiscoveryFailure,"},{"line_number":166,"context_line":"            exceptions.RequestTimeout,"},{"line_number":167,"context_line":"        ):"},{"line_number":168,"context_line":"            raise exceptions.ClientException("},{"line_number":169,"context_line":"                \u0027The OAuth2.0 access token API service is \u0027"},{"line_number":170,"context_line":"                \u0027temporarily unavailable.\u0027"},{"line_number":171,"context_line":"            )"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"        headers \u003d {"},{"line_number":174,"context_line":"            \u0027Accept\u0027: \u0027application/json\u0027,"}],"source_content_type":"text/x-python","patch_set":7,"id":"d4dc6ad6_2cd4d2ab","line":171,"range":{"start_line":138,"start_character":0,"end_line":171,"end_character":13},"updated":"2026-09-16 11:45:36.000000000","message":"Can we split this block up somewhat?\n\n\n\n```suggestion\n        try:\n            if self.auth_method \u003d\u003d \u0027tls_client_auth\u0027:\n                http_response \u003d self._get_token_by_tls_client_auth(session)\n            elif self.auth_method \u003d\u003d \u0027client_secret_post\u0027:\n                http_response \u003d self._get_token_by_client_secret_post(session)\n            elif self.auth_method \u003d\u003d \u0027client_secret_basic\u0027:\n                http_response \u003d self._get_token_by_client_secret_basic(session)\n            elif self.auth_method \u003d\u003d \u0027private_key_jwt\u0027:\n                http_response \u003d self._get_token_by_private_key_jwt(session)\n            elif self.auth_method \u003d\u003d \u0027client_secret_jwt\u0027:\n                http_response \u003d self._get_token_by_client_secret_jwt(session)\n            else:\n                raise exceptions.ClientException(\n                    \u0027Provided auth_method is not supported.\u0027\n                )\n        except (\n            exceptions.ConnectFailure,\n            exceptions.DiscoveryFailure,\n            exceptions.RequestTimeout,\n        ):\n            raise exceptions.ClientException(\n                \u0027The OAuth2.0 access token API service is \u0027\n                \u0027temporarily unavailable.\u0027\n            )\n\n        if http_response.status_code !\u003d 200:\n            msg \u003d http_response.json().get(\u0027error_description\u0027)\n            raise exceptions.ClientException(msg)\n\n        access_token \u003d http_response.json().get(\u0027access_token\u0027)\n        if not access_token:\n            raise exceptions.ClientException(\n                \u0027Failed to get an access token.\u0027\n            )\n        self.access_token \u003d access_token\n```","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":276,"context_line":"            key\u003djwt_key,"},{"line_number":277,"context_line":"            algorithm\u003dalg,"},{"line_number":278,"context_line":"        )"},{"line_number":279,"context_line":"        para \u003d {"},{"line_number":280,"context_line":"            \u0027client_id\u0027: self.client_id,"},{"line_number":281,"context_line":"            \u0027client_assertion_type\u0027: \u0027urn:ietf:params:oauth:client-assertion-type:jwt-bearer\u0027,"},{"line_number":282,"context_line":"            \u0027client_assertion\u0027: client_assertion,"}],"source_content_type":"text/x-python","patch_set":7,"id":"2bdaade6_29ab9f14","line":279,"updated":"2026-09-16 11:45:36.000000000","message":"nit:\n\n```suggestion\n        data \u003d {\n```","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":329,"context_line":""},{"line_number":330,"context_line":"    def get_headers("},{"line_number":331,"context_line":"        self, session: \u0027ks_session.Session\u0027"},{"line_number":332,"context_line":"    ) -\u003e ty.Optional[dict[str, str]]:"},{"line_number":333,"context_line":"        \"\"\"Fetch authentication headers for message."},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"        :param session: The session object that the auth_plugin belongs to."}],"source_content_type":"text/x-python","patch_set":7,"id":"b2f297c1_0fbf5748","line":332,"updated":"2026-09-16 11:45:36.000000000","message":"```suggestion\n    ) -\u003e dict[str, str] | None:\n```","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":331,"context_line":"        self, session: \u0027ks_session.Session\u0027"},{"line_number":332,"context_line":"    ) -\u003e ty.Optional[dict[str, str]]:"},{"line_number":333,"context_line":"        \"\"\"Fetch authentication headers for message."},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"        :param session: The session object that the auth_plugin belongs to."},{"line_number":336,"context_line":"        :type session: keystoneauth1.session.Session"},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"        :returns: Headers that are set to authenticate a message or None for"},{"line_number":339,"context_line":"                  failure. Note that when checking this value that the empty"},{"line_number":340,"context_line":"                  dict is a valid, non-failure response."},{"line_number":341,"context_line":"        :rtype: dict"},{"line_number":342,"context_line":"        \"\"\""},{"line_number":343,"context_line":"        # get headers for X-Auth-Token"},{"line_number":344,"context_line":"        headers \u003d super().get_headers(session)"}],"source_content_type":"text/x-python","patch_set":7,"id":"000290da_f6d1b613","line":341,"range":{"start_line":334,"start_character":1,"end_line":341,"end_character":20},"updated":"2026-09-16 11:45:36.000000000","message":"```suggestion\n\n        :param session: The session object that the auth_plugin belongs to.\n        :returns: Headers that are set to authenticate a message or None for\n            failure. Note that when checking this value that the empty dict is\n            a valid, non-failure response.\n```","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":340,"context_line":"                  dict is a valid, non-failure response."},{"line_number":341,"context_line":"        :rtype: dict"},{"line_number":342,"context_line":"        \"\"\""},{"line_number":343,"context_line":"        # get headers for X-Auth-Token"},{"line_number":344,"context_line":"        headers \u003d super().get_headers(session)"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"        # add OAuth2.0 access token to the headers"},{"line_number":347,"context_line":"        if headers:"},{"line_number":348,"context_line":"            headers[\u0027Authorization\u0027] \u003d f\u0027Bearer {self.access_token}\u0027"},{"line_number":349,"context_line":"        else:"},{"line_number":350,"context_line":"            headers \u003d {\u0027Authorization\u0027: f\u0027Bearer {self.access_token}\u0027}"},{"line_number":351,"context_line":"        return headers"}],"source_content_type":"text/x-python","patch_set":7,"id":"a5076f09_047da57c","line":350,"range":{"start_line":343,"start_character":38,"end_line":350,"end_character":70},"updated":"2026-09-16 11:45:36.000000000","message":"```suggestion\n        # get headers for X-Auth-Token\n        headers \u003d super().get_headers(session) or {}\n\n        # add OAuth2.0 access token to the headers\n        headers[\u0027Authorization\u0027] \u003d f\u0027Bearer {self.access_token}\u0027\n```\n\n?","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"}],"keystoneauth1/loading/_plugins/identity/v3.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":658,"context_line":""},{"line_number":659,"context_line":"    def get_options(self) -\u003e list[opts.Opt]:"},{"line_number":660,"context_line":"        options \u003d super().get_options()"},{"line_number":661,"context_line":"        # NOTE(xek): These options follow the naming in used keystone middleware"},{"line_number":662,"context_line":"        options.extend("},{"line_number":663,"context_line":"            ["},{"line_number":664,"context_line":"                loading.Opt("}],"source_content_type":"text/x-python","patch_set":7,"id":"8ebb67ec_9097a5f7","line":661,"updated":"2026-09-16 11:45:36.000000000","message":"nit:\n\n```suggestion\n        # NOTE(xek): These options follow the naming in used keystonemiddleware\n```","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":669,"context_line":"                loading.Opt("},{"line_number":670,"context_line":"                    \u0027scope\u0027,"},{"line_number":671,"context_line":"                    required\u003dTrue,"},{"line_number":672,"context_line":"                    help\u003d\u0027The scope` that the access token can access.\u0027,"},{"line_number":673,"context_line":"                ),"},{"line_number":674,"context_line":"                loading.Opt("},{"line_number":675,"context_line":"                    \u0027audience\u0027,"}],"source_content_type":"text/x-python","patch_set":7,"id":"d92f7638_b9c3f5aa","line":672,"updated":"2026-09-16 11:45:36.000000000","message":"```suggestion\n                    help\u003d\u0027The scope that the access token can access.\u0027,\n```","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":672,"context_line":"                    help\u003d\u0027The scope` that the access token can access.\u0027,"},{"line_number":673,"context_line":"                ),"},{"line_number":674,"context_line":"                loading.Opt("},{"line_number":675,"context_line":"                    \u0027audience\u0027,"},{"line_number":676,"context_line":"                    help\u003d\u0027The Audience should be the URL of the Authorization \u0027"},{"line_number":677,"context_line":"                    \"Server\u0027s Token Endpoint. The Authorization Server will \""},{"line_number":678,"context_line":"                    \u0027verify that it is an intended audience for the token.\u0027,"},{"line_number":679,"context_line":"                ),"},{"line_number":680,"context_line":"                loading.Opt("},{"line_number":681,"context_line":"                    \u0027auth_method\u0027,"}],"source_content_type":"text/x-python","patch_set":7,"id":"e7e21f14_92e9c339","line":678,"range":{"start_line":675,"start_character":31,"end_line":678,"end_character":76},"updated":"2026-09-16 11:45:36.000000000","message":"nit:\n\n```suggestion\n                    \u0027audience\u0027,\n                    help\u003d(\n                        \"The Audience should be the URL of the Authorization \"\n                        \"Server\u0027s Token Endpoint. The Authorization Server \"\n                        \"will verify that it is an intended audience for the \"\n                        \"token.\"\n                    ),\n```\n\nDitto for the remaining options below.","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":680,"context_line":"                loading.Opt("},{"line_number":681,"context_line":"                    \u0027auth_method\u0027,"},{"line_number":682,"context_line":"                    required\u003dTrue,"},{"line_number":683,"context_line":"                    default\u003d\u0027client_secret_basic\u0027,"},{"line_number":684,"context_line":"                    help\u003d\u0027The auth_method must use the authentication method \u0027"},{"line_number":685,"context_line":"                    \u0027specified by the Authorization Server.\u0027,"},{"line_number":686,"context_line":"                ),"}],"source_content_type":"text/x-python","patch_set":7,"id":"8a602f1b_7099eafa","line":683,"updated":"2026-09-16 11:45:36.000000000","message":"Can we add `choices` here?","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"}],"requirements.txt":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"387ea51b2bb6a4808375c9ac3ec73daaf6f151ea","unresolved":true,"context_lines":[{"line_number":16,"context_line":"stevedore\u003e\u003d5.9.1 # Apache-2.0"},{"line_number":17,"context_line":"os-service-types\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":18,"context_line":"typing-extensions\u003e\u003d4.12 # PSF"},{"line_number":19,"context_line":"PyJWT\u003e\u003d2.4.0 # MIT"}],"source_content_type":"text/plain","patch_set":7,"id":"4ad46cbc_082fae59","line":19,"updated":"2026-09-16 11:45:36.000000000","message":"This should be an optional dependency (like for SAML), surely?","commit_id":"b6e763e2c18d32a0c9d28b8ead7b2fe2991e9a18"}]}
