)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"10f157ed8b86255ae3920f4be199e3b09fb76124","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"0451a329_be332565","updated":"2026-05-04 22:23:29.000000000","message":"Hey, this is my proposal for dealing with the issue of application credentials being persisted over upstream IdP changes. This changes the default behavior only for federated users. I\u0027d also like to backport this. I would prefer to backport it as is, but if not, we could backport only the part that let\u0027s you configure these parameters, not the breaking default behavior change.\n\nWhen implementing this, I also looked into having these settings configurable per IdP, but to do it the right way, we would need to extend the database table with the new configuration options, and then maybe we would like to have the same for LDAP... so it\u0027s an overkill.\n\nIn line with our previous discussions, we could further limit the defaults to be more secure, limiting the application credential use also for the local/LDAP users.","commit_id":"d92795d4b8d838575819d1a9ea4dd4e7ba631619"}],"keystone/api/users.py":[{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"58f02a9bdab4d026c990ade8778ab7d49d6c0a64","unresolved":true,"context_lines":[{"line_number":193,"context_line":"        user_type \u003d \u0027federated\u0027"},{"line_number":194,"context_line":"    else:"},{"line_number":195,"context_line":"        _cfg \u003d CONF.application_credential"},{"line_number":196,"context_line":"        enabled \u003d _cfg.enabled"},{"line_number":197,"context_line":"        allow_unrestricted \u003d _cfg.allow_unrestricted"},{"line_number":198,"context_line":"        max_days \u003d _cfg.max_duration_days"},{"line_number":199,"context_line":"        user_type \u003d \u0027local\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"fbed1ab0_804a56ea","line":196,"updated":"2026-06-09 12:23:44.000000000","message":"I think _cfg \u003d CONF.application_credential could be hoisted above the if/else so that only the four branch-specific values differ between the two branches.","commit_id":"6bbf2d629a704ffa75a12eda12333882136d67d1"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"58f02a9bdab4d026c990ade8778ab7d49d6c0a64","unresolved":true,"context_lines":[{"line_number":217,"context_line":"    max_expires \u003d timeutils.utcnow() + max_delta"},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"    if not app_cred_data.get(\u0027expires_at\u0027):"},{"line_number":220,"context_line":"        app_cred_data[\u0027expires_at\u0027] \u003d max_expires.strftime("},{"line_number":221,"context_line":"            \u0027%Y-%m-%dT%H:%M:%S.%f\u0027"},{"line_number":222,"context_line":"        )"},{"line_number":223,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":14,"id":"cdc70cc1_400f3e6c","line":220,"updated":"2026-06-09 12:23:44.000000000","message":"strftime(\u0027%Y-%m-%dT%H:%M:%S.%f\u0027) produces a timestamp with no timezone designator. It works only because utils.parse_expiration_date appends \u0027Z\u0027 downstream. Could you use utils.isotime(max_expires, subsecond\u003dTrue) instead, for consistency with the rest of the codebase (e.g. keystone/token/provider.py).","commit_id":"6bbf2d629a704ffa75a12eda12333882136d67d1"}],"keystone/conf/application_credential.py":[{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"58f02a9bdab4d026c990ade8778ab7d49d6c0a64","unresolved":true,"context_lines":[{"line_number":113,"context_line":"outlive the upstream IdP session lifetime (see LP #2129010). Set to"},{"line_number":114,"context_line":"``True`` to allow federated users to create application credentials;"},{"line_number":115,"context_line":"``federated_max_duration_days`` must also be set to a positive integer"},{"line_number":116,"context_line":"or Keystone will refuse to start."},{"line_number":117,"context_line":"\"\"\""},{"line_number":118,"context_line":"    ),"},{"line_number":119,"context_line":")"}],"source_content_type":"text/x-python","patch_set":14,"id":"69afb796_17f30368","line":116,"updated":"2026-06-09 12:23:44.000000000","message":"The help text says Keystone \"will refuse to start\" if federated_enabled\u003dTrue and federated_max_duration_days\u003d0, but no such validation exists in this patch. The combination is silently accepted at startup, and _enforce_app_cred_policy returns early on max_days \u003c\u003d 0, so federated app creds end up with unbounded lifetime. Could you either add a startup-time validator that raises on this combination, or update the help text (and the release note) to describe the actual behaviour.","commit_id":"6bbf2d629a704ffa75a12eda12333882136d67d1"}],"keystone/tests/unit/test_v3_application_credential.py":[{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"58f02a9bdab4d026c990ade8778ab7d49d6c0a64","unresolved":true,"context_lines":[{"line_number":1106,"context_line":"        )"},{"line_number":1107,"context_line":""},{"line_number":1108,"context_line":""},{"line_number":1109,"context_line":"class TestEnforceFederatedAppCredPolicy(_AppCredPolicyBase):"},{"line_number":1110,"context_line":"    \"\"\"Tests for the federated branch of _enforce_app_cred_policy.\"\"\""},{"line_number":1111,"context_line":""},{"line_number":1112,"context_line":"    IS_FEDERATED \u003d True"}],"source_content_type":"text/x-python","patch_set":14,"id":"5ef2ed83_691eb84e","line":1109,"updated":"2026-06-09 12:23:44.000000000","message":"I think a functional test through RestfulTestCase that POSTs to /v3/users/{user_id}/application_credentials with a federation-issued token would be valuable: default federated_enabled\u003dFalse yields 403; with the override it yields 201; an over-limit expires_at yields 400. The current tests exercise the helper in isolation only.","commit_id":"6bbf2d629a704ffa75a12eda12333882136d67d1"}]}
