Skip to content

feat: Hot-reload fs per-domain config files - #1225

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

feat: Hot-reload fs per-domain config files#1225
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 fs domain-config driver read its directory once at startup and
held it immutably, so an operator's edit to a keystone.<name>.conf
including a per-domain assignment/driver binding (ADR 0034) — took
effect only after a restart, while the DB source already hot-reloads.

  • DomainConfigStore behind an ArcSwap; DomainConfigBackend::reload
    re-scans [identity] domain_config_dir on a blocking thread and swaps
    it in, defaulting to a no-op for sql (nothing cached).
  • ConfigManager watches domain_config_dir when it exists and now
    also reacts to removals, so an edit or a deletion under it fires the
    reload notification.
  • AssignmentService::rebuild re-scans the captured fs handle before
    it enumerates the bound domains; a scan error is logged and the last
    good scan is kept.

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

The `fs` domain-config driver read its directory once at startup and
held it immutably, so an operator's edit to a `keystone.<name>.conf` —
including a per-domain `assignment/driver` binding (ADR 0034) — took
effect only after a restart, while the DB source already hot-reloads.

- `DomainConfigStore` behind an `ArcSwap`; `DomainConfigBackend::reload`
  re-scans `[identity] domain_config_dir` on a blocking thread and swaps
  it in, defaulting to a no-op for `sql` (nothing cached).
- `ConfigManager` watches `domain_config_dir` when it exists and now
  also reacts to removals, so an edit or a deletion under it fires the
  reload notification.
- `AssignmentService::rebuild` re-scans the captured `fs` handle before
  it enumerates the bound domains; a scan error is logged and the last
  good scan is kept.

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 30.1809 sec.
 - Passed: 66
 - Skipped: 4
 - Expected Fail: 0
 - Unexpected Success: 0
 - Failed: 63
Sum of execute time for each test: 22.1882 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_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_default_project_id.TestDefaultProjectId.test_default_project_id[id-d6110661-6a71-49a7-a453-b5e26640ff6d]
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_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_domains.DomainsTestJSON.test_create_update_delete_domain[id-f2f5b44a-82e8-4dad-8084-0661ea3b18cf,smoke]
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_domains.DomainsTestJSON.test_domain_delete_cascades_content[id-d8d318b7-d1b3-4c37-94c5-3c5ba0b121ea]
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_list_domains_filter_by_enabled[id-3fd19840-65c1-43f8-b48c-51bdd066dff9]
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_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_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]
setUpClass (tempest.api.identity.admin.v3.test_endpoint_groups.EndPointGroupsTest)
tempest.api.identity.admin.v3.test_project_tags.IdentityV3ProjectTagsTest.test_list_update_delete_project_tags[id-7c123aac-999d-416a-a0fb-84b915ab10de]
tempest.api.identity.admin.v3.test_list_projects.ListProjectsStaticTestJSON.test_list_projects[id-1d830662-22ad-427c-8c3e-4ec854b0af44]
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_projects.ProjectsTestJSON.test_create_is_domain_project[id-a7eb9416-6f9b-4dbb-b71b-7f73aaef59d5]
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_groups.GroupsV3TestJSON.test_list_user_groups[id-64573281-d26a-4a52-b899-503cb0f4e4ec]
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_users_negative.UsersNegativeTest.test_create_user_for_non_existent_domain[id-e75f006c-89cc-477b-874d-588e4eab4b17,negative]
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_users.UsersV3TestJSON.test_list_user_projects[id-a831e70c-e35b-430b-92ed-81ebbc5437b8]
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_tokens.TokensV3TestJSON.test_get_available_domain_scopes[id-ec5ecb05-af64-4c04-ac86-4d9f6f12f185]
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_rescope_token[id-565fa210-1da1-4563-999b-f7b5b67cf112]
tempest.api.identity.v3.test_catalog.IdentityCatalogTest.test_catalog_standardization[id-56b57ced-22b8-4127-9b8a-565dfb0207e2]
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.admin.v3.test_trusts.TrustsV3TestJSON.test_get_trusts_all[id-4773ebd5-ecbf-4255-b8d8-b63e6f72b65d,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_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.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.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 17:11:09 26-09-08 17:11:32 00:00:23 0 → 45
Maintaining 26-09-08 17:11:32 26-09-08 17:12:02 00:00:30 45
Decreasing 26-09-08 17:12:02 26-09-08 17:12:03 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 57 0 420.07 71 565 1.90 0.00
DELETE DELETE /v3/projects/:id (teardown) 1 0 92.00 92 92 0.03 0.00
DELETE DELETE /v3/roles/:id (teardown) 1 0 83.00 83 83 0.03 0.00
DELETE DELETE /v3/users/:id (teardown) 2 0 91.00 72 110 0.07 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 1 0 245.00 245 245 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 1 0 77.00 77 77 0.03 0.00
GET 794 0 442.68 244 798 26.47 0.00
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 2897 2897 9.86 1 677 96.57 96.57
GET GET /v3/auth/tokens (validate new) 57 0 402.35 275 503 1.90 0.00
GET GET /v3/auth/tokens (validate revoked) 59 0 376.39 19 531 1.97 0.00
GET GET /v3/projects/:id 74 0 410.72 255 664 2.47 0.00
GET GET /v3/projects/:id (catalog) 108 0 408.71 249 612 3.60 0.00
GET GET /v3/role_assignments 54 0 439.26 288 644 1.80 0.00
GET GET /v3/role_assignments?role.id 55 0 402.65 290 537 1.83 0.00
GET GET /v3/role_assignments?scope.domain.id 57 0 395.98 278 515 1.90 0.00
GET GET /v3/role_assignments?user.id 56 0 401.00 274 540 1.87 0.00
GET GET /v3/roles 147 0 412.97 216 671 4.90 0.00
GET GET /v3/roles/:id 75 0 407.96 271 586 2.50 0.00
GET GET /v3/users/:id 141 0 433.21 210 672 4.70 0.00
GET GET /v3/users/:id (catalog) 138 0 427.18 233 612 4.60 0.00
GET GET /v4/api-keys 35 0 429.14 307 645 1.17 0.00
GET GET /v4/api-keys/:client_id 36 0 432.67 291 706 1.20 0.00
GET GET /v4/mappings/rulesets 36 0 433.97 291 662 1.20 0.00
GET GET /v4/mappings/rulesets/:mapping_id 36 0 406.53 272 565 1.20 0.00
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 1042 0 43.19 6 247 34.73 0.00
GET GET /v4/oauth2/:domain_id/clients 36 0 409.92 271 616 1.20 0.00
GET GET /v4/oauth2/:domain_id/clients/:provider_id 37 0 426.68 181 613 1.23 0.00
GET GET /v4/oauth2/:domain_id/jwks 1043 0 42.49 6 249 34.77 0.00
GET GET /v4/scim_realms 21 0 417.67 269 610 0.70 0.00
GET GET /v4/scim_realms/:domain_id/:provider_id 22 0 431.50 299 593 0.73 0.00
POST POST /v3/auth/tokens 56 0 395.46 268 530 1.87 0.00
POST POST /v3/auth/tokens (password, invalid) 41 0 745.83 403 1197 1.37 0.00
POST POST /v3/auth/tokens (password, project-scoped) 68 0 1005.15 696 1518 2.27 0.00
POST POST /v3/auth/tokens (password, unscoped) 66 0 815.53 459 1253 2.20 0.00
POST POST /v3/auth/tokens (rescope to system) 130 0 468.64 287 697 4.33 0.00
POST POST /v3/auth/tokens (rescope, invalid project) 79 0 384.47 247 625 2.63 0.00
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 61 0 1019.39 678 1476 2.03 0.00
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 0 297.00 297 297 0.03 0.00
PUT PUT /v4/scim_realms/:domain_id/:provider_id 22 0 543.50 371 761 0.73 0.00
Aggregated 7643 2897 178.75 1 1518 254.77 96.57

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 420 430 460 490 500 500 565 565
DELETE DELETE /v3/projects/:id (teardown) 92 92 92 92 92 92 92 92
DELETE DELETE /v3/roles/:id (teardown) 83 83 83 83 83 83 83 83
DELETE DELETE /v3/users/:id (teardown) 72 72 72 110 110 110 110 110
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 245 245 245 245 245 245 245 245
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 77 77 77 77 77 77 77 77
GET 440 460 480 500 500 600 600 798
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 5 6 7 9 13 16 220 677
GET GET /v3/auth/tokens (validate new) 410 420 440 450 480 490 500 500
GET GET /v3/auth/tokens (validate revoked) 370 400 410 450 470 500 500 500
GET GET /v3/projects/:id 410 430 440 460 490 500 600 664
GET GET /v3/projects/:id (catalog) 410 430 450 460 490 500 600 600
GET GET /v3/role_assignments 420 450 470 490 500 500 600 600
GET GET /v3/role_assignments?role.id 400 420 430 450 470 490 500 500
GET GET /v3/role_assignments?scope.domain.id 400 410 420 440 470 480 500 500
GET GET /v3/role_assignments?user.id 400 420 440 450 480 500 500 500
GET GET /v3/roles 420 430 450 470 500 500 600 671
GET GET /v3/roles/:id 410 430 440 460 490 500 586 586
GET GET /v3/users/:id 430 460 470 480 500 500 672 672
GET GET /v3/users/:id (catalog) 440 450 470 480 500 500 600 600
GET GET /v4/api-keys 420 430 460 480 500 500 600 600
GET GET /v4/api-keys/:client_id 430 440 460 480 490 600 700 700
GET GET /v4/mappings/rulesets 430 440 460 490 500 500 662 662
GET GET /v4/mappings/rulesets/:mapping_id 400 420 430 460 480 500 565 565
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 35 41 50 62 78 99 150 247
GET GET /v4/oauth2/:domain_id/clients 410 420 430 460 500 500 600 600
GET GET /v4/oauth2/:domain_id/clients/:provider_id 410 450 470 480 500 500 600 600
GET GET /v4/oauth2/:domain_id/jwks 34 41 49 61 78 91 130 249
GET GET /v4/scim_realms 410 410 440 470 500 500 600 600
GET GET /v4/scim_realms/:domain_id/:provider_id 410 440 460 500 500 500 593 593
POST POST /v3/auth/tokens 390 410 420 440 470 480 500 500
POST POST /v3/auth/tokens (password, invalid) 700 800 800 900 900 1,000 1,000 1,000
POST POST /v3/auth/tokens (password, project-scoped) 1,000 1,000 1,000 1,000 1,000 1,000 1,000 1,518
POST POST /v3/auth/tokens (password, unscoped) 800 900 900 1,000 1,000 1,000 1,000 1,000
POST POST /v3/auth/tokens (rescope to system) 470 490 500 500 500 600 697 697
POST POST /v3/auth/tokens (rescope, invalid project) 390 400 400 420 450 460 500 600
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 1,000 1,000 1,000 1,000 1,000 1,000 1,000 1,000
POST POST /v4/api-keys/:client_id/revoke (teardown) 297 297 297 297 297 297 297 297
PUT PUT /v4/scim_realms/:domain_id/:provider_id 500 500 600 600 700 700 761 761
Aggregated 33 65 350 420 480 500 1,000 1,518

Status Code Metrics

Method Name Status Codes
DELETE DELETE /v3/auth/tokens 57 [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 794 [200]
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 2,867 [429], 30 [401]
GET GET /v3/auth/tokens (validate new) 57 [200]
GET GET /v3/auth/tokens (validate revoked) 59 [404]
GET GET /v3/projects/:id 74 [200]
GET GET /v3/projects/:id (catalog) 108 [200]
GET GET /v3/role_assignments 54 [200]
GET GET /v3/role_assignments?role.id 55 [200]
GET GET /v3/role_assignments?scope.domain.id 57 [200]
GET GET /v3/role_assignments?user.id 56 [200]
GET GET /v3/roles 147 [200]
GET GET /v3/roles/:id 75 [200]
GET GET /v3/users/:id 141 [200]
GET GET /v3/users/:id (catalog) 138 [200]
GET GET /v4/api-keys 35 [200]
GET GET /v4/api-keys/:client_id 36 [200]
GET GET /v4/mappings/rulesets 36 [200]
GET GET /v4/mappings/rulesets/:mapping_id 36 [200]
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 1,042 [200]
GET GET /v4/oauth2/:domain_id/clients 36 [200]
GET GET /v4/oauth2/:domain_id/clients/:provider_id 37 [200]
GET GET /v4/oauth2/:domain_id/jwks 1,043 [200]
GET GET /v4/scim_realms 21 [200]
GET GET /v4/scim_realms/:domain_id/:provider_id 22 [200]
POST POST /v3/auth/tokens 56 [201]
POST POST /v3/auth/tokens (password, invalid) 41 [401]
POST POST /v3/auth/tokens (password, project-scoped) 68 [201]
POST POST /v3/auth/tokens (password, unscoped) 66 [201]
POST POST /v3/auth/tokens (rescope to system) 130 [201]
POST POST /v3/auth/tokens (rescope, invalid project) 79 [401]
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 61 [201]
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 [200]
PUT PUT /v4/scim_realms/:domain_id/:provider_id 22 [200]
Aggregated 4,123 [200], 2,867 [429], 59 [404], 381 [201], 150 [401], 63 [204]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
ReadHeavy
0.0 1 0 11.00 11 11 0.03 0.00
0.1 142 0 447.15 244 685 4.73 0.00
0.2 139 0 423.36 278 692 4.63 0.00
0.3 142 0 417.84 271 684 4.73 0.00
TokenLifecycle
1.0 0 0 0.00 0 0 0.00 0.00
1.1 59 0 1591.36 663 1933 1.97 0.00
ValidateToken
2.0 0 0 0.00 0 0 0.00 0.00
2.1 123 0 493.24 351 798 4.10 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 141 0 433.22 210 672 4.70 0.00
3.3 2 0 91.00 72 110 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 74 0 410.73 255 664 2.47 0.00
4.3 1 0 92.00 92 92 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 75 0 407.97 271 586 2.50 0.00
5.3 1 0 83.00 83 83 0.03 0.00
RoleList
6.0 0 0 0.00 0 0 0.00 0.00
6.1 147 0 412.99 216 671 4.90 0.00
RoleAssignmentList
7.0 0 0 0.00 0 0 0.00 0.00
7.1 54 0 439.26 288 644 1.80 0.00
7.2 56 0 401.05 274 540 1.87 0.00
7.3 57 0 395.98 278 515 1.90 0.00
7.4 55 0 402.65 290 537 1.83 0.00
UserRead
8.0 0 0 0.00 0 0 0.00 0.00
8.1 138 0 453.25 256 705 4.60 0.00
8.2 138 0 427.21 233 613 4.60 0.00
ProjectRead
9.0 0 0 0.00 0 0 0.00 0.00
9.1 110 0 423.83 256 546 3.67 0.00
9.2 108 0 408.75 249 612 3.60 0.00
PasswordAuth
10.0 66 0 815.55 459 1253 2.20 0.00
10.1 68 0 1005.15 696 1518 2.27 0.00
PasswordAuthNegative
11.0 41 0 745.88 403 1197 1.37 0.00
Rescope
12.0 0 0 0.00 0 0 0.00 0.00
12.1 130 0 468.69 287 697 4.33 0.00
RescopeNegative
13.0 0 0 0.00 0 0 0.00 0.00
13.1 79 0 384.48 247 625 2.63 0.00
SystemScopeAuth
14.0 61 0 1019.46 679 1476 2.03 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 36 0 432.67 291 706 1.20 0.00
15.3 35 0 429.23 307 645 1.17 0.00
15.4 1 0 297.00 297 297 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 36 0 406.56 272 565 1.20 0.00
16.3 36 0 434.03 291 662 1.20 0.00
16.4 1 0 245.00 245 245 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 37 0 426.70 181 613 1.23 0.00
17.3 36 0 409.94 271 616 1.20 0.00
17.4 1 0 77.00 77 77 0.03 0.00
OAuth2Discovery
18.0 1043 0 42.51 6 249 34.77 0.00
18.1 1042 0 43.22 6 247 34.73 0.00
ScimRealmRead
19.0 0 0 0.00 0 0 0.00 0.00
19.1 22 0 431.50 299 593 0.73 0.00
19.2 21 0 417.67 269 610 0.70 0.00
19.3 22 0 543.55 371 761 0.73 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 2897 0 9.88 1 677 96.57 0.00
20.4 2896 0 0.00 0 0 96.53 0.00
20.5 2896 0 0.00 0 0 96.53 0.00
20.6 1 0 0.00 0 0 0.03 0.00
Aggregated 13267 0 102.98 1 1933 442.23 0.00

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
ReadHeavy 6 140 1294.64 1042 1737 4.67 23.33
TokenLifecycle 3 56 1620.55 1310 1933 1.87 18.67
ValidateToken 2 121 494.83 351 798 4.03 60.50
UserCRUD 2 139 435.53 278 672 4.63 69.50
ProjectCRUD 1 73 411.78 255 664 2.43 73.00
RoleCRUD 1 74 409.82 298 586 2.47 74.00
RoleList 2 145 414.74 258 671 4.83 72.50
RoleAssignmentList 3 54 1648.94 1409 1874 1.80 18.00
UserRead 4 136 887.00 661 1163 4.53 34.00
ProjectRead 3 107 837.86 618 1048 3.57 35.67
PasswordAuth 4 65 1824.32 1224 2501 2.17 16.25
PasswordAuthNegative 1 40 749.70 403 1197 1.33 40.00
Rescope 2 128 470.80 287 697 4.27 64.00
RescopeNegative 1 78 385.72 247 625 2.60 78.00
SystemScopeAuth 2 59 1020.17 679 1476 1.97 29.50
ApiKeyCRUD 1 35 866.40 651 1126 1.17 35.00
MappingCRUD 1 36 844.42 612 1188 1.20 36.00
OAuth2ClientCRUD 1 36 843.92 630 1022 1.20 36.00
OAuth2Discovery 3 1041 86.23 14 294 34.70 347.00
ScimRealmRead 1 22 1397.41 1191 1730 0.73 22.00
ScimSync 1 2896 9.89 1 677 96.53 2896.00
Aggregated 45 5481 246.60 1 2501 182.70 4078.92

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) 98 401 Unauthorized: POST /v3/auth/tokens (password, invalid)
POST POST /v3/auth/tokens (rescope, invalid project) 204 401 Unauthorized: POST /v3/auth/tokens (rescope, invalid project)
GET GET /v3/auth/tokens (validate revoked) 216 404 Not Found: GET /v3/auth/tokens (validate revoked)
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 3054 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
229,910.00 ns
(-11.40%)Baseline: 259,485.44 ns
1,311,010.78 ns
(17.54%)
Command_Serde/apply/set📈 view plot
🚷 view threshold
251,380.00 ns
(-40.05%)Baseline: 419,296.16 ns
3,209,842.62 ns
(7.83%)
Command_Serde/pack/delete📈 view plot
🚷 view threshold
121.89 ns
(+4.15%)Baseline: 117.04 ns
154.98 ns
(78.65%)
Command_Serde/pack/delete_index📈 view plot
🚷 view threshold
109.71 ns
(+5.10%)Baseline: 104.39 ns
137.28 ns
(79.92%)
Command_Serde/pack/set📈 view plot
🚷 view threshold
212.92 ns
(+12.18%)Baseline: 189.80 ns
245.68 ns
(86.67%)
Command_Serde/pack/set_index📈 view plot
🚷 view threshold
109.31 ns
(+4.73%)Baseline: 104.37 ns
137.64 ns
(79.42%)
Command_Serde/unpack/delete📈 view plot
🚷 view threshold
199.91 ns
(+7.42%)Baseline: 186.10 ns
270.84 ns
(73.81%)
Command_Serde/unpack/delete_index📈 view plot
🚷 view threshold
159.74 ns
(+3.15%)Baseline: 154.85 ns
219.27 ns
(72.85%)
Command_Serde/unpack/set📈 view plot
🚷 view threshold
305.76 ns
(+16.24%)Baseline: 263.03 ns
365.63 ns
(83.63%)
Command_Serde/unpack/set_index📈 view plot
🚷 view threshold
156.57 ns
(+2.68%)Baseline: 152.49 ns
213.82 ns
(73.23%)
Payload_encryption/pack/remove_cmd📈 view plot
🚷 view threshold
116.62 ns
(+4.84%)Baseline: 111.24 ns
150.53 ns
(77.48%)
Payload_encryption/pack/set_cmd📈 view plot
🚷 view threshold
255.11 ns
(+28.44%)Baseline: 198.63 ns
266.76 ns
(95.63%)
Payload_encryption/unpack/remove_cmd📈 view plot
🚷 view threshold
212.49 ns
(+9.13%)Baseline: 194.72 ns
284.72 ns
(74.63%)
Payload_encryption/unpack/set_cmd📈 view plot
🚷 view threshold
305.61 ns
(+12.44%)Baseline: 271.80 ns
380.90 ns
(80.23%)
Raft_1Node_Latency/prefix/1node📈 view plot
🚷 view threshold
1,969,900.00 ns
(-35.41%)Baseline: 3,049,870.92 ns
7,880,083.15 ns
(25.00%)
Raft_1Node_Latency/read/1node📈 view plot
🚷 view threshold
39,430.00 ns
(+5.91%)Baseline: 37,231.41 ns
52,094.76 ns
(75.69%)
Raft_1Node_Latency/remove/1node📈 view plot
🚷 view threshold
580,630.00 ns
(-49.81%)Baseline: 1,156,778.12 ns
11,478,702.70 ns
(5.06%)
Raft_1Node_Latency/write/1node📈 view plot
🚷 view threshold
672,820.00 ns
(-30.20%)Baseline: 963,978.12 ns
7,540,761.93 ns
(8.92%)
build_snapshot/default📈 view plot
🚷 view threshold
100,900.00 ns
(-17.10%)Baseline: 121,715.58 ns
266,946.38 ns
(37.80%)
fernet token/project📈 view plot
🚷 view threshold
1,473.00 ns
(+4.11%)Baseline: 1,414.82 ns
1,817.56 ns
(81.04%)
get_data_keyspace📈 view plot
🚷 view threshold
0.31 ns
(-0.45%)Baseline: 0.31 ns
0.39 ns
(80.28%)
get_db📈 view plot
🚷 view threshold
0.31 ns
(-0.70%)Baseline: 0.31 ns
0.39 ns
(80.06%)
get_fernet_token_timestamp/project📈 view plot
🚷 view threshold
147.00 ns
(+5.39%)Baseline: 139.48 ns
181.99 ns
(80.77%)
get_keyspace📈 view plot
🚷 view threshold
4.36 ns
(-24.60%)Baseline: 5.79 ns
13.03 ns
(33.48%)
🐰 View full continuous benchmarking report in Bencher

Merged via the queue into main with commit e2f3743 Sep 8, 2026
39 of 40 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