Skip to content

test(adr0034): Add per-domain assignment driver tests - #1222

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

test(adr0034): Add per-domain assignment driver tests#1222
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

Unit suites under crates/core/src/assignment/service/tests/:
target-keyed dispatch, the per-domain resolution cache, the system
carve-out, stale binding fallback, the shared-backend fast path, the
cross-domain grant invariant, and the untargeted fan-out with de-dup /
pagination / fail-fast. Reload suite: block reuse by pointer, drop of an
unmapped block, dispatch switch-off, cache clear, and last-known-good on
an unresolvable config.

Integration suite tests/integration/src/assignment_per_domain.rs, over
the real Provider stack: dispatch-on still serves the global SQL path, a
named [assignment.backends.*] block is built by the reload reactor
through inventory, an unmapped binding falls back to global, the config
API rejects an unbindable driver, an untargeted listing unions and
de-duplicates two live SQL backends, and per-domain resolution is
cached. A stub OpenFGA HTTP server (mod openfga_stub, a stateful axum
tuple store) then drives the OpenFGA driver crate end to end: a domain
bound to a named OpenFGA block routes create_grant to it over real HTTP,
the target-scoped listing reads the tuple back through the driver, and
the grant stays disjoint from the global SQL backend; an untargeted
fan-out with an OpenFGA instance present fails the whole call.
tests/integration/Cargo.toml gains the axum json and tokio net features
and turns on openstack-keystone's openfga feature, which links the
OpenFGA assignment driver and its NamedAssignmentBackendRegistration
into the integration binary.

Live test_api suite tests/api/tests/api_v3/domain_config.rs, over the
real server and OPA: a cloud admin binds assignment/driver and reads it
back; a non-system caller is refused it on the whole-config, group and
option write shapes (ADR 0034 section 6).

driver_for_target held the binding_cache read guard as a match scrutinee
temporary while the None arm awaited a write on the same lock, a
self-deadlock on every resolver-routed grant or listing. Edition 2024
rescopes if-let scrutinee temporaries but not match ones; read into an
owned value first.

Split the in-file unit module into service/tests.rs and add a from_parts
test constructor that wires mock backends straight into the routing
bundle.

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

Unit suites under crates/core/src/assignment/service/tests/:
target-keyed dispatch, the per-domain resolution cache, the system
carve-out, stale binding fallback, the shared-backend fast path, the
cross-domain grant invariant, and the untargeted fan-out with de-dup /
pagination / fail-fast. Reload suite: block reuse by pointer, drop of an
unmapped block, dispatch switch-off, cache clear, and last-known-good on
an unresolvable config.

Integration suite tests/integration/src/assignment_per_domain.rs, over
the real Provider stack: dispatch-on still serves the global SQL path, a
named [assignment.backends.*] block is built by the reload reactor
through inventory, an unmapped binding falls back to global, the config
API rejects an unbindable driver, an untargeted listing unions and
de-duplicates two live SQL backends, and per-domain resolution is
cached. A stub OpenFGA HTTP server (mod openfga_stub, a stateful axum
tuple store) then drives the OpenFGA driver crate end to end: a domain
bound to a named OpenFGA block routes create_grant to it over real HTTP,
the target-scoped listing reads the tuple back through the driver, and
the grant stays disjoint from the global SQL backend; an untargeted
fan-out with an OpenFGA instance present fails the whole call.
tests/integration/Cargo.toml gains the axum json and tokio net features
and turns on openstack-keystone's openfga feature, which links the
OpenFGA assignment driver and its NamedAssignmentBackendRegistration
into the integration binary.

Live test_api suite tests/api/tests/api_v3/domain_config.rs, over the
real server and OPA: a cloud admin binds assignment/driver and reads it
back; a non-system caller is refused it on the whole-config, group and
option write shapes (ADR 0034 section 6).

driver_for_target held the binding_cache read guard as a match scrutinee
temporary while the None arm awaited a write on the same lock, a
self-deadlock on every resolver-routed grant or listing. Edition 2024
rescopes if-let scrutinee temporaries but not match ones; read into an
owned value first.

Split the in-file unit module into service/tests.rs and add a from_parts
test constructor that wires mock backends straight into the routing
bundle.

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 37.1981 sec.
 - Passed: 66
 - Skipped: 4
 - Expected Fail: 0
 - Unexpected Success: 0
 - Failed: 63
Sum of execute time for each test: 23.1940 sec.
Failed test IDs
===== FAILED TESTS (target=rust) =====
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_application_credentials.ApplicationCredentialsV3AdminTest.test_create_application_credential_with_roles[id-3b3dd48f-3388-406a-a9e6-4d078a552d0e]
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_default_project_id.TestDefaultProjectId.test_default_project_id[id-d6110661-6a71-49a7-a453-b5e26640ff6d]
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_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_negative.DomainsNegativeTestJSON.test_create_domain_with_name_length_over_64[id-37b1bbf2-d664-4785-9a11-333438586eae,negative]
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_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]
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_list_projects.ListProjectsStaticTestJSON.test_list_projects[id-1d830662-22ad-427c-8c3e-4ec854b0af44]
setUpClass (tempest.api.identity.admin.v3.test_endpoint_groups.EndPointGroupsTest)
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.ProjectsTestJSON.test_create_is_domain_project[id-a7eb9416-6f9b-4dbb-b71b-7f73aaef59d5]
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_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.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_projects_negative.ProjectsNegativeStaticTestJSON.test_create_projects_name_length_over_64[id-502b6ceb-b0c8-4422-bf53-f08fdb21e2f0,negative]
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_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_catalog.IdentityCatalogTest.test_catalog_standardization[id-56b57ced-22b8-4127-9b8a-565dfb0207e2]
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_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.v3.test_tokens.TokensV3Test.test_validate_token[id-a9512ac3-3909-48a4-b395-11f438e16260]
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_users_negative.UsersNegativeTest.test_create_user_for_non_existent_domain[id-e75f006c-89cc-477b-874d-588e4eab4b17,negative]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_get_trusts_query[id-6268b345-87ca-47c0-9ce3-37792b43403a]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_trust_expire[id-0ed14b66-cefd-4b5c-a964-65759453e292]
tempest.api.identity.v3.test_projects.IdentityV3ProjectsTest.test_list_projects_returns_only_authorized_projects[id-86128d46-e170-4644-866a-cc487f699e1d]
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_users.UsersV3TestJSON.test_list_user_projects[id-a831e70c-e35b-430b-92ed-81ebbc5437b8]
===== 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 12:42:47 26-09-08 12:43:09 00:00:22 0 → 45
Maintaining 26-09-08 12:43:09 26-09-08 12:43:39 00:00:30 45
Decreasing 26-09-08 12:43:39 26-09-08 12:43:40 00:00:01 0 ← 45

Request Metrics

Method Name # Requests # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
DELETE DELETE /v3/auth/tokens 45 0 535.09 95 707 1.50 0.00
DELETE DELETE /v3/projects/:id (teardown) 1 0 148.00 148 148 0.03 0.00
DELETE DELETE /v3/roles/:id (teardown) 1 0 72.00 72 72 0.03 0.00
DELETE DELETE /v3/users/:id (teardown) 2 0 123.50 71 176 0.07 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 1 0 226.00 226 226 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 1 0 79.00 79 79 0.03 0.00
GET 610 0 578.86 293 861 20.33 0.00
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 2022 2022 14.51 1 748 67.40 67.40
GET GET /v3/auth/tokens (validate new) 45 0 549.42 300 716 1.50 0.00
GET GET /v3/auth/tokens (validate revoked) 46 0 477.20 41 666 1.53 0.00
GET GET /v3/projects/:id 57 0 538.82 290 704 1.90 0.00
GET GET /v3/projects/:id (catalog) 83 0 544.43 320 749 2.77 0.00
GET GET /v3/role_assignments 42 0 584.36 318 799 1.40 0.00
GET GET /v3/role_assignments?role.id 43 0 538.95 387 676 1.43 0.00
GET GET /v3/role_assignments?scope.domain.id 42 0 491.45 352 615 1.40 0.00
GET GET /v3/role_assignments?user.id 42 0 551.69 331 728 1.40 0.00
GET GET /v3/roles 112 0 544.81 301 741 3.73 0.00
GET GET /v3/roles/:id 57 0 532.33 283 799 1.90 0.00
GET GET /v3/users/:id 108 0 567.06 328 736 3.60 0.00
GET GET /v3/users/:id (catalog) 104 0 573.25 346 830 3.47 0.00
GET GET /v4/api-keys 27 0 546.07 386 761 0.90 0.00
GET GET /v4/api-keys/:client_id 26 0 609.65 403 775 0.87 0.00
GET GET /v4/mappings/rulesets 28 0 539.00 393 746 0.93 0.00
GET GET /v4/mappings/rulesets/:mapping_id 29 0 537.31 382 766 0.97 0.00
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 889 0 51.06 11 195 29.63 0.00
GET GET /v4/oauth2/:domain_id/clients 29 0 541.55 344 699 0.97 0.00
GET GET /v4/oauth2/:domain_id/clients/:provider_id 28 0 538.71 330 679 0.93 0.00
GET GET /v4/oauth2/:domain_id/jwks 888 0 49.60 10 177 29.60 0.00
GET GET /v4/scim_realms 19 0 506.05 320 758 0.63 0.00
GET GET /v4/scim_realms/:domain_id/:provider_id 19 0 549.63 363 722 0.63 0.00
POST POST /v3/auth/tokens 44 0 493.02 298 683 1.47 0.00
POST POST /v3/auth/tokens (password, invalid) 32 0 992.34 613 1588 1.07 0.00
POST POST /v3/auth/tokens (password, project-scoped) 50 0 1337.66 624 1959 1.67 0.00
POST POST /v3/auth/tokens (password, unscoped) 52 0 1117.23 690 1758 1.73 0.00
POST POST /v3/auth/tokens (rescope to system) 100 0 612.94 313 836 3.33 0.00
POST POST /v3/auth/tokens (rescope, invalid project) 61 0 501.48 258 700 2.03 0.00
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 48 0 1291.00 817 2075 1.60 0.00
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 0 258.00 258 258 0.03 0.00
PUT PUT /v4/scim_realms/:domain_id/:provider_id 18 0 587.89 292 776 0.60 0.00
Aggregated 5852 2022 235.53 1 2075 195.07 67.40

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 600 600 600 600 700 700 700 700
DELETE DELETE /v3/projects/:id (teardown) 148 148 148 148 148 148 148 148
DELETE DELETE /v3/roles/:id (teardown) 72 72 72 72 72 72 72 72
DELETE DELETE /v3/users/:id (teardown) 71 71 71 176 176 176 176 176
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 226 226 226 226 226 226 226 226
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 79 79 79 79 79 79 79 79
GET 600 600 600 700 700 700 800 861
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 7 8 9 12 16 22 330 700
GET GET /v3/auth/tokens (validate new) 500 600 600 600 700 700 700 700
GET GET /v3/auth/tokens (validate revoked) 500 500 500 600 600 600 666 666
GET GET /v3/projects/:id 500 600 600 600 600 700 700 700
GET GET /v3/projects/:id (catalog) 500 600 600 600 600 700 700 700
GET GET /v3/role_assignments 600 600 600 700 700 700 799 799
GET GET /v3/role_assignments?role.id 500 500 600 600 600 676 676 676
GET GET /v3/role_assignments?scope.domain.id 470 500 500 600 600 600 600 600
GET GET /v3/role_assignments?user.id 500 600 600 600 700 700 700 700
GET GET /v3/roles 500 600 600 600 700 700 700 700
GET GET /v3/roles/:id 500 600 600 600 600 700 700 799
GET GET /v3/users/:id 600 600 600 600 700 700 700 700
GET GET /v3/users/:id (catalog) 600 600 600 600 700 700 800 800
GET GET /v4/api-keys 500 600 600 600 700 700 761 761
GET GET /v4/api-keys/:client_id 600 600 600 700 700 700 775 775
GET GET /v4/mappings/rulesets 500 600 600 600 600 700 700 700
GET GET /v4/mappings/rulesets/:mapping_id 500 600 600 600 600 700 766 766
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 45 51 61 69 85 100 150 195
GET GET /v4/oauth2/:domain_id/clients 500 600 600 600 600 699 699 699
GET GET /v4/oauth2/:domain_id/clients/:provider_id 500 600 600 600 679 679 679 679
GET GET /v4/oauth2/:domain_id/jwks 42 49 58 70 85 100 140 177
GET GET /v4/scim_realms 500 500 500 600 600 600 758 758
GET GET /v4/scim_realms/:domain_id/:provider_id 500 600 600 600 600 700 700 700
POST POST /v3/auth/tokens 470 490 500 600 600 683 683 683
POST POST /v3/auth/tokens (password, invalid) 1,000 1,000 1,000 1,000 1,000 1,000 1,588 1,588
POST POST /v3/auth/tokens (password, project-scoped) 1,000 1,000 1,000 1,959 1,959 1,959 1,959 1,959
POST POST /v3/auth/tokens (password, unscoped) 1,000 1,000 1,000 1,000 1,000 1,000 1,758 1,758
POST POST /v3/auth/tokens (rescope to system) 600 600 700 700 700 800 800 800
POST POST /v3/auth/tokens (rescope, invalid project) 500 500 600 600 600 600 700 700
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 1,000 1,000 1,000 2,000 2,000 2,000 2,000 2,000
POST POST /v4/api-keys/:client_id/revoke (teardown) 258 258 258 258 258 258 258 258
PUT PUT /v4/scim_realms/:domain_id/:provider_id 600 600 600 700 700 700 776 776
Aggregated 46 76 460 600 600 700 1,000 2,000

Status Code Metrics

Method Name Status Codes
DELETE DELETE /v3/auth/tokens 45 [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 610 [200]
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 31 [401], 1,991 [429]
GET GET /v3/auth/tokens (validate new) 45 [200]
GET GET /v3/auth/tokens (validate revoked) 46 [404]
GET GET /v3/projects/:id 57 [200]
GET GET /v3/projects/:id (catalog) 83 [200]
GET GET /v3/role_assignments 42 [200]
GET GET /v3/role_assignments?role.id 43 [200]
GET GET /v3/role_assignments?scope.domain.id 42 [200]
GET GET /v3/role_assignments?user.id 42 [200]
GET GET /v3/roles 112 [200]
GET GET /v3/roles/:id 57 [200]
GET GET /v3/users/:id 108 [200]
GET GET /v3/users/:id (catalog) 104 [200]
GET GET /v4/api-keys 27 [200]
GET GET /v4/api-keys/:client_id 26 [200]
GET GET /v4/mappings/rulesets 28 [200]
GET GET /v4/mappings/rulesets/:mapping_id 29 [200]
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 889 [200]
GET GET /v4/oauth2/:domain_id/clients 29 [200]
GET GET /v4/oauth2/:domain_id/clients/:provider_id 28 [200]
GET GET /v4/oauth2/:domain_id/jwks 888 [200]
GET GET /v4/scim_realms 19 [200]
GET GET /v4/scim_realms/:domain_id/:provider_id 19 [200]
POST POST /v3/auth/tokens 44 [201]
POST POST /v3/auth/tokens (password, invalid) 32 [401]
POST POST /v3/auth/tokens (password, project-scoped) 50 [201]
POST POST /v3/auth/tokens (password, unscoped) 52 [201]
POST POST /v3/auth/tokens (rescope to system) 100 [201]
POST POST /v3/auth/tokens (rescope, invalid project) 61 [401]
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 48 [201]
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 [200]
PUT PUT /v4/scim_realms/:domain_id/:provider_id 18 [200]
Aggregated 1,991 [429], 3,346 [200], 124 [401], 46 [404], 51 [204], 294 [201]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
ReadHeavy
0.0 1 0 51.00 51 51 0.03 0.00
0.1 108 0 588.36 328 858 3.60 0.00
0.2 108 0 548.25 293 753 3.60 0.00
0.3 108 0 555.78 296 753 3.60 0.00
TokenLifecycle
1.0 0 0 0.00 0 0 0.00 0.00
1.1 46 0 2051.83 965 2570 1.53 0.00
ValidateToken
2.0 0 0 0.00 0 0 0.00 0.00
2.1 96 0 641.16 346 861 3.20 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 108 0 567.09 328 737 3.60 0.00
3.3 2 0 123.50 71 176 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 57 0 538.84 290 704 1.90 0.00
4.3 1 0 148.00 148 148 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 57 0 532.35 283 799 1.90 0.00
5.3 1 0 72.00 72 72 0.03 0.00
RoleList
6.0 0 0 0.00 0 0 0.00 0.00
6.1 112 0 544.86 301 741 3.73 0.00
RoleAssignmentList
7.0 0 0 0.00 0 0 0.00 0.00
7.1 42 0 584.40 318 799 1.40 0.00
7.2 42 0 551.71 331 728 1.40 0.00
7.3 42 0 491.45 352 615 1.40 0.00
7.4 43 0 538.98 387 676 1.43 0.00
UserRead
8.0 0 0 0.00 0 0 0.00 0.00
8.1 106 0 590.74 322 822 3.53 0.00
8.2 104 0 573.28 346 830 3.47 0.00
ProjectRead
9.0 0 0 0.00 0 0 0.00 0.00
9.1 84 0 549.82 295 742 2.80 0.00
9.2 83 0 544.45 320 749 2.77 0.00
PasswordAuth
10.0 52 0 1117.27 690 1758 1.73 0.00
10.1 50 0 1337.68 624 1959 1.67 0.00
PasswordAuthNegative
11.0 32 0 992.41 613 1588 1.07 0.00
Rescope
12.0 0 0 0.00 0 0 0.00 0.00
12.1 100 0 612.96 313 836 3.33 0.00
RescopeNegative
13.0 0 0 0.00 0 0 0.00 0.00
13.1 61 0 501.56 258 700 2.03 0.00
SystemScopeAuth
14.0 48 0 1291.02 817 2075 1.60 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 26 0 609.77 403 775 0.87 0.00
15.3 27 0 546.07 386 761 0.90 0.00
15.4 1 0 258.00 258 258 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 29 0 537.38 382 766 0.97 0.00
16.3 28 0 539.11 393 746 0.93 0.00
16.4 1 0 226.00 226 226 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 28 0 538.75 330 679 0.93 0.00
17.3 29 0 541.55 344 699 0.97 0.00
17.4 1 0 79.00 79 79 0.03 0.00
OAuth2Discovery
18.0 888 0 49.63 10 177 29.60 0.00
18.1 889 0 51.08 11 195 29.63 0.00
ScimRealmRead
19.0 0 0 0.00 0 0 0.00 0.00
19.1 19 0 549.63 363 722 0.63 0.00
19.2 19 0 506.05 320 758 0.63 0.00
19.3 18 0 587.94 292 776 0.60 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 2022 0 14.54 1 748 67.40 0.00
20.4 2021 0 0.00 0 0 67.37 0.00
20.5 2021 0 0.00 0 0 67.37 0.00
20.6 1 0 0.00 0 0 0.03 0.00
Aggregated 9762 0 141.19 1 2570 325.40 0.00

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
ReadHeavy 6 105 1698.88 1251 1997 3.50 17.50
TokenLifecycle 3 43 2110.02 1822 2570 1.43 14.33
ValidateToken 2 94 646.93 346 861 3.13 47.00
UserCRUD 2 106 569.49 367 737 3.53 53.00
ProjectCRUD 1 56 538.73 290 704 1.87 56.00
RoleCRUD 1 56 536.80 324 799 1.87 56.00
RoleList 2 110 547.20 301 741 3.67 55.00
RoleAssignmentList 3 41 2168.46 1863 2477 1.37 13.67
UserRead 4 103 1170.40 866 1507 3.43 25.75
ProjectRead 3 82 1101.34 841 1456 2.73 27.33
PasswordAuth 4 49 2450.59 1749 3294 1.63 12.25
PasswordAuthNegative 1 31 1003.10 613 1588 1.03 31.00
Rescope 2 98 616.40 396 836 3.27 49.00
RescopeNegative 1 60 504.85 258 700 2.00 60.00
SystemScopeAuth 2 46 1283.80 817 2075 1.53 23.00
ApiKeyCRUD 1 26 1153.69 897 1349 0.87 26.00
MappingCRUD 1 28 1080.07 841 1392 0.93 28.00
OAuth2ClientCRUD 1 28 1085.89 739 1270 0.93 28.00
OAuth2Discovery 3 887 101.13 26 256 29.57 295.67
ScimRealmRead 1 18 1660.67 1379 2003 0.60 18.00
ScimSync 1 2021 14.34 1 748 67.37 2021.00
Aggregated 45 4088 330.39 1 3294 136.27 2957.50

Error Metrics

Method Name # Error
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 49 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) 72 401 Unauthorized: POST /v3/auth/tokens (password, invalid)
POST POST /v3/auth/tokens (rescope, invalid project) 160 401 Unauthorized: POST /v3/auth/tokens (rescope, invalid project)
GET GET /v3/auth/tokens (validate revoked) 160 404 Not Found: GET /v3/auth/tokens (validate revoked)
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 2110 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
129,500.00 ns
(-49.78%)Baseline: 257,849.81 ns
1,308,205.78 ns
(9.90%)
Command_Serde/apply/set📈 view plot
🚷 view threshold
145,170.00 ns
(-65.12%)Baseline: 416,221.62 ns
3,206,133.85 ns
(4.53%)
Command_Serde/pack/delete📈 view plot
🚷 view threshold
120.62 ns
(+2.47%)Baseline: 117.71 ns
152.62 ns
(79.03%)
Command_Serde/pack/delete_index📈 view plot
🚷 view threshold
108.16 ns
(+3.06%)Baseline: 104.95 ns
135.21 ns
(79.99%)
Command_Serde/pack/set📈 view plot
🚷 view threshold
198.46 ns
(+4.10%)Baseline: 190.64 ns
241.12 ns
(82.31%)
Command_Serde/pack/set_index📈 view plot
🚷 view threshold
108.65 ns
(+3.56%)Baseline: 104.91 ns
135.77 ns
(80.03%)
Command_Serde/unpack/delete📈 view plot
🚷 view threshold
195.38 ns
(+4.53%)Baseline: 186.91 ns
268.30 ns
(72.82%)
Command_Serde/unpack/delete_index📈 view plot
🚷 view threshold
156.80 ns
(+0.86%)Baseline: 155.46 ns
217.04 ns
(72.24%)
Command_Serde/unpack/set📈 view plot
🚷 view threshold
296.97 ns
(+12.44%)Baseline: 264.12 ns
360.38 ns
(82.40%)
Command_Serde/unpack/set_index📈 view plot
🚷 view threshold
155.30 ns
(+1.44%)Baseline: 153.09 ns
211.63 ns
(73.38%)
Payload_encryption/pack/remove_cmd📈 view plot
🚷 view threshold
115.43 ns
(+2.90%)Baseline: 112.17 ns
148.65 ns
(77.65%)
Payload_encryption/pack/set_cmd📈 view plot
🚷 view threshold
205.30 ns
(+2.99%)Baseline: 199.34 ns
262.06 ns
(78.34%)
Payload_encryption/unpack/remove_cmd📈 view plot
🚷 view threshold
204.66 ns
(+4.61%)Baseline: 195.64 ns
282.55 ns
(72.43%)
Payload_encryption/unpack/set_cmd📈 view plot
🚷 view threshold
301.84 ns
(+10.47%)Baseline: 273.22 ns
375.99 ns
(80.28%)
Raft_1Node_Latency/prefix/1node📈 view plot
🚷 view threshold
2,552,300.00 ns
(-16.98%)Baseline: 3,074,491.23 ns
7,924,629.46 ns
(32.21%)
Raft_1Node_Latency/read/1node📈 view plot
🚷 view threshold
42,883.00 ns
(+14.56%)Baseline: 37,432.14 ns
51,665.48 ns
(83.00%)
Raft_1Node_Latency/remove/1node📈 view plot
🚷 view threshold
383,460.00 ns
(-67.38%)Baseline: 1,175,686.72 ns
11,499,900.76 ns
(3.33%)
Raft_1Node_Latency/write/1node📈 view plot
🚷 view threshold
397,090.00 ns
(-59.36%)Baseline: 977,114.22 ns
7,555,767.72 ns
(5.26%)
build_snapshot/default📈 view plot
🚷 view threshold
117,430.00 ns
(-4.52%)Baseline: 122,988.55 ns
268,765.34 ns
(43.69%)
fernet token/project📈 view plot
🚷 view threshold
1,474.20 ns
(+3.56%)Baseline: 1,423.53 ns
1,795.59 ns
(82.10%)
get_data_keyspace📈 view plot
🚷 view threshold
0.31 ns
(-0.16%)Baseline: 0.31 ns
0.39 ns
(81.55%)
get_db📈 view plot
🚷 view threshold
0.32 ns
(+1.26%)Baseline: 0.32 ns
0.39 ns
(82.82%)
get_fernet_token_timestamp/project📈 view plot
🚷 view threshold
148.88 ns
(+6.15%)Baseline: 140.25 ns
180.02 ns
(82.70%)
get_keyspace📈 view plot
🚷 view threshold
4.43 ns
(-24.47%)Baseline: 5.87 ns
13.51 ns
(32.81%)
🐰 View full continuous benchmarking report in Bencher

Merged via the queue into main with commit 3bcfb81 Sep 8, 2026
36 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