Skip to content

feat: Support SVID + JWT used by service delegation - #1582

Merged
gtema merged 3 commits into
mainfrom
service_grant
Oct 22, 2026
Merged

gtema merged 3 commits into
mainfrom
service_grant

Conversation

@gtema

@gtema gtema commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator
  • feat(auth): Accept delegated JWT bound to SVID
  • docs(adr): Describe SVID plus delegated token auth
  • fix(auth): Harden delegated bearer authentication

gtema added 3 commits October 22, 2026 20:34
A request on the internal interface carrying both an SVID and a service
grant or on-behalf-of JWT is now authenticated as that delegation. The
token must be issued by the domain's own issuer, name an actor and be
matched by the connection SVID against the client's spiffe_ids. The
delegation is re-evaluated on every request, so revocation, role loss
and chain revocation apply at once. A mismatch is a 401 and never falls
back to the plain SVID identity.

Assisted-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Add ADR 0036 section 8.1 and update the admin guide: Keystone accepts a
service grant or on-behalf-of token only together with the acting
client's SVID.

Assisted-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Close the gaps found in review of the SVID plus delegated bearer path.

Service grant and on-behalf-of callers may only reach read policy
actions (show, list, check). The enforcer denies every other action
before OPA is asked, so role-only allow rules cannot let a service mint
application credentials or act as an admin on behalf of a user.

An Authorization header next to an SVID on the internal interface that
is not a well-formed bearer (any scheme case) is now a 401 instead of a
fallback to the plain SVID identity. The service grant show and delete
routes route such requests through the bound bearer path.

Per-request re-evaluation reuses the already loaded grant and no longer
refreshes last_redeemed_at. Rejections are logged at warn.

Share one config to key repository signing algorithm conversion and
cover the extractor and the policy gate with unit tests.

Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
@gtema
gtema enabled auto-merge October 22, 2026 19:07
@gtema gtema changed the title feat: Support SVID + JWT used by services feat: Support SVID + JWT used by service delegation Oct 22, 2026
@github-actions

Copy link
Copy Markdown

🐰 Bencher Report

Projectkeystone
Branchservice_grant
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
121,160.00 ns
(-11.96%)Baseline: 137,614.83 ns
263,947.71 ns
(45.90%)
Command_Serde/apply/set📈 view plot
🚷 view threshold
135,310.00 ns
(-4.92%)Baseline: 142,316.67 ns
248,562.59 ns
(54.44%)
Command_Serde/pack/delete📈 view plot
🚷 view threshold
139.15 ns
(+21.19%)Baseline: 114.82 ns
164.70 ns
(84.49%)
Command_Serde/pack/delete_index📈 view plot
🚷 view threshold
122.24 ns
(+18.56%)Baseline: 103.10 ns
144.24 ns
(84.75%)
Command_Serde/pack/set📈 view plot
🚷 view threshold
224.78 ns
(+20.72%)Baseline: 186.20 ns
271.29 ns
(82.86%)
Command_Serde/pack/set_index📈 view plot
🚷 view threshold
122.76 ns
(+18.55%)Baseline: 103.55 ns
146.53 ns
(83.78%)
Command_Serde/unpack/delete📈 view plot
🚷 view threshold
167.40 ns
(+15.71%)Baseline: 144.68 ns
217.75 ns
(76.88%)
Command_Serde/unpack/delete_index📈 view plot
🚷 view threshold
142.91 ns
(+16.99%)Baseline: 122.16 ns
182.53 ns
(78.29%)
Command_Serde/unpack/set📈 view plot
🚷 view threshold
263.70 ns
(+18.27%)Baseline: 222.97 ns
342.82 ns
(76.92%)
Command_Serde/unpack/set_index📈 view plot
🚷 view threshold
143.59 ns
(+17.87%)Baseline: 121.82 ns
180.83 ns
(79.41%)
Payload_encryption/pack/remove_cmd📈 view plot
🚷 view threshold
125.26 ns
(+17.78%)Baseline: 106.35 ns
158.85 ns
(78.86%)
Payload_encryption/pack/set_cmd📈 view plot
🚷 view threshold
217.29 ns
(+13.48%)Baseline: 191.49 ns
291.53 ns
(74.53%)
Payload_encryption/unpack/remove_cmd📈 view plot
🚷 view threshold
174.58 ns
(+19.14%)Baseline: 146.54 ns
218.77 ns
(79.80%)
Payload_encryption/unpack/set_cmd📈 view plot
🚷 view threshold
273.68 ns
(+20.44%)Baseline: 227.23 ns
349.53 ns
(78.30%)
Raft_1Node_Latency/prefix/1node📈 view plot
🚷 view threshold
2,885,000.00 ns
(-19.69%)Baseline: 3,592,111.09 ns
8,717,170.74 ns
(33.10%)
Raft_1Node_Latency/read/1node📈 view plot
🚷 view threshold
44,765.00 ns
(+31.05%)Baseline: 34,158.45 ns
52,414.01 ns
(85.41%)
Raft_1Node_Latency/remove/1node📈 view plot
🚷 view threshold
351,070.00 ns
(-1.24%)Baseline: 355,461.56 ns
602,136.58 ns
(58.30%)
Raft_1Node_Latency/write/1node📈 view plot
🚷 view threshold
369,570.00 ns
(-6.27%)Baseline: 394,290.94 ns
774,379.22 ns
(47.72%)
build_snapshot/default📈 view plot
🚷 view threshold
2,072.50 ns
(+0.14%)Baseline: 2,069.50 ns
2,780.61 ns
(74.53%)
fernet token/project📈 view plot
🚷 view threshold
1,411.30 ns
(+11.77%)Baseline: 1,262.68 ns
1,748.48 ns
(80.72%)
get_data_keyspace📈 view plot
🚷 view threshold
0.31 ns
(+6.23%)Baseline: 0.29 ns
0.38 ns
(82.28%)
get_db📈 view plot
🚷 view threshold
0.31 ns
(+6.23%)Baseline: 0.29 ns
0.38 ns
(82.48%)
get_fernet_token_timestamp/project📈 view plot
🚷 view threshold
146.43 ns
(+11.86%)Baseline: 130.90 ns
183.01 ns
(80.01%)
get_keyspace📈 view plot
🚷 view threshold
4.16 ns
(-37.27%)Baseline: 6.62 ns
15.45 ns
(26.90%)
🐰 View full continuous benchmarking report in Bencher

@github-actions

Copy link
Copy Markdown

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

rust

Totals
======
Ran: 80 tests in 15.6930 sec.
 - Passed: 38
 - Skipped: 2
 - Expected Fail: 0
 - Unexpected Success: 0
 - Failed: 40
Sum of execute time for each test: 8.2019 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]
setUpClass (tempest.api.identity.admin.v3.test_endpoint_groups.EndPointGroupsTest)
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_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.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_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_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]
setUpClass (tempest.api.identity.admin.v3.test_project_tags.IdentityV3ProjectTagsTest)
tempest.api.identity.admin.v3.test_projects_negative.ProjectsNegativeStaticTestJSON.test_create_project_by_unauthorized_user[id-8fba9de2-3e1f-4e77-812a-60cb68f8df13,negative]
tempest.api.identity.admin.v3.test_projects_negative.ProjectsNegativeStaticTestJSON.test_create_project_with_empty_name[id-7828db17-95e5-475b-9432-9a51b4aa79a9,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.admin.v3.test_projects_negative.ProjectsNegativeStaticTestJSON.test_delete_non_existent_project[id-7965b581-60c1-43b7-8169-95d4ab7fc6fb,negative]
tempest.api.identity.admin.v3.test_projects_negative.ProjectsNegativeStaticTestJSON.test_list_projects_by_unauthorized_user[id-24c49279-45dd-4155-887a-cb738c2385aa,negative]
tempest.api.identity.admin.v3.test_projects_negative.ProjectsNegativeStaticTestJSON.test_project_create_duplicate[id-874c3e84-d174-4348-a16b-8c01f599561b,negative]
setUpClass (tempest.api.identity.admin.v3.test_services.ServicesTestJSON)
setUpClass (tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON)
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]
setUpClass (tempest.api.identity.admin.v3.test_list_users.UsersV3TestJSON)
setUpClass (tempest.api.identity.admin.v3.test_users.UsersV3TestJSON)
setUpClass (tempest.api.identity.admin.v3.test_tokens.TokensV3TestJSON)
setUpClass (tempest.api.identity.admin.v3.test_roles.RolesV3TestJSON)
setUpClass (tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test)
setUpClass (tempest.api.identity.v3.test_api_discovery.TestApiDiscovery)
setUpClass (tempest.api.identity.admin.v3.test_projects_negative.ProjectsNegativeTestJSON)
setUpClass (tempest.api.identity.admin.v3.test_trusts.TrustsV3TestJSON)
setUpClass (tempest.api.identity.v3.test_catalog.IdentityCatalogTest)
setUpClass (tempest.api.identity.v3.test_ec2_credentials.EC2CredentialsTest)
setUpClass (tempest.api.identity.admin.v3.test_regions.RegionsTestJSON)
setUpClass (tempest.api.identity.v3.test_projects.IdentityV3ProjectsTest)
setUpClass (tempest.api.identity.v3.test_tokens.TokensV3Test)
setUpClass (tempest.api.identity.admin.v3.test_users_negative.UsersNegativeTest)
setUpClass (tempest.api.identity.v3.test_domains.DefaultDomainTestJSON)
===== END FAILED TESTS (target=rust) =====

View full run

@github-actions

Copy link
Copy Markdown

🦢 Load Test Results

Goose Attack Report

Plan Overview

Action Started Stopped Elapsed Users
Increasing 26-10-22 20:30:06 26-10-22 20:30:29 00:00:23 0 → 45
Maintaining 26-10-22 20:30:29 26-10-22 20:30:59 00:00:30 45
Decreasing 26-10-22 20:30:59 26-10-22 20:30:59 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 47 0 526.62 70 665 1.57 0.00
DELETE DELETE /v3/projects/:id (teardown) 1 0 324.00 324 324 0.03 0.00
DELETE DELETE /v3/roles/:id (teardown) 1 0 127.00 127 127 0.03 0.00
DELETE DELETE /v3/users/:id (teardown) 2 0 276.00 271 281 0.07 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (cc teardown) 1 0 341.00 341 341 0.03 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 1 0 305.00 305 305 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (cc teardown) 1 0 97.00 97 97 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 1 0 224.00 224 224 0.03 0.00
GET 517 0 565.84 351 802 17.23 0.00
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 48 30 243.10 2 728 1.60 1.00
GET GET /v3/auth/tokens (validate new) 47 0 505.30 190 713 1.57 0.00
GET GET /v3/auth/tokens (validate revoked) 47 0 450.21 19 594 1.57 0.00
GET GET /v3/projects/:id 58 0 528.52 350 671 1.93 0.00
GET GET /v3/projects/:id (catalog) 86 0 515.66 354 667 2.87 0.00
GET GET /v3/role_assignments 45 0 541.93 364 701 1.50 0.00
GET GET /v3/role_assignments?role.id 44 0 501.68 353 669 1.47 0.00
GET GET /v3/role_assignments?scope.domain.id 45 0 503.89 356 673 1.50 0.00
GET GET /v3/role_assignments?user.id 45 0 490.62 351 754 1.50 0.00
GET GET /v3/roles 117 0 522.72 336 723 3.90 0.00
GET GET /v3/roles/:id 58 0 522.98 363 699 1.93 0.00
GET GET /v3/users/:id 111 0 546.45 389 740 3.70 0.00
GET GET /v3/users/:id (catalog) 109 0 551.97 337 746 3.63 0.00
GET GET /v4/api-keys 31 0 479.77 278 609 1.03 0.00
GET GET /v4/api-keys/:client_id 32 0 488.38 386 621 1.07 0.00
GET GET /v4/mappings/rulesets 32 0 482.91 371 660 1.07 0.00
GET GET /v4/mappings/rulesets/:mapping_id 31 0 480.29 327 695 1.03 0.00
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 2214 0 20.08 4 136 73.80 0.00
GET GET /v4/oauth2/:domain_id/clients 31 0 489.81 354 666 1.03 0.00
GET GET /v4/oauth2/:domain_id/clients/:provider_id 31 0 492.55 412 625 1.03 0.00
GET GET /v4/oauth2/:domain_id/jwks 2211 0 19.64 3 105 73.70 0.00
GET GET /v4/scim_realms 21 0 478.67 352 587 0.70 0.00
GET GET /v4/scim_realms/:domain_id/:provider_id 21 0 478.67 346 668 0.70 0.00
POST POST /v3/auth/tokens 46 0 487.59 350 636 1.53 0.00
POST POST /v3/auth/tokens (password, invalid) 39 0 798.05 467 1254 1.30 0.00
POST POST /v3/auth/tokens (password, project-scoped) 59 0 1158.51 736 1584 1.97 0.00
POST POST /v3/auth/tokens (password, unscoped) 60 0 953.67 550 1644 2.00 0.00
POST POST /v3/auth/tokens (rescope to system) 105 0 584.40 345 791 3.50 0.00
POST POST /v3/auth/tokens (rescope, invalid project) 63 0 485.10 339 701 2.10 0.00
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 52 0 1204.54 730 1738 1.73 0.00
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 0 229.00 229 229 0.03 0.00
POST POST /v4/oauth2/:domain_id/device_authorization 632 0 47.15 15 186 21.07 0.00
POST POST /v4/oauth2/:domain_id/token (client_credentials) 15 0 617.60 329 1021 0.50 0.00
PUT PUT /v4/scim_realms/:domain_id/:provider_id 20 0 515.35 418 701 0.67 0.00
Aggregated 7179 30 186.23 2 1738 239.30 1.00

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 600 665 665 665
DELETE DELETE /v3/projects/:id (teardown) 324 324 324 324 324 324 324 324
DELETE DELETE /v3/roles/:id (teardown) 127 127 127 127 127 127 127 127
DELETE DELETE /v3/users/:id (teardown) 271 271 271 280 280 280 280 280
DELETE DELETE /v4/mappings/rulesets/:mapping_id (cc teardown) 341 341 341 341 341 341 341 341
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 305 305 305 305 305 305 305 305
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (cc teardown) 97 97 97 97 97 97 97 97
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 224 224 224 224 224 224 224 224
GET 600 600 600 600 700 700 800 800
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 230 280 370 420 500 600 700 700
GET GET /v3/auth/tokens (validate new) 500 500 500 500 600 700 700 700
GET GET /v3/auth/tokens (validate revoked) 470 480 490 500 594 594 594 594
GET GET /v3/projects/:id 500 500 600 600 600 600 600 671
GET GET /v3/projects/:id (catalog) 500 500 600 600 600 600 667 667
GET GET /v3/role_assignments 500 600 600 600 600 700 700 700
GET GET /v3/role_assignments?role.id 500 500 500 600 600 600 669 669
GET GET /v3/role_assignments?scope.domain.id 500 500 500 500 600 600 673 673
GET GET /v3/role_assignments?user.id 490 500 500 500 600 600 754 754
GET GET /v3/roles 500 500 600 600 600 600 700 700
GET GET /v3/roles/:id 500 500 600 600 600 600 699 699
GET GET /v3/users/:id 500 600 600 600 600 700 700 700
GET GET /v3/users/:id (catalog) 600 600 600 600 700 700 700 700
GET GET /v4/api-keys 490 500 500 500 600 600 600 600
GET GET /v4/api-keys/:client_id 490 500 500 500 600 600 600 600
GET GET /v4/mappings/rulesets 480 490 500 500 500 600 660 660
GET GET /v4/mappings/rulesets/:mapping_id 480 500 500 500 600 600 695 695
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 18 20 23 27 33 39 58 136
GET GET /v4/oauth2/:domain_id/clients 490 500 500 600 600 600 666 666
GET GET /v4/oauth2/:domain_id/clients/:provider_id 480 500 500 500 600 600 600 600
GET GET /v4/oauth2/:domain_id/jwks 17 19 22 26 33 41 57 105
GET GET /v4/scim_realms 470 490 500 500 500 587 587 587
GET GET /v4/scim_realms/:domain_id/:provider_id 470 480 500 500 600 600 668 668
POST POST /v3/auth/tokens 480 500 500 500 600 600 600 600
POST POST /v3/auth/tokens (password, invalid) 800 800 900 1,000 1,000 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,584 1,584 1,584
POST POST /v3/auth/tokens (password, unscoped) 900 1,000 1,000 1,000 1,000 1,000 1,644 1,644
POST POST /v3/auth/tokens (rescope to system) 600 600 600 600 700 700 791 791
POST POST /v3/auth/tokens (rescope, invalid project) 480 490 500 500 600 600 600 700
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 1,000 1,000 1,000 1,000 1,000 1,738 1,738 1,738
POST POST /v4/api-keys/:client_id/revoke (teardown) 229 229 229 229 229 229 229 229
POST POST /v4/oauth2/:domain_id/device_authorization 43 48 53 59 72 84 120 186
POST POST /v4/oauth2/:domain_id/token (client_credentials) 600 700 700 700 800 800 1,000 1,000
PUT PUT /v4/scim_realms/:domain_id/:provider_id 500 500 500 600 600 600 700 700
Aggregated 26 36 80 500 600 600 1,000 1,738

Status Code Metrics

Method Name Status Codes
DELETE DELETE /v3/auth/tokens 47 [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 517 [200]
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 30 [401], 18 [429]
GET GET /v3/auth/tokens (validate new) 47 [200]
GET GET /v3/auth/tokens (validate revoked) 47 [404]
GET GET /v3/projects/:id 58 [200]
GET GET /v3/projects/:id (catalog) 86 [200]
GET GET /v3/role_assignments 45 [200]
GET GET /v3/role_assignments?role.id 44 [200]
GET GET /v3/role_assignments?scope.domain.id 45 [200]
GET GET /v3/role_assignments?user.id 45 [200]
GET GET /v3/roles 117 [200]
GET GET /v3/roles/:id 58 [200]
GET GET /v3/users/:id 111 [200]
GET GET /v3/users/:id (catalog) 109 [200]
GET GET /v4/api-keys 31 [200]
GET GET /v4/api-keys/:client_id 32 [200]
GET GET /v4/mappings/rulesets 32 [200]
GET GET /v4/mappings/rulesets/:mapping_id 31 [200]
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 2,214 [200]
GET GET /v4/oauth2/:domain_id/clients 31 [200]
GET GET /v4/oauth2/:domain_id/clients/:provider_id 31 [200]
GET GET /v4/oauth2/:domain_id/jwks 2,211 [200]
GET GET /v4/scim_realms 21 [200]
GET GET /v4/scim_realms/:domain_id/:provider_id 21 [200]
POST POST /v3/auth/tokens 46 [201]
POST POST /v3/auth/tokens (password, invalid) 39 [401]
POST POST /v3/auth/tokens (password, project-scoped) 59 [201]
POST POST /v3/auth/tokens (password, unscoped) 60 [201]
POST POST /v3/auth/tokens (rescope to system) 105 [201]
POST POST /v3/auth/tokens (rescope, invalid project) 63 [401]
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 52 [201]
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 [200]
POST POST /v4/oauth2/:domain_id/device_authorization 632 [200]
POST POST /v4/oauth2/:domain_id/token (client_credentials) 15 [200]
PUT PUT /v4/scim_realms/:domain_id/:provider_id 20 [200]
Aggregated 47 [404], 55 [204], 322 [201], 6,605 [200], 18 [429], 132 [401]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
ReadHeavy
0.0 1 0 10.00 10 10 0.03 0.00
0.1 75 0 584.95 394 797 2.50 0.00
0.2 73 0 535.60 354 740 2.43 0.00
0.3 75 0 521.47 407 672 2.50 0.00
TokenLifecycle
1.0 0 0 0.00 0 0 0.00 0.00
1.1 47 0 1971.30 652 2214 1.57 0.00
ValidateToken
2.0 0 0 0.00 0 0 0.00 0.00
2.1 99 0 619.57 377 794 3.30 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 111 0 546.48 390 740 3.70 0.00
3.3 2 0 276.00 271 281 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 58 0 528.60 350 671 1.93 0.00
4.3 1 0 324.00 324 324 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 58 0 523.05 363 699 1.93 0.00
5.3 1 0 127.00 127 127 0.03 0.00
RoleList
6.0 0 0 0.00 0 0 0.00 0.00
6.1 117 0 522.79 336 723 3.90 0.00
RoleAssignmentList
7.0 0 0 0.00 0 0 0.00 0.00
7.1 45 0 541.96 364 701 1.50 0.00
7.2 45 0 490.62 351 754 1.50 0.00
7.3 45 0 503.91 356 673 1.50 0.00
7.4 44 0 501.82 353 669 1.47 0.00
UserRead
8.0 0 0 0.00 0 0 0.00 0.00
8.1 108 0 577.26 403 802 3.60 0.00
8.2 109 0 552.06 337 746 3.63 0.00
ProjectRead
9.0 0 0 0.00 0 0 0.00 0.00
9.1 87 0 538.02 351 744 2.90 0.00
9.2 86 0 515.71 354 667 2.87 0.00
PasswordAuth
10.0 60 0 953.70 550 1644 2.00 0.00
10.1 59 0 1158.63 737 1584 1.97 0.00
PasswordAuthNegative
11.0 39 0 798.05 467 1254 1.30 0.00
Rescope
12.0 0 0 0.00 0 0 0.00 0.00
12.1 105 0 584.47 345 791 3.50 0.00
RescopeNegative
13.0 0 0 0.00 0 0 0.00 0.00
13.1 63 0 485.21 339 701 2.10 0.00
SystemScopeAuth
14.0 52 0 1204.63 730 1738 1.73 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 32 0 488.41 386 621 1.07 0.00
15.3 31 0 479.84 278 609 1.03 0.00
15.4 1 0 229.00 229 229 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 31 0 480.32 327 695 1.03 0.00
16.3 32 0 482.91 371 660 1.07 0.00
16.4 1 0 305.00 305 305 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 31 0 492.58 412 625 1.03 0.00
17.3 31 0 489.84 354 666 1.03 0.00
17.4 1 0 224.00 224 224 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 15 0 617.60 329 1021 0.50 0.00
18.3 1 0 439.00 439 439 0.03 0.00
OAuth2DeviceAuthorization
19.0 632 0 47.20 15 186 21.07 0.00
OAuth2Discovery
20.0 2211 0 19.69 3 105 73.70 0.00
20.1 2214 0 20.13 4 136 73.80 0.00
ScimRealmRead
21.0 0 0 0.00 0 0 0.00 0.00
21.1 21 0 478.81 346 668 0.70 0.00
21.2 21 0 478.67 352 587 0.70 0.00
21.3 20 0 515.45 418 701 0.67 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 49 0 626.43 173 1026 1.63 0.00
22.4 48 0 0.00 0 0 1.60 0.00
22.5 48 0 0.00 0 0 1.60 0.00
22.6 1 0 0.00 0 0 0.03 0.00
Aggregated 7137 0 187.32 3 2214 237.90 0.00

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
ReadHeavy 4 74 1648.35 1374 1925 2.47 18.50
TokenLifecycle 3 44 2026.30 1745 2214 1.47 14.67
ValidateToken 2 97 623.39 453 794 3.23 48.50
UserCRUD 2 109 547.95 390 740 3.63 54.50
ProjectCRUD 1 57 529.75 350 671 1.90 57.00
RoleCRUD 1 57 525.86 394 699 1.90 57.00
RoleList 2 115 524.56 336 723 3.83 57.50
RoleAssignmentList 3 43 2053.93 1760 2361 1.43 14.33
UserRead 4 106 1136.70 914 1402 3.53 26.50
ProjectRead 3 85 1057.75 780 1302 2.83 28.33
PasswordAuth 4 58 2124.62 1451 3083 1.93 14.50
PasswordAuthNegative 1 38 801.05 467 1254 1.27 38.00
Rescope 2 103 587.63 375 791 3.43 51.50
RescopeNegative 1 62 486.79 339 701 2.07 62.00
SystemScopeAuth 2 50 1216.70 730 1738 1.67 25.00
ApiKeyCRUD 1 31 970.77 833 1157 1.03 31.00
MappingCRUD 1 31 969.26 786 1139 1.03 31.00
OAuth2ClientCRUD 1 31 984.94 810 1186 1.03 31.00
OAuth2ClientCredentials 1 14 2120.71 1547 2565 0.47 14.00
OAuth2DeviceAuthorization 1 631 47.19 15 186 21.03 631.00
OAuth2Discovery 3 2211 40.31 10 165 73.70 737.00
ScimRealmRead 1 20 1478.95 1271 1646 0.67 20.00
ScimSync 1 48 618.10 173 1023 1.60 48.00
Aggregated 45 4115 329.11 10 3083 137.17 2110.83

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) 90 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) 170 404 Not Found: GET /v3/auth/tokens (validate revoked)
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 46 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 Oct 22, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 22, 2026
@gtema
gtema added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 420c730 Oct 22, 2026
42 of 43 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