)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"155760f769e90be4809120e5de5184077b9d1948","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"68149e95_b21ea2d1","updated":"2026-09-18 14:57:39.000000000","message":"Sorry, I didn\u0027t read properly the code, not I get it and it was my mistake","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"},{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"1607a3327209d4631b66ce006e5cc30fcdc31862","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"d65c47aa_f4e86fbc","updated":"2026-09-18 10:08:04.000000000","message":"While it may not be as important to be so precise in the spec, but it\u0027s IMO very important for the user facing documentation to be explicit and precise about the security claims.","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"e3e6ba96a9bd6689bcfb29426d662dce575ed794","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"8632faf1_9a243ad8","updated":"2026-09-18 15:35:51.000000000","message":"Qwen3.8 findings\n\nBlocking / major\n1. Domain-delete cascade is undefined (biggest gap). Today _delete_domain (keystone/resource/core.py:908) recursively hard-deletes all projects/subprojects in the domain, then the _domain_deleted notification (keystone/identity/core.py:619) deletes all groups and users in it. The spec only says delete_domain() will \"mark as deleted\" — it never says what happens to the domain\u0027s contents. If only the domain row is marked, its projects and users stay deleted\u003dFALSE but become unreachable zombies (domain no longer resolves). The spec must define whether domain soft-delete cascades to soft-deleting all contained projects and users (each with its own deleted_at).\n2. Cross-spec conflict with the explicit-IDs spec (same cycle, 2026.2).\n- References (line 861) points to specs/keystone/2026.2/explicit-resource-ids.rst, which doesn\u0027t exist; the actual spec is explicit-project-domain-ids.rst (on review/997320), and it covers projects and domains only — not users. The dependency wording (\"explicit ID creation\" as motivation for user ID reuse) overstates the dependent spec\u0027s scope.\n- Config-option clash: that spec plans [resource] soft_delete_projects; this spec defines [resource] soft_delete_enabled + [identity] soft_delete_enabled. Both can\u0027t own project soft delete.\n- That spec\u0027s phased plan says soft delete is \"Phase 2 (next release)\"; this spec implements it in 2026.2 and depends on it. The dependency direction and ownership need to be reconciled before either lands.\n- Work item 5 references check_id_uniqueness() and id_in_use() in keystone/common/id_utils.py — none of these exist in keystone. The explicit spec defines validate_global_uniqueness(resource_id, resource_type), and it goes through API-level get_user()/get_project(), which this spec will make filter out soft-deleted rows. That function needs an include-deleted path; the cross-spec dependency should be stated explicitly.\n3. Work item 2 cites a non-existent filter. \"Remove local_user.id IS NULL exemption from list_users()\" — no such exemption exists; list_users (keystone/identity/backends/sql.py:184) only outer-joins LocalUser for the password_expires_at filter. Likely a misread; drop or rewrite the bullet.\nModerate\n4. Group namespace omitted from ID-reuse checks. The pseudocode checks project and user only; Keystone user/group/project IDs share one namespace. Either include group or state explicitly it\u0027s out of scope (note the explicit spec\u0027s validate_global_uniqueness also omits it — worth aligning).\n5. Missing DROP statements in DDL. The existing UniqueConstraint(\u0027domain_id\u0027, \u0027name\u0027) on both project and local_user must be dropped when replacing with the name_active indexes — otherwise soft-deleted names stay blocked. The federated_user section says \"replace\" but the MySQL DDL blocks for project/local_user/federated_user only show ADD/CREATE.\n6. name_active maintenance on rename. User names are updatable (update_user accepts name; keystone/identity/core.py:1345). The app-maintained local_user.name_active must be updated on the rename path and re-uniqueness-checked, but the spec only describes create/soft-delete transitions.\n7. Default-on is an upgrade behavior change that\u0027s under-discussed. soft_delete_enabled \u003d True by default means every upgrading deployment changes delete semantics (names/IDs no longer immediately reusable, unbounded storage growth if no purge). The Alternatives section considers \"mandatory\", but Other Deployer Impact never calls out the default-on change or the opt-out (\u003d False to keep today\u0027s behavior).\nMinor\n 8. Reference Implementation: keystone already ships soft delete for trusts (trust.deleted_at, filtered deleted_at\u003dNone in keystone/trust/backends/sql.py:162) plus a purge command (keystone-manage trust_flush, keystone/cmd/cli.py:972). That\u0027s a closer in-tree precedent than Barbican and gives a naming precedent for the new purge commands.\n 9. CLI flag --age-in-days vs config auto_purge_age_days — naming inconsistency, cosmetic.\n10. Purge of a user leaves dangling trust/role references — same as today\u0027s hard delete, and \"purge affects only the Keystone database\" covers it; a one-line explicit note would prevent reviewer questions.\nVerified accurate (no action needed)\n- nonlocal_user PK is indeed (domain_id, name) with unique user_id; surrogate-PK migration is justified\n- federated_user has the unconditional UniqueConstraint(\u0027idp_id\u0027,\u0027protocol_id\u0027,\u0027unique_id\u0027)\n- expiring_user_group_membership is a real table; shadow_users_api.delete_user() is a real path used during domain deletion (keystone/identity/core.py:646)\n- get_user/get_federated_user/get_federated_users exist in identity/shadow_backends/sql.py\n- Re-auth flow (shadow_federated_user → update_federated_user_display_name → get_federated_user → create) matches the \"create new shadow\" behavior described\n- FK ondelete\u003d\u0027CASCADE\u0027 on local_user/federated_user/nonlocal_user means purge cascades as claimed","commit_id":"0668f7f9abec4de31a5babfd33c2cfed9f7e907f"}],"specs/keystone/2026.2/soft-delete.rst":[{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"f279cec028951effc7837b82edfae8c21e7a058f","unresolved":true,"context_lines":[{"line_number":98,"context_line":"    ALTER TABLE project ADD COLUMN deleted BOOLEAN DEFAULT FALSE;"},{"line_number":99,"context_line":"    ALTER TABLE project ADD COLUMN deleted_at DATETIME DEFAULT NULL;"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"**local_user table**::"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    ALTER TABLE local_user ADD COLUMN deleted BOOLEAN DEFAULT FALSE;"},{"line_number":104,"context_line":"    ALTER TABLE local_user ADD COLUMN deleted_at DATETIME DEFAULT NULL;"}],"source_content_type":"text/x-rst","patch_set":4,"id":"e885c202_674d154e","line":101,"updated":"2026-08-14 15:27:57.000000000","message":"I think we should better have it on the main \"user\" table and not the local_user, otherwise we also need it on nonlocal_user, federated_user","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"ae62074a0a0be3b3d02f38bcd09771c6b854d6e3","unresolved":true,"context_lines":[{"line_number":171,"context_line":"        raise Conflict(\"ID already used\")"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    # For auto-generated ID"},{"line_number":174,"context_line":"    while True:"},{"line_number":175,"context_line":"        new_id \u003d uuid.uuid4().hex"},{"line_number":176,"context_line":"        existing \u003d SELECT id FROM project WHERE id \u003d new_id;  # No deleted filter"},{"line_number":177,"context_line":"        if not existing:"}],"source_content_type":"text/x-rst","patch_set":4,"id":"5cbc2f45_59a575bd","line":174,"updated":"2026-08-19 12:56:42.000000000","message":"Do we need this while True here?\nShouldn\u0027t we just try to insert directly? As this will be rare to happen, we could just send a error message and ask to try to create the resource again, or just limit it to try: \u0027insert the uuid\u0027 except: try \u0027insert a new uuid again\u0027 except: failure, user should try again.\nAlso, this should be rare, but many things could happen between the select and then the insert.","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":9914,"name":"Ade Lee","email":"alee@redhat.com","username":"alee"},"change_message_id":"461b4c62fe0ed07df18f0d3e20916ba2e4c13469","unresolved":true,"context_lines":[{"line_number":171,"context_line":"        raise Conflict(\"ID already used\")"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    # For auto-generated ID"},{"line_number":174,"context_line":"    while True:"},{"line_number":175,"context_line":"        new_id \u003d uuid.uuid4().hex"},{"line_number":176,"context_line":"        existing \u003d SELECT id FROM project WHERE id \u003d new_id;  # No deleted filter"},{"line_number":177,"context_line":"        if not existing:"}],"source_content_type":"text/x-rst","patch_set":4,"id":"0cd96a1c_832457f0","line":174,"in_reply_to":"5cbc2f45_59a575bd","updated":"2026-09-17 18:54:22.000000000","message":"This is just psuedo code really,  This cmoment is better suited for the implementation patches.  But while True here just loops until we find an ID that is unused.  It might even be what\u0027s already there.","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"ae62074a0a0be3b3d02f38bcd09771c6b854d6e3","unresolved":true,"context_lines":[{"line_number":184,"context_line":""},{"line_number":185,"context_line":"**Manual purge via keystone-manage**::"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"    keystone-manage resource purge --days 90"},{"line_number":188,"context_line":"    keystone-manage identity purge --days 90"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"**Automatic purge via periodic task**::"}],"source_content_type":"text/x-rst","patch_set":4,"id":"2324954e_82ce7b8e","line":187,"updated":"2026-08-19 12:56:42.000000000","message":"Should we throw a warning about purging keystone resources, that this should be done to the others databases as well, since purging keystone and not the others, could lead to problems previously mentioned?","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":9914,"name":"Ade Lee","email":"alee@redhat.com","username":"alee"},"change_message_id":"461b4c62fe0ed07df18f0d3e20916ba2e4c13469","unresolved":true,"context_lines":[{"line_number":184,"context_line":""},{"line_number":185,"context_line":"**Manual purge via keystone-manage**::"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"    keystone-manage resource purge --days 90"},{"line_number":188,"context_line":"    keystone-manage identity purge --days 90"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"**Automatic purge via periodic task**::"}],"source_content_type":"text/x-rst","patch_set":4,"id":"099f108a_3c1be053","line":187,"in_reply_to":"2324954e_82ce7b8e","updated":"2026-09-17 18:54:22.000000000","message":"This command is an administrative function to handle what is in the keystone DB.  We should document perhaps the possible implications, but I think a warning is unnecessary.  We don\u0027t have similar warnings on other cleanup scripts - for example, the script to clean up barbican resources.\n\nBut I have no objection if keystone cores think this necessary.","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"ae62074a0a0be3b3d02f38bcd09771c6b854d6e3","unresolved":true,"context_lines":[{"line_number":260,"context_line":""},{"line_number":261,"context_line":"**Positive Security Impacts**"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"* **Prevents ID reuse attacks**: Attackers cannot recreate a resource with"},{"line_number":264,"context_line":"  a previously used ID to gain access to orphaned resources in other services."},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"* **Audit log integrity**: Historical audit entries continue to reference"}],"source_content_type":"text/x-rst","patch_set":4,"id":"0409e34b_3c3d3dcd","line":263,"updated":"2026-08-19 12:56:42.000000000","message":"Depends on how they use the purge mechanism","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":9914,"name":"Ade Lee","email":"alee@redhat.com","username":"alee"},"change_message_id":"461b4c62fe0ed07df18f0d3e20916ba2e4c13469","unresolved":true,"context_lines":[{"line_number":260,"context_line":""},{"line_number":261,"context_line":"**Positive Security Impacts**"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"* **Prevents ID reuse attacks**: Attackers cannot recreate a resource with"},{"line_number":264,"context_line":"  a previously used ID to gain access to orphaned resources in other services."},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"* **Audit log integrity**: Historical audit entries continue to reference"}],"source_content_type":"text/x-rst","patch_set":4,"id":"fe4c3f9c_1d549f66","line":263,"in_reply_to":"0409e34b_3c3d3dcd","updated":"2026-09-17 18:54:22.000000000","message":"sure.  There is always that caveat.  Admins have to balance keeping the DB a manageable size vs. preventing uuid reuse.","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"ae62074a0a0be3b3d02f38bcd09771c6b854d6e3","unresolved":true,"context_lines":[{"line_number":263,"context_line":"* **Prevents ID reuse attacks**: Attackers cannot recreate a resource with"},{"line_number":264,"context_line":"  a previously used ID to gain access to orphaned resources in other services."},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"* **Audit log integrity**: Historical audit entries continue to reference"},{"line_number":267,"context_line":"  the correct resource, even if it has been deleted."},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"* **Recovery capability**: Accidentally deleted resources can potentially be"}],"source_content_type":"text/x-rst","patch_set":4,"id":"78a3965e_dfcffc91","line":266,"updated":"2026-08-19 12:56:42.000000000","message":"Same issue as mentioned before.","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":9914,"name":"Ade Lee","email":"alee@redhat.com","username":"alee"},"change_message_id":"461b4c62fe0ed07df18f0d3e20916ba2e4c13469","unresolved":true,"context_lines":[{"line_number":263,"context_line":"* **Prevents ID reuse attacks**: Attackers cannot recreate a resource with"},{"line_number":264,"context_line":"  a previously used ID to gain access to orphaned resources in other services."},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"* **Audit log integrity**: Historical audit entries continue to reference"},{"line_number":267,"context_line":"  the correct resource, even if it has been deleted."},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"* **Recovery capability**: Accidentally deleted resources can potentially be"}],"source_content_type":"text/x-rst","patch_set":4,"id":"57aeed45_f814d173","line":266,"in_reply_to":"78a3965e_dfcffc91","updated":"2026-09-17 18:54:22.000000000","message":"same as above.","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"ae62074a0a0be3b3d02f38bcd09771c6b854d6e3","unresolved":true,"context_lines":[{"line_number":320,"context_line":"Soft-deleted resources remain in the database until purged:"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"* Default 90-day retention means ~3 months of deleted resources"},{"line_number":323,"context_line":"* Large deployments may see 10-20% database size increase"},{"line_number":324,"context_line":"* Mitigated by regular purging (manual or automatic)"},{"line_number":325,"context_line":""},{"line_number":326,"context_line":"Other Deployer Impact"}],"source_content_type":"text/x-rst","patch_set":4,"id":"97d4f7ab_eb0c6a4c","line":323,"updated":"2026-08-19 12:56:42.000000000","message":"Where do these 10-20% numbers come from? Do we have some statistics on users operations?","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":9914,"name":"Ade Lee","email":"alee@redhat.com","username":"alee"},"change_message_id":"461b4c62fe0ed07df18f0d3e20916ba2e4c13469","unresolved":true,"context_lines":[{"line_number":320,"context_line":"Soft-deleted resources remain in the database until purged:"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"* Default 90-day retention means ~3 months of deleted resources"},{"line_number":323,"context_line":"* Large deployments may see 10-20% database size increase"},{"line_number":324,"context_line":"* Mitigated by regular purging (manual or automatic)"},{"line_number":325,"context_line":""},{"line_number":326,"context_line":"Other Deployer Impact"}],"source_content_type":"text/x-rst","patch_set":4,"id":"84ab5686_b85980d9","line":323,"in_reply_to":"97d4f7ab_eb0c6a4c","updated":"2026-09-17 18:54:22.000000000","message":"Yeah , thats probably a number made up by AI to sound more impressive.  I\u0027ll revise this just to say that the DB size will be bigger.","commit_id":"2e1e857fc7f013c747ce060e27f35f72251e6385"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"c085d50420d94f3d8be427fb23475dc3c2004518","unresolved":true,"context_lines":[{"line_number":408,"context_line":"        new_id \u003d uuid.uuid4().hex"},{"line_number":409,"context_line":"        existing \u003d SELECT id FROM project WHERE id \u003d new_id"},{"line_number":410,"context_line":"        if not existing:"},{"line_number":411,"context_line":"            existing \u003d SELECT id FROM user WHERE id \u003d new_id"},{"line_number":412,"context_line":"        if not existing:"},{"line_number":413,"context_line":"            break"},{"line_number":414,"context_line":""}],"source_content_type":"text/x-rst","patch_set":7,"id":"1496cad5_7ececf59","line":411,"updated":"2026-09-18 10:44:32.000000000","message":"I don\u0027t understand what this if is doing; If the new_id doesn\u0027t exist then we just try to select it again?","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"155760f769e90be4809120e5de5184077b9d1948","unresolved":false,"context_lines":[{"line_number":408,"context_line":"        new_id \u003d uuid.uuid4().hex"},{"line_number":409,"context_line":"        existing \u003d SELECT id FROM project WHERE id \u003d new_id"},{"line_number":410,"context_line":"        if not existing:"},{"line_number":411,"context_line":"            existing \u003d SELECT id FROM user WHERE id \u003d new_id"},{"line_number":412,"context_line":"        if not existing:"},{"line_number":413,"context_line":"            break"},{"line_number":414,"context_line":""}],"source_content_type":"text/x-rst","patch_set":7,"id":"90852aec_a011caf2","line":411,"in_reply_to":"1496cad5_7ececf59","updated":"2026-09-18 14:57:39.000000000","message":"Done","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"c085d50420d94f3d8be427fb23475dc3c2004518","unresolved":true,"context_lines":[{"line_number":410,"context_line":"        if not existing:"},{"line_number":411,"context_line":"            existing \u003d SELECT id FROM user WHERE id \u003d new_id"},{"line_number":412,"context_line":"        if not existing:"},{"line_number":413,"context_line":"            break"},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"``check_id_uniqueness()`` must treat any ``user`` row with ``deleted\u003dTRUE``"},{"line_number":416,"context_line":"as blocking ID reuse, regardless of whether the user has ``local_user``,"}],"source_content_type":"text/x-rst","patch_set":7,"id":"e576cd1f_2dc6e3ea","line":413,"updated":"2026-09-18 10:44:32.000000000","message":"If the second selection, without a generating a new id, doesn\u0027t exist then we break the while?\nMaybe we should keep like on the previous patch?\nif not existing:\n    break\notherwise go back to the start of the loop and generate a new id.","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"},{"author":{"_account_id":34120,"name":"Andre Aranha","display_name":"afariasa","email":"afariasa@redhat.com","username":"afariasa"},"change_message_id":"155760f769e90be4809120e5de5184077b9d1948","unresolved":false,"context_lines":[{"line_number":410,"context_line":"        if not existing:"},{"line_number":411,"context_line":"            existing \u003d SELECT id FROM user WHERE id \u003d new_id"},{"line_number":412,"context_line":"        if not existing:"},{"line_number":413,"context_line":"            break"},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"``check_id_uniqueness()`` must treat any ``user`` row with ``deleted\u003dTRUE``"},{"line_number":416,"context_line":"as blocking ID reuse, regardless of whether the user has ``local_user``,"}],"source_content_type":"text/x-rst","patch_set":7,"id":"a952f6b2_907fbb4c","line":413,"in_reply_to":"e576cd1f_2dc6e3ea","updated":"2026-09-18 14:57:39.000000000","message":"Done","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"},{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"1607a3327209d4631b66ce006e5cc30fcdc31862","unresolved":true,"context_lines":[{"line_number":551,"context_line":"Security Impact"},{"line_number":552,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":553,"context_line":""},{"line_number":554,"context_line":"**Positive Security Impacts**"},{"line_number":555,"context_line":""},{"line_number":556,"context_line":"* **Prevents ID reuse attacks**: Attackers cannot recreate a resource with"},{"line_number":557,"context_line":"  a previously used ID to gain access to orphaned resources in other services."}],"source_content_type":"text/x-rst","patch_set":7,"id":"b65ff287_0b83e470","line":554,"updated":"2026-09-18 10:08:04.000000000","message":"I think this needs to be very expilicit: Change the Security Impact claim that soft delete “prevents ID reuse attacks” — that is only true until purge","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"},{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"1607a3327209d4631b66ce006e5cc30fcdc31862","unresolved":true,"context_lines":[{"line_number":562,"context_line":"* **Recovery capability**: Accidentally deleted resources can potentially be"},{"line_number":563,"context_line":"  recovered (though this spec does not implement recovery UI/API)."},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"**Negative Security Impacts**"},{"line_number":566,"context_line":""},{"line_number":567,"context_line":"* **Increased database size**: Soft-deleted resources remain in the database"},{"line_number":568,"context_line":"  until purged, increasing storage requirements."}],"source_content_type":"text/x-rst","patch_set":7,"id":"910311b7_33df44ef","line":565,"updated":"2026-09-18 10:08:04.000000000","message":"purge section should say explicitly that purge re-enables ID reuse, including deliberate recreate via explicit IDs, and that operators must treat purge as a security-sensitive step (dry-run + confirm no orphans, or never purge if they cannot).","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"},{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"1607a3327209d4631b66ce006e5cc30fcdc31862","unresolved":true,"context_lines":[{"line_number":565,"context_line":"**Negative Security Impacts**"},{"line_number":566,"context_line":""},{"line_number":567,"context_line":"* **Increased database size**: Soft-deleted resources remain in the database"},{"line_number":568,"context_line":"  until purged, increasing storage requirements."},{"line_number":569,"context_line":""},{"line_number":570,"context_line":"* **Potential for enumeration**: An attacker with database access could"},{"line_number":571,"context_line":"  enumerate soft-deleted resources. However, database access already provides"}],"source_content_type":"text/x-rst","patch_set":7,"id":"36d89b6e_74d09201","line":568,"updated":"2026-09-18 10:08:04.000000000","message":"after that you are back to today’s model, just with a delayed fuse — and worse once explicit IDs make deliberate reuse easy","commit_id":"119e0eef701a37f7a78289a965df8d22d856a5b6"}]}
