Skip to content

feat(oauth2): Add DPoP binding data model - #1576

Merged
gtema merged 1 commit into
mainfrom
dpop
Oct 21, 2026
Merged

gtema merged 1 commit into
mainfrom
dpop

Conversation

@gtema

@gtema gtema commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

Add the cnf confirmation claim to the OAuth2 access tokens, the
dpop_jkt key thumbprint to authorization codes, refresh token families
and device grants, and the dpop_bound_access_tokens client flag, as
described in ADR 0043 sections 1 and 3.

A rotated refresh token keeps the binding of its family, and the
thumbprint is carried from the authorization code and device grant
into the refresh family. All new fields are trailing and defaulted,
so stored records stay readable.

Turning the client flag off, or revoking a client that has it on,
requires the admin role. Setting the flag to true is rejected for now
because issued tokens are not bound yet, so a client would be
believed sender-constrained while still receiving bearer tokens.

Assisted-by: Claude noreply@anthropic.com
Signed-off-by: Artem Goncharov artem.goncharov@gmail.com

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

🐰 Bencher Report

Projectkeystone
Branchdpop
Testbedubuntu-latest

🚨 1 Alert

BenchmarkMeasure
Units
ViewBenchmark Result
(Result Δ%)
Upper Boundary
(Limit %)
Raft_1Node_Latency/prefix/1nodeLatency
milliseconds (ms)
📈 plot
🚷 threshold
🚨 alert (🔔)
9.80 ms
(+170.58%)Baseline: 3.62 ms
8.70 ms
(112.74%)

Click to view all benchmark results
BenchmarkLatencyBenchmark Result
nanoseconds (ns)
(Result Δ%)
Upper Boundary
nanoseconds (ns)
(Limit %)
Command_Serde/apply/remove📈 view plot
🚷 view threshold
116,990.00 ns
(-14.36%)Baseline: 136,607.41 ns
262,080.74 ns
(44.64%)
Command_Serde/apply/set📈 view plot
🚷 view threshold
128,320.00 ns
(-10.04%)Baseline: 142,639.53 ns
248,027.41 ns
(51.74%)
Command_Serde/pack/delete📈 view plot
🚷 view threshold
141.02 ns
(+22.14%)Baseline: 115.46 ns
165.48 ns
(85.22%)
Command_Serde/pack/delete_index📈 view plot
🚷 view threshold
122.60 ns
(+18.03%)Baseline: 103.87 ns
145.65 ns
(84.17%)
Command_Serde/pack/set📈 view plot
🚷 view threshold
225.07 ns
(+20.62%)Baseline: 186.59 ns
272.33 ns
(82.65%)
Command_Serde/pack/set_index📈 view plot
🚷 view threshold
122.97 ns
(+17.92%)Baseline: 104.29 ns
147.48 ns
(83.38%)
Command_Serde/unpack/delete📈 view plot
🚷 view threshold
166.96 ns
(+15.43%)Baseline: 144.65 ns
217.24 ns
(76.85%)
Command_Serde/unpack/delete_index📈 view plot
🚷 view threshold
142.98 ns
(+16.56%)Baseline: 122.66 ns
183.19 ns
(78.05%)
Command_Serde/unpack/set📈 view plot
🚷 view threshold
267.02 ns
(+18.78%)Baseline: 224.80 ns
347.00 ns
(76.95%)
Command_Serde/unpack/set_index📈 view plot
🚷 view threshold
143.72 ns
(+17.78%)Baseline: 122.02 ns
180.95 ns
(79.43%)
Payload_encryption/pack/remove_cmd📈 view plot
🚷 view threshold
124.89 ns
(+16.42%)Baseline: 107.28 ns
160.97 ns
(77.59%)
Payload_encryption/pack/set_cmd📈 view plot
🚷 view threshold
216.65 ns
(+11.89%)Baseline: 193.63 ns
295.78 ns
(73.25%)
Payload_encryption/unpack/remove_cmd📈 view plot
🚷 view threshold
176.47 ns
(+20.32%)Baseline: 146.67 ns
218.45 ns
(80.78%)
Payload_encryption/unpack/set_cmd📈 view plot
🚷 view threshold
274.41 ns
(+20.00%)Baseline: 228.67 ns
352.68 ns
(77.81%)
Raft_1Node_Latency/prefix/1node📈 view plot
🚷 view threshold
🚨 view alert (🔔)
9,804,600.00 ns
(+170.58%)Baseline: 3,623,495.47 ns
8,696,690.66 ns
(112.74%)

Raft_1Node_Latency/read/1node📈 view plot
🚷 view threshold
34,632.00 ns
(+0.20%)Baseline: 34,562.84 ns
52,594.68 ns
(65.85%)
Raft_1Node_Latency/remove/1node📈 view plot
🚷 view threshold
343,420.00 ns
(-3.51%)Baseline: 355,916.56 ns
598,887.44 ns
(57.34%)
Raft_1Node_Latency/write/1node📈 view plot
🚷 view threshold
368,400.00 ns
(-4.54%)Baseline: 385,930.47 ns
753,901.24 ns
(48.87%)
build_snapshot/default📈 view plot
🚷 view threshold
2,133.70 ns
(+2.71%)Baseline: 2,077.44 ns
2,796.17 ns
(76.31%)
fernet token/project📈 view plot
🚷 view threshold
1,412.10 ns
(+11.14%)Baseline: 1,270.52 ns
1,758.55 ns
(80.30%)
get_data_keyspace📈 view plot
🚷 view threshold
0.33 ns
(+12.05%)Baseline: 0.29 ns
0.38 ns
(86.56%)
get_db📈 view plot
🚷 view threshold
0.33 ns
(+12.03%)Baseline: 0.29 ns
0.38 ns
(86.64%)
get_fernet_token_timestamp/project📈 view plot
🚷 view threshold
143.75 ns
(+9.44%)Baseline: 131.35 ns
184.39 ns
(77.96%)
get_keyspace📈 view plot
🚷 view threshold
4.14 ns
(-37.78%)Baseline: 6.65 ns
15.56 ns
(26.59%)
🐰 View full continuous benchmarking report in Bencher

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

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

rust

Totals
======
Ran: 133 tests in 30.9785 sec.
 - Passed: 83
 - Skipped: 4
 - Expected Fail: 0
 - Unexpected Success: 0
 - Failed: 46
Sum of execute time for each test: 30.7796 sec.
Failed test IDs
===== FAILED TESTS (target=rust) =====
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_credentials.CredentialsTestJSON.test_credentials_create_get_update_delete[id-7cd59bf9-bda4-4c72-9467-d21cab278355,smoke]
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_list_projects.ListProjectsTestJSON.test_list_projects_with_parent[id-6edc66f5-2941-4a17-9526-4073311c1fac]
setUpClass (tempest.api.identity.admin.v3.test_endpoint_groups.EndPointGroupsTest)
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_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_projects.ProjectsTestJSON.test_project_create_with_parent[id-1854f9c0-70bc-4d11-a08a-1c789d339e3d]
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_project_tags.IdentityV3ProjectTagsTest.test_list_update_delete_project_tags[id-7c123aac-999d-416a-a0fb-84b915ab10de]
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_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_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_users_negative.UsersNegativeTest.test_create_user_for_non_existent_domain[id-e75f006c-89cc-477b-874d-588e4eab4b17,negative]
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_trusts.TrustsV3TestJSON.test_trust_expire[id-0ed14b66-cefd-4b5c-a964-65759453e292]
tempest.api.identity.admin.v3.test_tokens.TokensV3TestJSON.test_rescope_token[id-565fa210-1da1-4563-999b-f7b5b67cf112]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_trust_impersonate[id-5a0a91a4-baef-4a14-baba-59bf4d7fcace]
tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential_expires[id-852daf0c-42b5-4239-8466-d193d0543ed3]
tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON.test_trust_noimpersonate[id-ed2a8779-a7ac-49dc-afd7-30f32f936ed2]
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.v3.test_tokens.TokensV3Test.test_validate_token[id-a9512ac3-3909-48a4-b395-11f438e16260]
===== END FAILED TESTS (target=rust) =====

View full run

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

🦢 Load Test Results

Goose Attack Report

Plan Overview

Action Started Stopped Elapsed Users
Increasing 26-10-21 13:54:10 26-10-21 13:54:32 00:00:22 0 → 45
Maintaining 26-10-21 13:54:32 26-10-21 13:55:03 00:00:31 45
Decreasing 26-10-21 13:55:03 26-10-21 13:55:03 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 38 0 638.55 419 1065 1.27 0.00
DELETE DELETE /v3/projects/:id (teardown) 1 0 234.00 234 234 0.03 0.00
DELETE DELETE /v3/roles/:id (teardown) 1 0 78.00 78 78 0.03 0.00
DELETE DELETE /v3/users/:id (teardown) 2 0 243.50 175 312 0.07 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (cc teardown) 1 0 66.00 66 66 0.03 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 1 0 276.00 276 276 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (cc teardown) 1 0 32.00 32 32 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 1 0 104.00 104 104 0.03 0.00
GET 420 0 700.13 348 1632 14.00 0.00
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 47 32 335.70 2 1396 1.57 1.07
GET GET /v3/auth/tokens (validate new) 37 0 661.84 444 1484 1.23 0.00
GET GET /v3/auth/tokens (validate revoked) 39 0 539.08 92 1049 1.30 0.00
GET GET /v3/projects/:id 47 0 654.40 408 1102 1.57 0.00
GET GET /v3/projects/:id (catalog) 70 0 651.17 342 1246 2.33 0.00
GET GET /v3/role_assignments 36 0 668.92 443 1322 1.20 0.00
GET GET /v3/role_assignments?role.id 36 0 621.58 399 1379 1.20 0.00
GET GET /v3/role_assignments?scope.domain.id 35 0 621.00 329 1186 1.17 0.00
GET GET /v3/role_assignments?user.id 36 0 634.53 341 1278 1.20 0.00
GET GET /v3/roles 93 0 657.42 319 1515 3.10 0.00
GET GET /v3/roles/:id 46 0 662.17 346 1371 1.53 0.00
GET GET /v3/users/:id 90 0 674.78 399 1361 3.00 0.00
GET GET /v3/users/:id (catalog) 91 0 640.60 441 1178 3.03 0.00
GET GET /v4/api-keys 25 0 573.40 385 1113 0.83 0.00
GET GET /v4/api-keys/:client_id 25 0 643.08 353 1367 0.83 0.00
GET GET /v4/mappings/rulesets 25 0 582.76 369 1064 0.83 0.00
GET GET /v4/mappings/rulesets/:mapping_id 25 0 628.40 395 1407 0.83 0.00
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 1741 0 25.35 3 236 58.03 0.00
GET GET /v4/oauth2/:domain_id/clients 25 0 622.48 396 1424 0.83 0.00
GET GET /v4/oauth2/:domain_id/clients/:provider_id 26 0 584.77 308 1147 0.87 0.00
GET GET /v4/oauth2/:domain_id/jwks 1741 0 25.45 3 226 58.03 0.00
GET GET /v4/scim_realms 16 0 624.56 371 1414 0.53 0.00
GET GET /v4/scim_realms/:domain_id/:provider_id 17 0 567.59 405 1167 0.57 0.00
POST POST /v3/auth/tokens 36 0 602.36 392 889 1.20 0.00
POST POST /v3/auth/tokens (password, invalid) 35 0 874.89 486 1503 1.17 0.00
POST POST /v3/auth/tokens (password, project-scoped) 57 0 1236.11 694 1900 1.90 0.00
POST POST /v3/auth/tokens (password, unscoped) 55 0 970.16 568 1656 1.83 0.00
POST POST /v3/auth/tokens (rescope to system) 98 0 624.26 97 1207 3.27 0.00
POST POST /v3/auth/tokens (rescope, invalid project) 58 0 528.40 76 1031 1.93 0.00
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 53 0 1165.57 681 1719 1.77 0.00
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 0 83.00 83 83 0.03 0.00
POST POST /v4/oauth2/:domain_id/device_authorization 498 0 60.07 14 227 16.60 0.00
POST POST /v4/oauth2/:domain_id/token (client_credentials) 12 0 810.42 495 1483 0.40 0.00
PUT PUT /v4/scim_realms/:domain_id/:provider_id 16 0 676.94 381 1103 0.53 0.00
Aggregated 5754 32 232.66 2 1900 191.80 1.07

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 700 700 800 1,000 1,000 1,000
DELETE DELETE /v3/projects/:id (teardown) 234 234 234 234 234 234 234 234
DELETE DELETE /v3/roles/:id (teardown) 78 78 78 78 78 78 78 78
DELETE DELETE /v3/users/:id (teardown) 180 180 180 310 310 310 310 310
DELETE DELETE /v4/mappings/rulesets/:mapping_id (cc teardown) 66 66 66 66 66 66 66 66
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 276 276 276 276 276 276 276 276
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (cc teardown) 32 32 32 32 32 32 32 32
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 104 104 104 104 104 104 104 104
GET 700 700 700 800 900 1,000 1,000 1,632
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 320 370 430 600 600 700 1,000 1,000
GET GET /v3/auth/tokens (validate new) 600 700 700 700 900 900 1,000 1,000
GET GET /v3/auth/tokens (validate revoked) 500 600 600 600 700 700 1,000 1,000
GET GET /v3/projects/:id 600 700 700 800 800 1,000 1,000 1,000
GET GET /v3/projects/:id (catalog) 600 700 700 700 900 900 1,000 1,000
GET GET /v3/role_assignments 600 700 700 700 800 900 1,000 1,000
GET GET /v3/role_assignments?role.id 600 600 600 700 700 1,000 1,000 1,000
GET GET /v3/role_assignments?scope.domain.id 600 600 700 700 800 900 1,000 1,000
GET GET /v3/role_assignments?user.id 600 600 700 800 800 900 1,000 1,000
GET GET /v3/roles 600 600 700 700 900 1,000 1,515 1,515
GET GET /v3/roles/:id 600 600 700 800 800 1,000 1,000 1,000
GET GET /v3/users/:id 600 700 700 800 900 1,000 1,000 1,000
GET GET /v3/users/:id (catalog) 600 700 700 700 800 800 1,000 1,000
GET GET /v4/api-keys 500 600 600 700 700 800 1,000 1,000
GET GET /v4/api-keys/:client_id 600 600 700 700 800 1,000 1,000 1,000
GET GET /v4/mappings/rulesets 500 600 600 600 800 900 1,000 1,000
GET GET /v4/mappings/rulesets/:mapping_id 600 600 600 700 700 800 1,000 1,000
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 21 24 27 33 44 60 97 236
GET GET /v4/oauth2/:domain_id/clients 600 600 600 600 900 1,000 1,000 1,000
GET GET /v4/oauth2/:domain_id/clients/:provider_id 500 600 600 600 700 1,000 1,000 1,000
GET GET /v4/oauth2/:domain_id/jwks 20 24 28 34 45 61 94 226
GET GET /v4/scim_realms 600 600 600 600 700 700 1,000 1,000
GET GET /v4/scim_realms/:domain_id/:provider_id 500 500 600 600 700 800 1,000 1,000
POST POST /v3/auth/tokens 600 600 700 700 800 800 889 889
POST POST /v3/auth/tokens (password, invalid) 800 900 1,000 1,000 1,000 1,000 1,503 1,503
POST POST /v3/auth/tokens (password, project-scoped) 1,000 1,000 1,000 1,000 1,900 1,900 1,900 1,900
POST POST /v3/auth/tokens (password, unscoped) 900 1,000 1,000 1,000 1,000 1,000 1,000 1,656
POST POST /v3/auth/tokens (rescope to system) 700 700 700 800 800 900 1,000 1,000
POST POST /v3/auth/tokens (rescope, invalid project) 600 600 600 700 700 800 900 1,000
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 1,000 1,000 1,000 1,000 1,719 1,719 1,719 1,719
POST POST /v4/api-keys/:client_id/revoke (teardown) 83 83 83 83 83 83 83 83
POST POST /v4/oauth2/:domain_id/device_authorization 51 58 68 80 110 130 160 227
POST POST /v4/oauth2/:domain_id/token (client_credentials) 600 700 700 1,000 1,000 1,000 1,000 1,000
PUT PUT /v4/scim_realms/:domain_id/:provider_id 600 600 700 700 1,000 1,000 1,000 1,000
Aggregated 33 49 310 600 700 900 1,000 1,900

Status Code Metrics

Method Name Status Codes
DELETE DELETE /v3/auth/tokens 38 [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 (cc teardown) 1 [204]
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 1 [204]
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (cc teardown) 1 [204]
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 1 [204]
GET 420 [200]
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 32 [401], 15 [429]
GET GET /v3/auth/tokens (validate new) 37 [200]
GET GET /v3/auth/tokens (validate revoked) 39 [404]
GET GET /v3/projects/:id 47 [200]
GET GET /v3/projects/:id (catalog) 70 [200]
GET GET /v3/role_assignments 36 [200]
GET GET /v3/role_assignments?role.id 36 [200]
GET GET /v3/role_assignments?scope.domain.id 35 [200]
GET GET /v3/role_assignments?user.id 36 [200]
GET GET /v3/roles 93 [200]
GET GET /v3/roles/:id 46 [200]
GET GET /v3/users/:id 90 [200]
GET GET /v3/users/:id (catalog) 91 [200]
GET GET /v4/api-keys 25 [200]
GET GET /v4/api-keys/:client_id 25 [200]
GET GET /v4/mappings/rulesets 25 [200]
GET GET /v4/mappings/rulesets/:mapping_id 25 [200]
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 1,741 [200]
GET GET /v4/oauth2/:domain_id/clients 25 [200]
GET GET /v4/oauth2/:domain_id/clients/:provider_id 26 [200]
GET GET /v4/oauth2/:domain_id/jwks 1,741 [200]
GET GET /v4/scim_realms 16 [200]
GET GET /v4/scim_realms/:domain_id/:provider_id 17 [200]
POST POST /v3/auth/tokens 36 [201]
POST POST /v3/auth/tokens (password, invalid) 35 [401]
POST POST /v3/auth/tokens (password, project-scoped) 57 [201]
POST POST /v3/auth/tokens (password, unscoped) 55 [201]
POST POST /v3/auth/tokens (rescope to system) 98 [201]
POST POST /v3/auth/tokens (rescope, invalid project) 58 [401]
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 53 [201]
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 [200]
POST POST /v4/oauth2/:domain_id/device_authorization 498 [200]
POST POST /v4/oauth2/:domain_id/token (client_credentials) 12 [200]
PUT PUT /v4/scim_realms/:domain_id/:provider_id 16 [200]
Aggregated 5,230 [200], 125 [401], 15 [429], 299 [201], 46 [204], 39 [404]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
ReadHeavy
0.0 0 0 0.00 0 0 0.00 0.00
0.1 60 0 710.15 439 1410 2.00 0.00
0.2 60 0 683.23 448 1387 2.00 0.00
0.3 60 0 648.53 415 1435 2.00 0.00
TokenLifecycle
1.0 0 0 0.00 0 0 0.00 0.00
1.1 39 0 2438.51 1733 3696 1.30 0.00
ValidateToken
2.0 0 0 0.00 0 0 0.00 0.00
2.1 81 0 758.00 473 1465 2.70 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 90 0 674.83 399 1361 3.00 0.00
3.3 2 0 243.50 175 312 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 47 0 654.45 409 1102 1.57 0.00
4.3 1 0 234.00 234 234 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 46 0 662.24 346 1371 1.53 0.00
5.3 1 0 78.00 78 78 0.03 0.00
RoleList
6.0 0 0 0.00 0 0 0.00 0.00
6.1 93 0 657.47 319 1515 3.10 0.00
RoleAssignmentList
7.0 0 0 0.00 0 0 0.00 0.00
7.1 36 0 669.03 443 1323 1.20 0.00
7.2 36 0 634.56 341 1278 1.20 0.00
7.3 35 0 621.03 329 1186 1.17 0.00
7.4 36 0 621.67 399 1379 1.20 0.00
UserRead
8.0 0 0 0.00 0 0 0.00 0.00
8.1 89 0 723.93 423 1632 2.97 0.00
8.2 91 0 640.66 441 1178 3.03 0.00
ProjectRead
9.0 0 0 0.00 0 0 0.00 0.00
9.1 70 0 653.30 348 1606 2.33 0.00
9.2 70 0 651.23 342 1246 2.33 0.00
PasswordAuth
10.0 55 0 970.22 568 1656 1.83 0.00
10.1 57 0 1236.16 694 1900 1.90 0.00
PasswordAuthNegative
11.0 35 0 874.91 486 1503 1.17 0.00
Rescope
12.0 0 0 0.00 0 0 0.00 0.00
12.1 98 0 624.32 97 1208 3.27 0.00
RescopeNegative
13.0 0 0 0.00 0 0 0.00 0.00
13.1 58 0 528.41 76 1031 1.93 0.00
SystemScopeAuth
14.0 53 0 1165.64 681 1719 1.77 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 25 0 643.12 353 1367 0.83 0.00
15.3 25 0 573.48 385 1113 0.83 0.00
15.4 1 0 83.00 83 83 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 25 0 628.40 395 1407 0.83 0.00
16.3 25 0 582.80 369 1064 0.83 0.00
16.4 1 0 276.00 276 276 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 26 0 584.81 308 1147 0.87 0.00
17.3 25 0 622.48 396 1424 0.83 0.00
17.4 1 0 104.00 104 104 0.03 0.00
OAuth2ClientCredentials
18.0 0 0 0.00 0 0 0.00 0.00
18.1 0 0 0.00 0 0 0.00 0.00
18.2 12 0 810.42 495 1483 0.40 0.00
18.3 1 0 98.00 98 98 0.03 0.00
OAuth2DeviceAuthorization
19.0 498 0 60.13 14 227 16.60 0.00
OAuth2Discovery
20.0 1741 0 25.49 3 226 58.03 0.00
20.1 1741 0 25.40 3 236 58.03 0.00
ScimRealmRead
21.0 0 0 0.00 0 0 0.00 0.00
21.1 17 0 567.59 405 1167 0.57 0.00
21.2 16 0 624.62 371 1414 0.53 0.00
21.3 16 0 677.06 381 1103 0.53 0.00
ScimSync
22.0 0 0 0.00 0 0 0.00 0.00
22.1 0 0 0.00 0 0 0.00 0.00
22.2 0 0 0.00 0 0 0.00 0.00
22.3 47 0 655.11 248 1396 1.57 0.00
22.4 46 0 0.00 0 0 1.53 0.00
22.5 46 0 0.00 0 0 1.53 0.00
22.6 1 0 0.00 0 0 0.03 0.00
Aggregated 5735 0 233.43 3 3696 191.17 0.00

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
ReadHeavy 4 59 2056.86 1597 3950 1.97 14.75
TokenLifecycle 3 36 2482.44 1998 3696 1.20 12.00
ValidateToken 2 79 760.29 473 1465 2.63 39.50
UserCRUD 2 88 676.27 399 1361 2.93 44.00
ProjectCRUD 1 46 655.76 409 1102 1.53 46.00
RoleCRUD 1 45 669.27 447 1371 1.50 45.00
RoleList 2 91 662.82 353 1515 3.03 45.50
RoleAssignmentList 3 36 2560.92 2012 4286 1.20 12.00
UserRead 4 88 1372.68 1046 2413 2.93 22.00
ProjectRead 3 68 1314.19 842 2420 2.27 22.67
PasswordAuth 4 55 2235.67 1524 3235 1.83 13.75
PasswordAuthNegative 1 34 867.82 486 1503 1.13 34.00
Rescope 2 96 621.67 97 1208 3.20 48.00
RescopeNegative 1 57 526.54 76 1031 1.90 57.00
SystemScopeAuth 2 51 1172.90 681 1719 1.70 25.50
ApiKeyCRUD 1 24 1227.04 801 2481 0.80 24.00
MappingCRUD 1 25 1211.88 764 2471 0.83 25.00
OAuth2ClientCRUD 1 25 1219.00 794 1995 0.83 25.00
OAuth2ClientCredentials 1 12 2467.25 1639 3378 0.40 12.00
OAuth2DeviceAuthorization 1 497 60.14 14 227 16.57 497.00
OAuth2Discovery 3 1740 51.43 9 264 58.00 580.00
ScimRealmRead 1 16 1878.12 1450 3685 0.53 16.00
ScimSync 1 46 660.93 248 1396 1.53 46.00
Aggregated 45 3314 408.84 9 4286 110.47 1706.67

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) 84 401 Unauthorized: POST /v3/auth/tokens (password, invalid)
POST POST /v3/auth/tokens (rescope, invalid project) 146 401 Unauthorized: POST /v3/auth/tokens (rescope, invalid project)
GET GET /v3/auth/tokens (validate revoked) 140 404 Not Found: GET /v3/auth/tokens (validate revoked)
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 32 429 Too Many Requests: GET /SCIM/v2/:domain_id/Users (sync reconcile list)

View full report

Add the cnf confirmation claim to the OAuth2 access tokens, the
dpop_jkt key thumbprint to authorization codes, refresh token families
and device grants, and the dpop_bound_access_tokens client flag, as
described in ADR 0043 sections 1 and 3.

A rotated refresh token keeps the binding of its family, and the
thumbprint is carried from the authorization code and device grant
into the refresh family. All new fields are trailing and defaulted,
so stored records stay readable.

Turning the client flag off, or revoking a client that has it on,
requires the admin role. Setting the flag to true is rejected for now
because issued tokens are not bound yet, so a client would be
believed sender-constrained while still receiving bearer tokens.

Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
@gtema
gtema added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit b3a3f99 Oct 21, 2026
46 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