Skip to content

feat: Start implementation of on-behalf-of exchange - #1578

Open
gtema wants to merge 11 commits into
mainfrom
service_grant
Open

gtema wants to merge 11 commits into
mainfrom
service_grant

Conversation

@gtema

@gtema gtema commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator
  • feat(oauth2): Validate delegation role ceiling
  • fix(service_grant): Key redemption limit per SVID
  • test(service_grant): Add Raft integration tests
  • test(api): Add live service grant tests
  • test(api): Redeem service grants with a real SVID
  • docs(adr): Add on-behalf-of phase 2 design
  • feat(auth): Add on-behalf-of auth context
  • feat(oauth2): Add on-behalf-of exchange logic
  • feat(oauth2): Serve on-behalf-of token exchange
  • test(oauth2): Cover on-behalf-of with raft tests
  • fix(oauth2): Harden on-behalf-of exchange
  • fix(oauth2): Key chain revocation on first audit id

gtema added 9 commits October 22, 2026 09:48
Cover the service grant API against a live server: the grant
lifecycle, the delegatable service listing hiding SPIFFE IDs, and
rejected or foreign callers. Another user's grant answers as an id
that never existed, so the response is no oracle for grant ids.

Prove a grant can not be consumed through the public interface: a
redemption with the grantee client id, a forged SPIFFE identity, or
the grantor's own token is refused with invalid_client and issues no
token, and a live and an unknown grant answer alike. The internal
interface refuses a client without an SVID at the TLS handshake.

Add an [interface_internal] section to the API test server so client
registration accepts SPIFFE IDs of the example.org trust domain.

Assisted-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
The live harness already runs SPIRE, so redeem a grant over the
internal mTLS listener with an X.509-SVID fetched from the agent.

start-spire.sh registers two more workload entries for the test uid.
The svid_client helper picks one of the SVIDs the agent hands out by
its SPIFFE ID and posts a form over mTLS. A client's spiffe_ids may
not overlap another's, so the redeeming test owns one entry.

Cover a successful redemption (token claims, act.sub, repeated
redemption, last_redeemed_at, refusal after revocation) and the
refusal of a valid SVID that is not one of the client's spiffe_ids.

Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Record how phase 2 implements the on-behalf-of exchange: accepted
subjects, SVID client authentication, the OnBehalfOf context shape,
root revocation and the operation lifetime bound.

Assisted-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Add AuthenticationContext::OnBehalfOf and the matching delegation
claim. The chain keeps the subject's project, role ceiling, methods,
auth time and root token id, so a hop token can be exchanged again
without the original context.

A delegated subject reaches only its own project and stays bounded by
its roles on every hop. A plain subject may use project or domain
scope. Nothing else is reachable and no Fernet token is ever minted
from the context.

Assisted-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Exchange a user's Keystone token, or the hop token of an earlier
exchange by the same client, for an OnBehalfOf security context bound
to the authenticated client.

The client must authenticate by its SVID and hold the on_behalf_of
policy. Trust, service grant and other actors' tokens are refused.
The chain ends with its root token's revocation, the user's or
domain's state, the live roles and the client's operation lifetime.

Assisted-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
A service that authenticates with its SVID on the internal interface
and presents no client secret now exchanges a user's token through the
existing token-exchange grant. subject_token_type selects a Keystone
token or the hop token of an earlier exchange.

The token names the user as sub and the service as act, never
outlives the client's operation lifetime and carries no refresh token.
Each exchange emits a CADF event with an on_behalf_of attachment that
records the root token, the user, the actor and the delegated project.

Assisted-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Drive the exchange end to end against real providers: a user's real
token is exchanged, the result is signed with the domain key and
exchanged again. The chain keeps its root and auth time, and ends when
the root token is revoked, the role is removed or the client's
operation lifetime passes. Another client cannot continue the chain.

Document the exchange in the admin guide and record the ceiling
decision in the ADR.

Assisted-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Close the gaps found reviewing the on-behalf-of exchange.

- Reject restricted application credentials as subject, as their
  restriction cannot be carried along.
- Treat every on-behalf-of token as delegated, so trust, credential
  and EC2 policies bound a token a service holds.
- Carry the application credential id and recheck that it exists and
  has not expired on every hop.
- Derive auth_time from the token expiry and use the last audit id as
  root_jti, so rescoping neither extends nor hides the chain.
- Keep a renewed token within the audience of the hop token.
- Audit refused exchanges and read client_id from Basic auth too.
- Look up max_role_ids concurrently, share the rate limit key helper
  and drop an unreachable branch.

Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Revocation events are recorded under the first audit id of the revoked
token, so the chain must be keyed on it to end when the token the user
handed over is revoked. The last id matched no event.

Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Set the new cnf claim and dpop_bound_access_tokens field that landed
on main. On-behalf-of tokens stay bearer tokens, like the other
service grants. Drop a stray conflict marker left in the live
service grant test.

Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
@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
84,301.00 ns
(-38.49%)Baseline: 137,054.11 ns
262,278.58 ns
(32.14%)
Command_Serde/apply/set📈 view plot
🚷 view threshold
91,495.00 ns
(-35.54%)Baseline: 141,939.64 ns
247,142.65 ns
(37.02%)
Command_Serde/pack/delete📈 view plot
🚷 view threshold
102.02 ns
(-11.12%)Baseline: 114.79 ns
164.59 ns
(61.98%)
Command_Serde/pack/delete_index📈 view plot
🚷 view threshold
92.31 ns
(-10.57%)Baseline: 103.22 ns
144.53 ns
(63.87%)
Command_Serde/pack/set📈 view plot
🚷 view threshold
163.35 ns
(-12.19%)Baseline: 186.04 ns
270.77 ns
(60.33%)
Command_Serde/pack/set_index📈 view plot
🚷 view threshold
92.19 ns
(-11.01%)Baseline: 103.59 ns
146.59 ns
(62.89%)
Command_Serde/unpack/delete📈 view plot
🚷 view threshold
141.18 ns
(-2.27%)Baseline: 144.45 ns
217.38 ns
(64.95%)
Command_Serde/unpack/delete_index📈 view plot
🚷 view threshold
124.47 ns
(+1.76%)Baseline: 122.32 ns
183.06 ns
(67.99%)
Command_Serde/unpack/set📈 view plot
🚷 view threshold
197.09 ns
(-11.83%)Baseline: 223.54 ns
345.25 ns
(57.09%)
Command_Serde/unpack/set_index📈 view plot
🚷 view threshold
119.38 ns
(-1.98%)Baseline: 121.79 ns
180.73 ns
(66.05%)
Payload_encryption/pack/remove_cmd📈 view plot
🚷 view threshold
97.16 ns
(-8.86%)Baseline: 106.60 ns
159.50 ns
(60.92%)
Payload_encryption/pack/set_cmd📈 view plot
🚷 view threshold
157.45 ns
(-17.98%)Baseline: 191.96 ns
292.67 ns
(53.80%)
Payload_encryption/unpack/remove_cmd📈 view plot
🚷 view threshold
148.93 ns
(+1.61%)Baseline: 146.57 ns
218.78 ns
(68.07%)
Payload_encryption/unpack/set_cmd📈 view plot
🚷 view threshold
201.50 ns
(-11.40%)Baseline: 227.43 ns
349.83 ns
(57.60%)
Raft_1Node_Latency/prefix/1node📈 view plot
🚷 view threshold
3,860,100.00 ns
(+6.39%)Baseline: 3,628,337.66 ns
8,736,647.71 ns
(44.18%)
Raft_1Node_Latency/read/1node📈 view plot
🚷 view threshold
24,138.00 ns
(-29.48%)Baseline: 34,230.17 ns
52,373.44 ns
(46.09%)
Raft_1Node_Latency/remove/1node📈 view plot
🚷 view threshold
229,640.00 ns
(-35.18%)Baseline: 354,294.69 ns
597,366.53 ns
(38.44%)
Raft_1Node_Latency/write/1node📈 view plot
🚷 view threshold
242,580.00 ns
(-37.80%)Baseline: 389,994.84 ns
770,143.20 ns
(31.50%)
build_snapshot/default📈 view plot
🚷 view threshold
1,743.00 ns
(-15.83%)Baseline: 2,070.79 ns
2,784.15 ns
(62.60%)
fernet token/project📈 view plot
🚷 view threshold
1,165.10 ns
(-7.88%)Baseline: 1,264.76 ns
1,753.62 ns
(66.44%)
get_data_keyspace📈 view plot
🚷 view threshold
0.27 ns
(-6.80%)Baseline: 0.29 ns
0.38 ns
(72.18%)
get_db📈 view plot
🚷 view threshold
0.27 ns
(-7.04%)Baseline: 0.29 ns
0.38 ns
(72.18%)
get_fernet_token_timestamp/project📈 view plot
🚷 view threshold
114.98 ns
(-12.19%)Baseline: 130.94 ns
183.07 ns
(62.81%)
get_keyspace📈 view plot
🚷 view threshold
3.53 ns
(-46.75%)Baseline: 6.62 ns
15.45 ns
(22.84%)
🐰 View full continuous benchmarking report in Bencher

@github-actions

Copy link
Copy Markdown

🦢 Load Test Results

Goose Attack Report

Plan Overview

Action Started Stopped Elapsed Users
Increasing 26-10-22 09:57:08 26-10-22 09:57:31 00:00:23 0 → 45
Maintaining 26-10-22 09:57:31 26-10-22 09:58:01 00:00:30 45
Decreasing 26-10-22 09:58:01 26-10-22 09:58:01 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 42 0 543.38 185 701 1.40 0.00
DELETE DELETE /v3/projects/:id (teardown) 1 0 223.00 223 223 0.03 0.00
DELETE DELETE /v3/roles/:id (teardown) 1 0 277.00 277 277 0.03 0.00
DELETE DELETE /v3/users/:id (teardown) 2 0 154.50 134 175 0.07 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (cc teardown) 1 0 30.00 30 30 0.03 0.00
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 1 0 204.00 204 204 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (cc teardown) 1 0 33.00 33 33 0.03 0.00
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 1 0 287.00 287 287 0.03 0.00
GET 463 0 628.97 380 872 15.43 0.00
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 48 31 275.50 2 800 1.60 1.03
GET GET /v3/auth/tokens (validate new) 42 0 632.52 474 741 1.40 0.00
GET GET /v3/auth/tokens (validate revoked) 42 0 510.95 47 722 1.40 0.00
GET GET /v3/projects/:id 52 0 588.31 405 736 1.73 0.00
GET GET /v3/projects/:id (catalog) 78 0 596.51 416 786 2.60 0.00
GET GET /v3/role_assignments 39 0 601.92 468 759 1.30 0.00
GET GET /v3/role_assignments?role.id 40 0 582.60 442 719 1.33 0.00
GET GET /v3/role_assignments?scope.domain.id 40 0 565.20 403 793 1.33 0.00
GET GET /v3/role_assignments?user.id 40 0 548.72 329 718 1.33 0.00
GET GET /v3/roles 104 0 583.01 391 790 3.47 0.00
GET GET /v3/roles/:id 52 0 584.00 421 817 1.73 0.00
GET GET /v3/users/:id 100 0 609.40 438 850 3.33 0.00
GET GET /v3/users/:id (catalog) 98 0 601.95 426 836 3.27 0.00
GET GET /v4/api-keys 29 0 523.31 366 701 0.97 0.00
GET GET /v4/api-keys/:client_id 28 0 547.11 467 671 0.93 0.00
GET GET /v4/mappings/rulesets 28 0 544.50 453 739 0.93 0.00
GET GET /v4/mappings/rulesets/:mapping_id 28 0 543.71 335 748 0.93 0.00
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 2018 0 21.70 3 133 67.27 0.00
GET GET /v4/oauth2/:domain_id/clients 28 0 548.00 441 651 0.93 0.00
GET GET /v4/oauth2/:domain_id/clients/:provider_id 28 0 546.36 438 749 0.93 0.00
GET GET /v4/oauth2/:domain_id/jwks 2018 0 21.92 4 119 67.27 0.00
GET GET /v4/scim_realms 19 0 505.16 372 651 0.63 0.00
GET GET /v4/scim_realms/:domain_id/:provider_id 18 0 525.83 440 627 0.60 0.00
POST POST /v3/auth/tokens 41 0 525.71 404 806 1.37 0.00
POST POST /v3/auth/tokens (password, invalid) 37 0 841.05 536 1294 1.23 0.00
POST POST /v3/auth/tokens (password, project-scoped) 56 0 1204.32 799 1714 1.87 0.00
POST POST /v3/auth/tokens (password, unscoped) 55 0 1008.18 506 1560 1.83 0.00
POST POST /v3/auth/tokens (rescope to system) 94 0 656.26 425 993 3.13 0.00
POST POST /v3/auth/tokens (rescope, invalid project) 56 0 548.71 391 773 1.87 0.00
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 53 0 1166.19 645 1693 1.77 0.00
POST POST /v4/api-keys/:client_id/revoke (teardown) 1 0 133.00 133 133 0.03 0.00
POST POST /v4/oauth2/:domain_id/device_authorization 576 0 51.66 12 173 19.20 0.00
POST POST /v4/oauth2/:domain_id/token (client_credentials) 16 0 574.38 313 835 0.53 0.00
PUT PUT /v4/scim_realms/:domain_id/:provider_id 19 0 617.68 431 726 0.63 0.00
Aggregated 6534 31 204.37 2 1714 217.80 1.03

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) 223 223 223 223 223 223 223 223
DELETE DELETE /v3/roles/:id (teardown) 277 277 277 277 277 277 277 277
DELETE DELETE /v3/users/:id (teardown) 134 134 134 175 175 175 175 175
DELETE DELETE /v4/mappings/rulesets/:mapping_id (cc teardown) 30 30 30 30 30 30 30 30
DELETE DELETE /v4/mappings/rulesets/:mapping_id (teardown) 204 204 204 204 204 204 204 204
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (cc teardown) 33 33 33 33 33 33 33 33
DELETE DELETE /v4/oauth2/:domain_id/clients/:provider_id (teardown) 287 287 287 287 287 287 287 287
GET 600 700 700 700 800 800 800 872
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 290 360 420 460 600 600 800 800
GET GET /v3/auth/tokens (validate new) 600 700 700 700 700 700 700 700
GET GET /v3/auth/tokens (validate revoked) 500 600 600 600 700 700 700 700
GET GET /v3/projects/:id 600 600 600 700 700 700 700 700
GET GET /v3/projects/:id (catalog) 600 600 700 700 700 700 786 786
GET GET /v3/role_assignments 600 600 600 700 700 700 759 759
GET GET /v3/role_assignments?role.id 600 600 600 600 700 700 700 700
GET GET /v3/role_assignments?scope.domain.id 600 600 600 600 600 700 793 793
GET GET /v3/role_assignments?user.id 500 600 600 700 700 700 700 700
GET GET /v3/roles 600 600 600 600 700 700 790 790
GET GET /v3/roles/:id 600 600 600 600 700 700 700 800
GET GET /v3/users/:id 600 600 700 700 700 800 800 850
GET GET /v3/users/:id (catalog) 600 600 700 700 700 700 800 800
GET GET /v4/api-keys 500 500 600 600 600 700 700 700
GET GET /v4/api-keys/:client_id 500 500 600 600 600 671 671 671
GET GET /v4/mappings/rulesets 500 500 600 600 600 700 700 700
GET GET /v4/mappings/rulesets/:mapping_id 500 600 600 600 600 700 700 700
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 18 21 24 29 37 45 66 130
GET GET /v4/oauth2/:domain_id/clients 600 600 600 600 600 600 651 651
GET GET /v4/oauth2/:domain_id/clients/:provider_id 500 600 600 600 600 700 700 700
GET GET /v4/oauth2/:domain_id/jwks 19 21 24 29 38 46 74 119
GET GET /v4/scim_realms 500 500 600 600 600 600 651 651
GET GET /v4/scim_realms/:domain_id/:provider_id 500 500 600 600 600 600 600 600
POST POST /v3/auth/tokens 500 500 600 600 600 600 800 800
POST POST /v3/auth/tokens (password, invalid) 900 900 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,714 1,714 1,714
POST POST /v3/auth/tokens (password, unscoped) 1,000 1,000 1,000 1,000 1,000 1,000 1,000 1,560
POST POST /v3/auth/tokens (rescope to system) 700 700 700 700 800 800 800 993
POST POST /v3/auth/tokens (rescope, invalid project) 600 600 600 600 600 700 700 773
POST POST /v3/auth/tokens (system-scoped, bootstrap admin) 1,000 1,000 1,000 1,000 1,693 1,693 1,693 1,693
POST POST /v4/api-keys/:client_id/revoke (teardown) 133 133 133 133 133 133 133 133
POST POST /v4/oauth2/:domain_id/device_authorization 47 51 57 66 79 95 130 170
POST POST /v4/oauth2/:domain_id/token (client_credentials) 600 600 600 700 800 800 800 800
PUT PUT /v4/scim_realms/:domain_id/:provider_id 600 600 600 700 700 700 700 700
Aggregated 28 40 85 500 700 700 1,000 1,714

Status Code Metrics

Method Name Status Codes
DELETE DELETE /v3/auth/tokens 42 [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 463 [200]
GET GET /SCIM/v2/:domain_id/Users (sync reconcile list) 31 [401], 17 [429]
GET GET /v3/auth/tokens (validate new) 42 [200]
GET GET /v3/auth/tokens (validate revoked) 42 [404]
GET GET /v3/projects/:id 52 [200]
GET GET /v3/projects/:id (catalog) 78 [200]
GET GET /v3/role_assignments 39 [200]
GET GET /v3/role_assignments?role.id 40 [200]
GET GET /v3/role_assignments?scope.domain.id 40 [200]
GET GET /v3/role_assignments?user.id 40 [200]
GET GET /v3/roles 104 [200]
GET GET /v3/roles/:id 52 [200]
GET GET /v3/users/:id 100 [200]
GET GET /v3/users/:id (catalog) 98 [200]
GET GET /v4/api-keys 29 [200]
GET GET /v4/api-keys/:client_id 28 [200]
GET GET /v4/mappings/rulesets 28 [200]
GET GET /v4/mappings/rulesets/:mapping_id 28 [200]
GET GET /v4/oauth2/:domain_id/.well-known/openid-configuration 2,018 [200]
GET GET /v4/oauth2/:domain_id/clients 28 [200]
GET GET /v4/oauth2/:domain_id/clients/:provider_id 28 [200]
GET GET /v4/oauth2/:domain_id/jwks 2,018 [200]
GET GET /v4/scim_realms 19 [200]
GET GET /v4/scim_realms/:domain_id/:provider_id 18 [200]
POST POST /v3/auth/tokens 41 [201]
POST POST /v3/auth/tokens (password, invalid) 37 [401]
POST POST /v3/auth/tokens (password, project-scoped) 56 [201]
POST POST /v3/auth/tokens (password, unscoped) 55 [201]
POST POST /v3/auth/tokens (rescope to system) 94 [201]
POST POST /v3/auth/tokens (rescope, invalid project) 56 [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 576 [200]
POST POST /v4/oauth2/:domain_id/token (client_credentials) 16 [200]
PUT PUT /v4/scim_realms/:domain_id/:provider_id 19 [200]
Aggregated 6,002 [200], 124 [401], 299 [201], 50 [204], 17 [429], 42 [404]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
ReadHeavy
0.0 1 0 22.00 22 22 0.03 0.00
0.1 68 0 660.51 526 847 2.27 0.00
0.2 67 0 592.67 380 748 2.23 0.00
0.3 65 0 571.29 430 731 2.17 0.00
TokenLifecycle
1.0 0 0 0.00 0 0 0.00 0.00
1.1 42 0 2214.31 1411 2567 1.40 0.00
ValidateToken
2.0 0 0 0.00 0 0 0.00 0.00
2.1 88 0 695.02 394 872 2.93 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 100 0 609.49 438 850 3.33 0.00
3.3 2 0 154.50 134 175 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 52 0 588.35 405 736 1.73 0.00
4.3 1 0 224.00 224 224 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 52 0 584.04 421 817 1.73 0.00
5.3 1 0 277.00 277 277 0.03 0.00
RoleList
6.0 0 0 0.00 0 0 0.00 0.00
6.1 104 0 583.06 391 790 3.47 0.00
RoleAssignmentList
7.0 0 0 0.00 0 0 0.00 0.00
7.1 39 0 601.95 468 759 1.30 0.00
7.2 40 0 548.80 329 718 1.33 0.00
7.3 40 0 565.22 403 793 1.33 0.00
7.4 40 0 582.78 442 720 1.33 0.00
UserRead
8.0 0 0 0.00 0 0 0.00 0.00
8.1 98 0 649.79 457 838 3.27 0.00
8.2 98 0 602.08 426 836 3.27 0.00
ProjectRead
9.0 0 0 0.00 0 0 0.00 0.00
9.1 77 0 579.79 399 811 2.57 0.00
9.2 78 0 596.54 416 786 2.60 0.00
PasswordAuth
10.0 55 0 1008.22 506 1560 1.83 0.00
10.1 56 0 1204.43 799 1714 1.87 0.00
PasswordAuthNegative
11.0 37 0 841.08 536 1294 1.23 0.00
Rescope
12.0 0 0 0.00 0 0 0.00 0.00
12.1 94 0 656.41 425 993 3.13 0.00
RescopeNegative
13.0 0 0 0.00 0 0 0.00 0.00
13.1 56 0 548.77 391 773 1.87 0.00
SystemScopeAuth
14.0 53 0 1166.25 645 1693 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 28 0 547.11 467 671 0.93 0.00
15.3 29 0 523.34 366 701 0.97 0.00
15.4 1 0 133.00 133 133 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 28 0 543.71 335 748 0.93 0.00
16.3 28 0 544.54 453 739 0.93 0.00
16.4 1 0 204.00 204 204 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 546.43 438 749 0.93 0.00
17.3 28 0 548.07 441 651 0.93 0.00
17.4 1 0 287.00 287 287 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 16 0 574.38 313 835 0.53 0.00
18.3 1 0 63.00 63 63 0.03 0.00
OAuth2DeviceAuthorization
19.0 576 0 51.74 12 173 19.20 0.00
OAuth2Discovery
20.0 2018 0 21.99 4 119 67.27 0.00
20.1 2018 0 21.76 3 133 67.27 0.00
ScimRealmRead
21.0 0 0 0.00 0 0 0.00 0.00
21.1 18 0 525.89 440 627 0.60 0.00
21.2 19 0 505.26 372 651 0.63 0.00
21.3 19 0 617.74 431 726 0.63 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 48 0 630.02 184 1030 1.60 0.00
22.4 47 0 0.00 0 0 1.57 0.00
22.5 47 0 0.00 0 0 1.57 0.00
22.6 1 0 0.00 0 0 0.03 0.00
Aggregated 6504 0 205.31 3 2567 216.80 0.00

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
ReadHeavy 4 64 1822.19 1587 2107 2.13 16.00
TokenLifecycle 3 39 2267.41 1941 2567 1.30 13.00
ValidateToken 2 86 699.91 479 872 2.87 43.00
UserCRUD 2 98 610.82 438 850 3.27 49.00
ProjectCRUD 1 51 589.59 405 736 1.70 51.00
RoleCRUD 1 51 583.67 421 817 1.70 51.00
RoleList 2 102 582.38 391 790 3.40 51.00
RoleAssignmentList 3 39 2300.51 1985 2617 1.30 13.00
UserRead 4 96 1251.28 930 1621 3.20 24.00
ProjectRead 3 75 1174.29 859 1415 2.50 25.00
PasswordAuth 4 54 2211.00 1688 2844 1.80 13.50
PasswordAuthNegative 1 36 849.56 542 1294 1.20 36.00
Rescope 2 92 658.23 425 993 3.07 46.00
RescopeNegative 1 55 550.45 391 773 1.83 55.00
SystemScopeAuth 2 51 1178.86 645 1693 1.70 25.50
ApiKeyCRUD 1 28 1078.57 898 1338 0.93 28.00
MappingCRUD 1 27 1089.11 886 1351 0.90 27.00
OAuth2ClientCRUD 1 27 1095.22 894 1314 0.90 27.00
OAuth2ClientCredentials 1 16 1935.94 1591 2618 0.53 16.00
OAuth2DeviceAuthorization 1 575 51.73 12 173 19.17 575.00
OAuth2Discovery 3 2016 44.23 11 211 67.20 672.00
ScimRealmRead 1 18 1657.33 1484 1836 0.60 18.00
ScimSync 1 47 637.55 184 1030 1.57 47.00
Aggregated 45 3743 358.55 11 2844 124.77 1922.00

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

View full report

@github-actions

Copy link
Copy Markdown

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

rust

Totals
======
Ran: 133 tests in 36.7568 sec.
 - Passed: 83
 - Skipped: 4
 - Expected Fail: 0
 - Unexpected Success: 0
 - Failed: 46
Sum of execute time for each test: 29.9138 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_domain_configuration.DomainConfigurationTestJSON.test_create_domain_config_and_show_config_groups_and_options[id-9e3ff13c-f597-4f01-9377-d6c06c2a1477]
tempest.api.identity.admin.v3.test_domain_configuration.DomainConfigurationTestJSON.test_create_update_and_delete_domain_config_groups_and_opts[id-c7510fa2-6661-4170-9c6b-4783a80651e9]
tempest.api.identity.admin.v3.test_domain_configuration.DomainConfigurationTestJSON.test_show_default_group_config_and_options[id-11a02bf0-6f94-4380-b3b0-c8dc18fc0d22]
tempest.api.identity.admin.v3.test_domains_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_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_projects.ProjectsTestJSON.test_create_is_domain_project[id-a7eb9416-6f9b-4dbb-b71b-7f73aaef59d5]
tempest.api.identity.admin.v3.test_projects.ProjectsTestJSON.test_project_create_with_parent[id-1854f9c0-70bc-4d11-a08a-1c789d339e3d]
tempest.api.identity.admin.v3.test_project_tags.IdentityV3ProjectTagsTest.test_list_update_delete_project_tags[id-7c123aac-999d-416a-a0fb-84b915ab10de]
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_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_inherits.InheritsV3TestJSON.test_inherit_assign_check_revoke_roles_on_projects_group[id-26021436-d5a4-4256-943c-ded01e0d4b45]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_check_revoke_roles_on_projects_user[id-18b70e45-7687-4b72-8277-b8f1a47d7591]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_list_check_revoke_roles_on_domains_group[id-c7a8dda2-be50-4fb4-9a9c-e830771078b1]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_list_check_revoke_roles_on_domains_user[id-4e6f0366-97c8-423c-b2be-41eae6ac91c8]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_list_revoke_user_roles_on_domain[id-3acf666e-5354-42ac-8e17-8b68893bcd36]
tempest.api.identity.admin.v3.test_inherits.InheritsV3TestJSON.test_inherit_assign_list_revoke_user_roles_on_project_tree[id-9f02ccd9-9b57-46b4-8f77-dd5a736f3a06]
tempest.api.identity.admin.v3.test_list_projects.ListProjectsTestJSON.test_list_projects_with_parent[id-6edc66f5-2941-4a17-9526-4073311c1fac]
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_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.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_tokens.TokensV3TestJSON.test_rescope_token[id-565fa210-1da1-4563-999b-f7b5b67cf112]
tempest.api.identity.v3.test_tokens.TokensV3Test.test_validate_token[id-a9512ac3-3909-48a4-b395-11f438e16260]
tempest.api.identity.v3.test_catalog.IdentityCatalogTest.test_catalog_standardization[id-56b57ced-22b8-4127-9b8a-565dfb0207e2]
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_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]
===== END FAILED TESTS (target=rust) =====

View full run

Gate J rejects wildcard arms in validate_scope_boundaries. List the
Some and None cases of the on-behalf-of project check explicitly.

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

This branch has not been deployed

No deployments
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