Skip to content

feat(adr0034): Restrict the assignment DC group to admins - #1221

Merged
gtema merged 1 commit into
mainfrom
claude/per-domain-assignments-provider-k0tp5e
Sep 8, 2026
Merged

feat(adr0034): Restrict the assignment DC group to admins#1221
gtema merged 1 commit into
mainfrom
claude/per-domain-assignments-provider-k0tp5e

Conversation

@gtema

@gtema gtema commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

The assignment group binds a domain to an assignment backend, which is
a role-minting surface: a domain manager who could set it would pick
which driver mints roles for their own domain (ADR 0034 §6).

  • Add a touches_assignment_group guard to the domain-manager allow
    clause of domain_config create/update/delete. It fires on the group or
    option path (input.target.group == "assignment") and on an
    assignment block in a whole-config PATCH/PUT body
    (input.target.config.assignment).
  • The admin / is_admin clauses stay unconditional; they key on the
    authentication chain and are never satisfiable by a domain-scoped
    token.
  • A whole-config DELETE carries no group, so a manager can still drop
    their domain's entire configuration; that only reverts the domain to
    the global driver, which mints nothing.
  • Cover the decision with opa test cases and, in the group handler,
    with tests driven through the real opa run policy and the production
    HttpPolicyEnforcer.

Signed-off-by: Artem Goncharov artem.goncharov@gmail.com

The `assignment` group binds a domain to an assignment backend, which is
a role-minting surface: a domain manager who could set it would pick
which driver mints roles for their own domain (ADR 0034 §6).

- Add a `touches_assignment_group` guard to the domain-manager `allow`
  clause of domain_config create/update/delete. It fires on the group or
  option path (`input.target.group == "assignment"`) and on an
  `assignment` block in a whole-config PATCH/PUT body
  (`input.target.config.assignment`).
- The `admin` / `is_admin` clauses stay unconditional; they key on the
  authentication chain and are never satisfiable by a domain-scoped
  token.
- A whole-config DELETE carries no group, so a manager can still drop
  their domain's entire configuration; that only reverts the domain to
  the global driver, which mints nothing.
- Cover the decision with `opa test` cases and, in the group handler,
  with tests driven through the real `opa run` policy and the production
  HttpPolicyEnforcer.

Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

🧪 Tempest Identity Compatibility Results (advisory, non-blocking)

rust

Totals
======
Ran: 133 tests in 25.4960 sec.
 - Passed: 66
 - Skipped: 4
 - Expected Fail: 0
 - Unexpected Success: 0
 - Failed: 63
Sum of execute time for each test: 20.2446 sec.
Failed test IDs
===== FAILED TESTS (target=rust) =====
tempest.api.identity.admin.v3.test_application_credentials.ApplicationCredentialsV3AdminTest.test_create_application_credential_with_roles[id-3b3dd48f-3388-406a-a9e6-4d078a552d0e]
tempest.api.identity.admin.v3.test_domains_negative.DomainsNegativeTestJSON.test_create_domain_with_name_length_over_64[id-37b1bbf2-d664-4785-9a11-333438586eae,negative]
tempest.api.identity.admin.v3.test_credentials.CredentialsTestJSON.test_credentials_create_get_update_delete[id-7cd59bf9-bda4-4c72-9467-d21cab278355,smoke]
tempest.api.identity.admin.v3.test_domains_negative.DomainsNegativeTestJSON.test_delete_active_domain[gate,id-1f3fbff5-4e44-400d-9ca1-d953f05f609b,negative]
tempest.api.identity.admin.v3.test_default_project_id.TestDefaultProjectId.test_default_project_id[id-d6110661-6a71-49a7-a453-b5e26640ff6d]
tempest.api.identity.admin.v3.test_domain_configuration.DomainConfigurationTestJSON.test_create_domain_config_and_show_config_groups_and_options[id-9e3ff13c-f597-4f01-9377-d6c06c2a1477]
tempest.api.identity.admin.v3.test_domain_configuration.DomainConfigurationTestJSON.test_create_update_and_delete_domain_config_groups_and_opts[id-c7510fa2-6661-4170-9c6b-4783a80651e9]
tempest.api.identity.admin.v3.test_domain_configuration.DomainConfigurationTestJSON.test_show_default_group_config_and_options[id-11a02bf0-6f94-4380-b3b0-c8dc18fc0d22]
tempest.api.identity.admin.v3.test_domains.DomainsTestJSON.test_create_domain_without_description[id-2abf8764-309a-4fa9-bc58-201b799817ad]
tempest.api.identity.admin.v3.test_domains.DomainsTestJSON.test_create_update_delete_domain[id-f2f5b44a-82e8-4dad-8084-0661ea3b18cf,smoke]
tempest.api.identity.admin.v3.test_domains.DomainsTestJSON.test_domain_delete_cascades_content[id-d8d318b7-d1b3-4c37-94c5-3c5ba0b121ea]
tempest.api.identity.admin.v3.test_domains.DomainsTestJSON.test_list_domains_filter_by_enabled[id-3fd19840-65c1-43f8-b48c-51bdd066dff9]
setUpClass (tempest.api.identity.admin.v3.test_endpoint_groups.EndPointGroupsTest)
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_check_revoke_roles_on_projects_group[id-26021436-d5a4-4256-943c-ded01e0d4b45]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_check_revoke_roles_on_projects_user[id-18b70e45-7687-4b72-8277-b8f1a47d7591]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_list_check_revoke_roles_on_domains_group[id-c7a8dda2-be50-4fb4-9a9c-e830771078b1]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_list_check_revoke_roles_on_domains_user[id-4e6f0366-97c8-423c-b2be-41eae6ac91c8]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_list_revoke_user_roles_on_domain[id-3acf666e-5354-42ac-8e17-8b68893bcd36]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_list_revoke_user_roles_on_project_tree[id-9f02ccd9-9b57-46b4-8f77-dd5a736f3a06]
tempest.api.identity.admin.v3.test_list_projects.ListProjectsTestJSON.test_list_projects_with_enabled[id-0fe7a334-675a-4509-b00e-1c4b95d5dae8]
tempest.api.identity.admin.v3.test_list_projects.ListProjectsTestJSON.test_list_projects_with_parent[id-6edc66f5-2941-4a17-9526-4073311c1fac]
tempest.api.identity.admin.v3.test_groups.GroupsV3TestJSON.test_group_users_add_list_delete[id-1598521a-2f36-4606-8df9-30772bd51339,smoke]
tempest.api.identity.admin.v3.test_groups.GroupsV3TestJSON.test_list_user_groups[id-64573281-d26a-4a52-b899-503cb0f4e4ec]
tempest.api.identity.admin.v3.test_oauth_consumers.OAUTHConsumersV3Test.test_create_and_show_consumer[id-c8307ea6-a86c-47fd-ae7b-5b3b2caca76d]
tempest.api.identity.admin.v3.test_oauth_consumers.OAUTHConsumersV3Test.test_delete_consumer[id-fdfa1b7f-2a31-4354-b2c7-f6ae20554f93]
tempest.api.identity.admin.v3.test_oauth_consumers.OAUTHConsumersV3Test.test_list_consumers[id-09ca50de-78f2-4ffb-ac71-f2254036b2b8]
tempest.api.identity.admin.v3.test_oauth_consumers.OAUTHConsumersV3Test.test_update_consumer[id-080a9b1a-c009-47c0-9979-5305bf72e3dc]
tempest.api.identity.admin.v3.test_list_users.UsersV3TestJSON.test_list_users_with_not_enabled[id-bff8bf2f-9408-4ef5-b63a-753c8c2124eb]
tempest.api.identity.admin.v3.test_projects_negative.ProjectsNegativeStaticTestJSON.test_create_projects_name_length_over_64[id-502b6ceb-b0c8-4422-bf53-f08fdb21e2f0,negative]
tempest.api.identity.admin.v3.test_list_projects.ListProjectsStaticTestJSON.test_list_projects[id-1d830662-22ad-427c-8c3e-4ec854b0af44]
tempest.api.identity.admin.v3.test_users_negative.UsersNegativeTest.test_create_user_for_non_existent_domain[id-e75f006c-89cc-477b-874d-588e4eab4b17,negative]
tempest.api.identity.admin.v3.test_project_tags.IdentityV3ProjectTagsTest.test_list_update_delete_project_tags[id-7c123aac-999d-416a-a0fb-84b915ab10de]
tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265,smoke]
tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd,smoke]
tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_identity_v3_existence[id-79aec9ae-710f-4c54-a4fc-3aa25b4feac3]
tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_list_api_versions[id-721f480f-35b6-46c7-846e-047e6acea0dc,smoke]
tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential[id-8080c75c-eddc-4786-941a-c2da7039ae61]
tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential_expires[id-852daf0c-42b5-4239-8466-d193d0543ed3]
tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_list_application_credentials[id-ff0cd457-6224-46e7-b79e-0ada4964a8a6]
tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_query_application_credentials[id-9bb5e5cc-5250-493a-8869-8b665f6aa5f6]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_get_trusts_all[id-4773ebd5-ecbf-4255-b8d8-b63e6f72b65d,smoke]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_get_trusts_query[id-6268b345-87ca-47c0-9ce3-37792b43403a]
tempest.api.identity.admin.v3.test_projects.ProjectsTestJSON.test_create_is_domain_project[id-a7eb9416-6f9b-4dbb-b71b-7f73aaef59d5]
tempest.api.identity.admin.v3.test_projects.ProjectsTestJSON.test_project_create_with_parent[id-1854f9c0-70bc-4d11-a08a-1c789d339e3d]
tempest.api.identity.admin.v3.test_projects.ProjectsTestJSON.test_project_get_equals_list[id-d1db68b6-aebe-4fa0-b79d-d724d2e21162]
tempest.api.identity.v3.test_tokens.TokensV3Test.test_validate_token[id-a9512ac3-3909-48a4-b395-11f438e16260]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_trust_expire[id-0ed14b66-cefd-4b5c-a964-65759453e292]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_trust_impersonate[id-5a0a91a4-baef-4a14-baba-59bf4d7fcace]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_trust_noimpersonate[id-ed2a8779-a7ac-49dc-afd7-30f32f936ed2]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_assignments_for_domain_roles[id-3859df7e-5b78-4e4d-b10e-214c8953842a]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_assignments_for_implied_roles_create_delete[id-c8828027-df48-4021-95df-b65b92c7429e]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_grant_list_revoke_role_to_group_on_domain[id-4bf8a70b-e785-413a-ad53-9f91ce02faa7]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_grant_list_revoke_role_to_group_on_project[id-cbf11737-1904-4690-9613-97bcbb3df1c4]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_grant_list_revoke_role_to_group_on_system[id-c888fe4f-8018-48db-b959-542225c1b4b6]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_grant_list_revoke_role_to_user_on_domain[id-6c9a2940-3625-43a3-ac02-5dcec62ef3bd]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_implied_domain_roles[id-eb1e1c24-1bc4-4d47-9748-e127a1852c82]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_implied_roles_create_check_show_delete[id-c90c316c-d706-4728-bcba-eb1912081b69]
tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON.test_role_create_update_show_list[id-18afc6c0-46cf-4911-824e-9989cc056c3a,smoke]
tempest.api.identity.admin.v3.test_tokens.TokensV3TestJSON.test_get_available_domain_scopes[id-ec5ecb05-af64-4c04-ac86-4d9f6f12f185]
tempest.api.identity.admin.v3.test_tokens.TokensV3TestJSON.test_rescope_token[id-565fa210-1da1-4563-999b-f7b5b67cf112]
tempest.api.identity.admin.v3.test_users.UsersV3TestJSON.test_list_user_projects[id-a831e70c-e35b-430b-92ed-81ebbc5437b8]
tempest.api.identity.v3.test_catalog.IdentityCatalogTest.test_catalog_standardization[id-56b57ced-22b8-4127-9b8a-565dfb0207e2]
tempest.api.identity.v3.test_projects.IdentityV3ProjectsTest.test_list_projects_returns_only_authorized_projects[id-86128d46-e170-4644-866a-cc487f699e1d]
===== END FAILED TESTS (target=rust) =====

View full run

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

🦢 Load Test Results

Goose Attack Report

Plan Overview

Action Started Stopped Elapsed Users
Increasing 26-09-08 07:46:05 26-09-08 07:46:28 00:00:23 0 → 45
Maintaining 26-09-08 07:46:28 26-09-08 07:46:58 00:00:30 45
Decreasing 26-09-08 07:46:58 26-09-08 07:46:58 00:00:00 0 ← 45

Request Metrics

Method Name # Requests # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
DELETE DELETE /v3/auth/tokens 79 0 313.06 37 695 2.63 0.00
DELETE DELETE /v3/projects/:id (teardown) 1 0 76.00 76 76 0.03 0.00
DELETE DELETE /v3/roles/:id (teardown) 1 0 94.00 94 94 0.03 0.00
DELETE DELETE /v3/users/:id (teardown) 2 0 111.50 91 132 0.07 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 1 0 244.00 244 244 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 1 0 94.00 94 94 0.03 0.00
GET 1093 0 319.50 140 612 36.43 0.00
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 3322 3322 8.74 1 831 110.73 110.73
GET GET /v3/auth/tokens (validate new) 78 0 304.32 168 452 2.60 0.00
GET GET /v3/auth/tokens (validate revoked) 79 0 270.09 15 422 2.63 0.00
GET GET /v3/projects/:id 100 0 301.49 164 420 3.33 0.00
GET GET /v3/projects/:id (catalog) 150 0 305.30 136 442 5.00 0.00
GET GET /v3/role_assignments 76 0 307.22 166 433 2.53 0.00
GET GET /v3/role_assignments?role.id 76 0 306.16 147 434 2.53 0.00
GET GET /v3/role_assignments?scope.domain.id 76 0 291.22 144 456 2.53 0.00
GET GET /v3/role_assignments?user.id 77 0 283.99 154 403 2.57 0.00
GET GET /v3/roles 201 0 302.15 155 435 6.70 0.00
GET GET /v3/roles/:id 101 0 300.46 154 430 3.37 0.00
GET GET /v3/users/:id 191 0 316.54 168 479 6.37 0.00
GET GET /v3/users/:id (catalog) 188 0 315.23 146 461 6.27 0.00
GET GET /v4/api-keys 47 0 316.89 207 428 1.57 0.00
GET GET /v4/api-keys/:client_id 47 0 328.17 207 470 1.57 0.00
GET GET /v4/mappings/rulesets 50 0 320.22 162 455 1.67 0.00
GET GET /v4/mappings/rulesets/:mapping_id 49 0 292.41 151 434 1.63 0.00
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 1230 0 36.24 5 205 41.00 0.00
GET GET /v4/oauth2/:domain_id/clients 49 0 300.24 181 402 1.63 0.00
GET GET /v4/oauth2/:domain_id/clients/:provider_id 50 0 315.04 127 418 1.67 0.00
GET GET /v4/oauth2/:domain_id/jwks 1229 0 36.20 4 181 40.97 0.00
GET GET /v4/scim_realms 30 0 308.70 177 475 1.00 0.00
GET GET /v4/scim_realms/:domain_id/:provider_id 31 0 299.81 207 400 1.03 0.00
POST POST /v3/auth/tokens 76 0 280.16 120 433 2.53 0.00
POST POST /v3/auth/tokens (password, invalid) 45 0 673.58 446 1165 1.50 0.00
POST POST /v3/auth/tokens (password, project-scoped) 82 0 809.00 544 1213 2.73 0.00
POST POST /v3/auth/tokens (password, unscoped) 80 0 706.01 406 1083 2.67 0.00
POST POST /v3/auth/tokens (rescope to system) 180 0 335.54 176 482 6.00 0.00
POST POST /v3/auth/tokens (rescope, invalid project) 107 0 281.33 126 403 3.57 0.00
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 75 0 813.57 548 1197 2.50 0.00
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 0 262.00 262 262 0.03 0.00
PUT PUT /v4/scim_realms/:domain_id/:provider_id 30 0 398.77 299 572 1.00 0.00
Aggregated 9381 3322 145.30 1 1213 312.70 110.73

Response Time Metrics

Method Name 50%ile (ms) 60%ile (ms) 70%ile (ms) 80%ile (ms) 90%ile (ms) 95%ile (ms) 99%ile (ms) 100%ile (ms)
DELETE DELETE /v3/auth/tokens 310 320 340 350 390 420 460 695
DELETE DELETE /v3/projects/:id (teardown) 76 76 76 76 76 76 76 76
DELETE DELETE /v3/roles/:id (teardown) 94 94 94 94 94 94 94 94
DELETE DELETE /v3/users/:id (teardown) 91 91 91 130 130 130 130 130
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 244 244 244 244 244 244 244 244
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 94 94 94 94 94 94 94 94
GET 320 340 350 370 400 420 460 600
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 4 4 5 7 10 13 40 800
GET GET /v3/auth/tokens (validate new) 310 320 330 350 360 390 400 450
GET GET /v3/auth/tokens (validate revoked) 260 290 310 340 360 400 410 420
GET GET /v3/projects/:id 310 320 330 350 370 390 420 420
GET GET /v3/projects/:id (catalog) 310 320 340 350 370 380 430 440
GET GET /v3/role_assignments 310 330 330 350 370 380 420 430
GET GET /v3/role_assignments?role.id 300 320 340 360 380 400 430 430
GET GET /v3/role_assignments?scope.domain.id 290 310 320 340 350 370 440 456
GET GET /v3/role_assignments?user.id 280 300 310 330 350 350 390 400
GET GET /v3/roles 310 320 340 350 370 390 420 435
GET GET /v3/roles/:id 300 310 330 350 360 380 400 430
GET GET /v3/users/:id 320 330 340 360 390 410 450 479
GET GET /v3/users/:id (catalog) 320 330 350 360 390 400 420 460
GET GET /v4/api-keys 320 330 340 360 380 390 428 428
GET GET /v4/api-keys/:client_id 350 350 360 380 390 450 470 470
GET GET /v4/mappings/rulesets 320 330 350 360 390 420 455 455
GET GET /v4/mappings/rulesets/:mapping_id 290 290 330 350 370 380 430 430
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 29 34 41 54 69 84 120 205
GET GET /v4/oauth2/:domain_id/clients 300 310 320 340 380 380 400 400
GET GET /v4/oauth2/:domain_id/clients/:provider_id 320 340 350 360 380 390 418 418
GET GET /v4/oauth2/:domain_id/jwks 28 34 40 53 68 88 130 180
GET GET /v4/scim_realms 290 320 360 380 390 410 475 475
GET GET /v4/scim_realms/:domain_id/:provider_id 300 320 330 350 370 370 400 400
POST POST /v3/auth/tokens 280 300 310 320 360 370 380 430
POST POST /v3/auth/tokens (password, invalid) 700 700 800 800 900 1,000 1,000 1,000
POST POST /v3/auth/tokens (password, project-scoped) 800 800 900 1,000 1,000 1,000 1,000 1,000
POST POST /v3/auth/tokens (password, unscoped) 700 700 800 800 900 1,000 1,000 1,000
POST POST /v3/auth/tokens (rescope to system) 340 350 370 390 410 430 460 480
POST POST /v3/auth/tokens (rescope, invalid project) 290 300 310 320 350 360 400 400
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 800 800 900 900 1,000 1,000 1,000 1,000
POST POST /v4/api-keys/:client_id/revoke (teardown) 262 262 262 262 262 262 262 262
PUT PUT /v4/scim_realms/:domain_id/:provider_id 370 420 430 460 490 500 572 572
Aggregated 32 84 270 320 360 410 800 1,000

Status Code Metrics

Method Name Status Codes
DELETE DELETE /v3/auth/tokens 79 [204]
DELETE DELETE /v3/projects/:id (teardown) 1 [204]
DELETE DELETE /v3/roles/:id (teardown) 1 [204]
DELETE DELETE /v3/users/:id (teardown) 2 [204]
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 1 [204]
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 1 [204]
GET 1,093 [200]
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 31 [401], 3,291 [429]
GET GET /v3/auth/tokens (validate new) 78 [200]
GET GET /v3/auth/tokens (validate revoked) 79 [404]
GET GET /v3/projects/:id 100 [200]
GET GET /v3/projects/:id (catalog) 150 [200]
GET GET /v3/role_assignments 76 [200]
GET GET /v3/role_assignments?role.id 76 [200]
GET GET /v3/role_assignments?scope.domain.id 76 [200]
GET GET /v3/role_assignments?user.id 77 [200]
GET GET /v3/roles 201 [200]
GET GET /v3/roles/:id 101 [200]
GET GET /v3/users/:id 191 [200]
GET GET /v3/users/:id (catalog) 188 [200]
GET GET /v4/api-keys 47 [200]
GET GET /v4/api-keys/:client_id 47 [200]
GET GET /v4/mappings/rulesets 50 [200]
GET GET /v4/mappings/rulesets/:mapping_id 49 [200]
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 1,230 [200]
GET GET /v4/oauth2/:domain_id/clients 49 [200]
GET GET /v4/oauth2/:domain_id/clients/:provider_id 50 [200]
GET GET /v4/oauth2/:domain_id/jwks 1,229 [200]
GET GET /v4/scim_realms 30 [200]
GET GET /v4/scim_realms/:domain_id/:provider_id 31 [200]
POST POST /v3/auth/tokens 76 [201]
POST POST /v3/auth/tokens (password, invalid) 45 [401]
POST POST /v3/auth/tokens (password, project-scoped) 82 [201]
POST POST /v3/auth/tokens (password, unscoped) 80 [201]
POST POST /v3/auth/tokens (rescope to system) 180 [201]
POST POST /v3/auth/tokens (rescope, invalid project) 107 [401]
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 75 [201]
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 [200]
PUT PUT /v4/scim_realms/:domain_id/:provider_id 30 [200]
Aggregated 85 [204], 3,291 [429], 183 [401], 493 [201], 79 [404], 5,250 [200]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
ReadHeavy
0.0 1 0 18.00 18 18 0.03 0.00
0.1 195 0 325.33 144 492 6.50 0.00
0.2 194 0 304.76 141 454 6.47 0.00
0.3 194 0 304.03 149 440 6.47 0.00
TokenLifecycle
1.0 0 0 0.00 0 0 0.00 0.00
1.1 79 0 1171.47 516 1625 2.63 0.00
ValidateToken
2.0 0 0 0.00 0 0 0.00 0.00
2.1 170 0 357.59 150 612 5.67 0.00
UserCRUD
3.0 0 0 0.00 0 0 0.00 0.00
3.1 0 0 0.00 0 0 0.00 0.00
3.2 191 0 316.57 168 479 6.37 0.00
3.3 2 0 111.50 91 132 0.07 0.00
ProjectCRUD
4.0 0 0 0.00 0 0 0.00 0.00
4.1 0 0 0.00 0 0 0.00 0.00
4.2 100 0 301.51 164 420 3.33 0.00
4.3 1 0 77.00 77 77 0.03 0.00
RoleCRUD
5.0 0 0 0.00 0 0 0.00 0.00
5.1 0 0 0.00 0 0 0.00 0.00
5.2 101 0 300.47 154 430 3.37 0.00
5.3 1 0 94.00 94 94 0.03 0.00
RoleList
6.0 0 0 0.00 0 0 0.00 0.00
6.1 201 0 302.15 155 435 6.70 0.00
RoleAssignmentList
7.0 0 0 0.00 0 0 0.00 0.00
7.1 76 0 307.24 166 433 2.53 0.00
7.2 77 0 284.06 154 403 2.57 0.00
7.3 76 0 291.24 144 456 2.53 0.00
7.4 76 0 306.18 147 434 2.53 0.00
UserRead
8.0 0 0 0.00 0 0 0.00 0.00
8.1 189 0 325.55 178 492 6.30 0.00
8.2 188 0 315.26 146 461 6.27 0.00
ProjectRead
9.0 0 0 0.00 0 0 0.00 0.00
9.1 151 0 300.57 140 447 5.03 0.00
9.2 150 0 305.33 136 442 5.00 0.00
PasswordAuth
10.0 80 0 706.04 406 1083 2.67 0.00
10.1 82 0 809.01 544 1213 2.73 0.00
PasswordAuthNegative
11.0 45 0 673.64 446 1165 1.50 0.00
Rescope
12.0 0 0 0.00 0 0 0.00 0.00
12.1 180 0 335.57 176 482 6.00 0.00
RescopeNegative
13.0 0 0 0.00 0 0 0.00 0.00
13.1 107 0 281.35 126 403 3.57 0.00
SystemScopeAuth
14.0 75 0 813.59 548 1197 2.50 0.00
ApiKeyCRUD
15.0 0 0 0.00 0 0 0.00 0.00
15.1 0 0 0.00 0 0 0.00 0.00
15.2 47 0 328.21 207 470 1.57 0.00
15.3 47 0 316.89 207 428 1.57 0.00
15.4 1 0 262.00 262 262 0.03 0.00
MappingCRUD
16.0 0 0 0.00 0 0 0.00 0.00
16.1 0 0 0.00 0 0 0.00 0.00
16.2 49 0 292.45 151 434 1.63 0.00
16.3 50 0 320.22 162 455 1.67 0.00
16.4 1 0 244.00 244 244 0.03 0.00
OAuth2ClientCRUD
17.0 0 0 0.00 0 0 0.00 0.00
17.1 0 0 0.00 0 0 0.00 0.00
17.2 50 0 315.06 127 418 1.67 0.00
17.3 49 0 300.27 181 402 1.63 0.00
17.4 1 0 94.00 94 94 0.03 0.00
OAuth2Discovery
18.0 1229 0 36.22 4 181 40.97 0.00
18.1 1230 0 36.26 5 205 41.00 0.00
ScimRealmRead
19.0 0 0 0.00 0 0 0.00 0.00
19.1 31 0 299.87 207 400 1.03 0.00
19.2 30 0 308.73 177 475 1.00 0.00
19.3 30 0 398.77 299 572 1.00 0.00
ScimSync
20.0 0 0 0.00 0 0 0.00 0.00
20.1 0 0 0.00 0 0 0.00 0.00
20.2 0 0 0.00 0 0 0.00 0.00
20.3 3322 0 8.76 1 831 110.73 0.00
20.4 3321 0 0.00 0 0 110.70 0.00
20.5 3321 0 0.00 0 0 110.70 0.00
20.6 1 0 0.00 0 0 0.03 0.00
Aggregated 15792 0 86.31 1 1625 526.40 0.00

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
ReadHeavy 6 191 940.99 484 1160 6.37 31.83
TokenLifecycle 3 76 1188.87 858 1625 2.53 25.33
ValidateToken 2 168 358.67 150 612 5.60 84.00
UserCRUD 2 189 316.63 168 479 6.30 94.50
ProjectCRUD 1 99 302.12 164 420 3.30 99.00
RoleCRUD 1 100 300.76 154 430 3.33 100.00
RoleList 2 199 303.14 155 435 6.63 99.50
RoleAssignmentList 3 75 1194.24 853 1430 2.50 25.00
UserRead 4 186 643.59 385 821 6.20 46.50
ProjectRead 3 150 608.65 316 778 5.00 50.00
PasswordAuth 4 80 1516.74 1112 2023 2.67 20.00
PasswordAuthNegative 1 44 674.91 446 1165 1.47 44.00
Rescope 2 178 336.48 185 482 5.93 89.00
RescopeNegative 1 106 281.45 126 403 3.53 106.00
SystemScopeAuth 2 73 807.30 548 1197 2.43 36.50
ApiKeyCRUD 1 47 650.32 445 811 1.57 47.00
MappingCRUD 1 49 618.61 420 762 1.63 49.00
OAuth2ClientCRUD 1 49 618.51 375 820 1.63 49.00
OAuth2Discovery 3 1228 72.97 12 317 40.93 409.33
ScimRealmRead 1 30 1010.37 770 1155 1.00 30.00
ScimSync 1 3321 8.77 1 831 110.70 3321.00
Aggregated 45 6638 203.52 1 2023 221.27 4856.50

Error Metrics

Method Name # Error
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 48 401 Unauthorized: GET /SCIM/v2/:domain_id/Users (sync reconcile list)
POST POST /SCIM/v2/:domain_id/Users (sync provision) 1 401 Unauthorized: POST /SCIM/v2/:domain_id/Users (sync provision)
POST POST /v3/auth/tokens (password, invalid) 106 401 Unauthorized: POST /v3/auth/tokens (password, invalid)
POST POST /v3/auth/tokens (rescope, invalid project) 266 401 Unauthorized: POST /v3/auth/tokens (rescope, invalid project)
GET GET /v3/auth/tokens (validate revoked) 264 404 Not Found: GET /v3/auth/tokens (validate revoked)
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 3649 429 Too Many Requests: GET /SCIM/v2/:domain_id/Users (sync reconcile list)

View full report

@gtema
gtema added this pull request to the merge queue Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

🐰 Bencher Report

Projectkeystone
Branchclaude/per-domain-assignments-provider-k0tp5e
Testbedubuntu-latest
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
nanoseconds (ns)
(Result Δ%)
Upper Boundary
nanoseconds (ns)
(Limit %)
Command_Serde/apply/remove📈 view plot
🚷 view threshold
261,830.00 ns
(+1.51%)Baseline: 257,929.19 ns
1,308,224.68 ns
(20.01%)
Command_Serde/apply/set📈 view plot
🚷 view threshold
445,440.00 ns
(+7.00%)Baseline: 416,299.28 ns
3,206,165.49 ns
(13.89%)
Command_Serde/pack/delete📈 view plot
🚷 view threshold
97.33 ns
(-17.33%)Baseline: 117.73 ns
152.65 ns
(63.76%)
Command_Serde/pack/delete_index📈 view plot
🚷 view threshold
90.45 ns
(-13.83%)Baseline: 104.96 ns
135.23 ns
(66.88%)
Command_Serde/pack/set📈 view plot
🚷 view threshold
155.76 ns
(-18.39%)Baseline: 190.85 ns
241.68 ns
(64.45%)
Command_Serde/pack/set_index📈 view plot
🚷 view threshold
88.78 ns
(-15.38%)Baseline: 104.92 ns
135.79 ns
(65.38%)
Command_Serde/unpack/delete📈 view plot
🚷 view threshold
172.46 ns
(-7.77%)Baseline: 186.99 ns
268.43 ns
(64.25%)
Command_Serde/unpack/delete_index📈 view plot
🚷 view threshold
141.56 ns
(-8.97%)Baseline: 155.51 ns
217.11 ns
(65.20%)
Command_Serde/unpack/set📈 view plot
🚷 view threshold
220.54 ns
(-16.35%)Baseline: 263.65 ns
359.33 ns
(61.38%)
Command_Serde/unpack/set_index📈 view plot
🚷 view threshold
138.97 ns
(-9.21%)Baseline: 153.08 ns
211.62 ns
(65.67%)
Payload_encryption/pack/remove_cmd📈 view plot
🚷 view threshold
91.27 ns
(-18.74%)Baseline: 112.32 ns
149.00 ns
(61.26%)
Payload_encryption/pack/set_cmd📈 view plot
🚷 view threshold
151.09 ns
(-24.16%)Baseline: 199.23 ns
261.91 ns
(57.69%)
Payload_encryption/unpack/remove_cmd📈 view plot
🚷 view threshold
170.21 ns
(-12.92%)Baseline: 195.46 ns
282.10 ns
(60.34%)
Payload_encryption/unpack/set_cmd📈 view plot
🚷 view threshold
239.07 ns
(-12.43%)Baseline: 273.01 ns
375.39 ns
(63.69%)
Raft_1Node_Latency/prefix/1node📈 view plot
🚷 view threshold
1,844,100.00 ns
(-39.95%)Baseline: 3,070,777.17 ns
7,923,702.43 ns
(23.27%)
Raft_1Node_Latency/read/1node📈 view plot
🚷 view threshold
27,050.00 ns
(-27.73%)Baseline: 37,431.47 ns
51,663.54 ns
(52.36%)
Raft_1Node_Latency/remove/1node📈 view plot
🚷 view threshold
903,930.00 ns
(-23.15%)Baseline: 1,176,161.41 ns
11,500,152.56 ns
(7.86%)
Raft_1Node_Latency/write/1node📈 view plot
🚷 view threshold
621,860.00 ns
(-36.37%)Baseline: 977,268.28 ns
7,555,838.77 ns
(8.23%)
build_snapshot/default📈 view plot
🚷 view threshold
188,310.00 ns
(+53.13%)Baseline: 122,970.27 ns
268,756.26 ns
(70.07%)
fernet token/project📈 view plot
🚷 view threshold
1,256.20 ns
(-11.80%)Baseline: 1,424.23 ns
1,796.95 ns
(69.91%)
get_data_keyspace📈 view plot
🚷 view threshold
0.27 ns
(-13.26%)Baseline: 0.31 ns
0.39 ns
(70.85%)
get_db📈 view plot
🚷 view threshold
0.27 ns
(-13.14%)Baseline: 0.32 ns
0.39 ns
(71.05%)
get_fernet_token_timestamp/project📈 view plot
🚷 view threshold
119.19 ns
(-15.02%)Baseline: 140.26 ns
180.04 ns
(66.20%)
get_keyspace📈 view plot
🚷 view threshold
3.59 ns
(-38.87%)Baseline: 5.87 ns
13.51 ns
(26.55%)
🐰 View full continuous benchmarking report in Bencher

Merged via the queue into main with commit 2584589 Sep 8, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant