Skip to content

Knox 3334 - Introduce ActorChainPrincipal for RFC 8693 instead of ImpersonatedPrincipal#1257

Open
lmccay wants to merge 2 commits into
apache:masterfrom
lmccay:KNOX-3334
Open

Knox 3334 - Introduce ActorChainPrincipal for RFC 8693 instead of ImpersonatedPrincipal#1257
lmccay wants to merge 2 commits into
apache:masterfrom
lmccay:KNOX-3334

Conversation

@lmccay

@lmccay lmccay commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

(It is very important that you created an Apache Knox JIRA for this change and that the PR title/commit message includes the Apache Knox JIRA ID!)

KNOX-3334 Introduce ActorChainPrincipal for RFC 8693 instead of ImpersonatedPrincipal

What changes were proposed in this pull request?

KNOX-3321 provided an initial implementation for 8693 and adding an 'act' claim to the returned JWT based on the presence of the ImpersonatedPrincipal and having delegated auth enabled on the KnoxToken service.

This falls short of what we need to support token exchanges that already include an 'act' claim in the subject token. To support this properly, we need the previous 'act' claim represented in the Java Subject with the full chain represented. We will then add the next actor subclaim to the chain from within the KnoxToken service, effectively continuing the chain as it flows through the actors for the given request.

To support this, we should introduce a new principal called ActorChainPrincipal which will have an extended interface to provide the list of 'act' claims within the presented token for building out the chain in the new token.

How was this patch tested?

  • Built and ran existing tests
  • Added new tests
  • Manually tested as follows:

curl -ivku admin:admin-password 'https://localhost:8443/gateway/knoxcreds/knoxtoken/api/v1/token?doAs=guest'

{"access_token":"eyJqa3UiOiJodHRwczovL2xvY2FsaG9zdDo4NDQzL2dhdGV3YXkva25veGNyZWRzL2tub3h0b2tlbi9hcGkvdjEvandrcy5qc29uIiwia2lkIjoiS1M2enJFSUsxSFJTbUQ4Ri1FckhnOWc2bHlSQ1A1WUcxLUN0TFFaM2U2byIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJndWVzdCIsImFjd...uIiwia2lkIjoiS1M2enJFSUsxSFJTbUQ4Ri1FckhnOWc2bHlSQ1A1WUcxLUN0TFFaM2U2byIsImlzcyI6IktOT1hTU08iLCJtYW5hZ2VkLnRva2VuIjoidHJ1ZSIsImtub3guaWQiOiI1YTk4MzM4ZC1kNjlkLTRlNTEtYWNiMS0yNzVhNzZkYzE4M2UifQ.VJOd0pJFwQpWFWv7Xo661pKFMl8md_1UmYf1kLdQIgeVfLhhwWINAKqpD-9Od6YwWIXlfr3SBGbPoHeMQYZp1fEOt4fx1gyFo08VGhDSJMI63FX93KpvDrdeECKwcKimIhnh9H9VEQLP56WOBqn3eYoc8aJFua4Ydh9dC0b0AbnVSrDqoS3hOJLwGsj602NvsIU5IoxmYz8s7rNO7CN6qynxmTp-w4g1Q3skmqU8zki9DvEMJXMRdMsflssFDWrybw0UvzMjjmKQxzKqcb9jsnM3lrsqit7-JEg6kPNA5M5IWIKgkIgt-P_iYAr6ouXt0BxxGfJplK_rF2qxkD98xg","token_id":"5a98338d-d69d-4e51-acb1-275a76dc183e","managed":"true","endpoint_public_cert":"MIIDZDCCAkygAwIBAgIISWFJksv5UD4wDQYJKoZIhvcNAQELBQAwXzESMBAGA1UEAwwJbG9jYWxob3N0MQ0wCwYDVQQLDARUZXN0MQ8wDQYDVQQKDAZIYWRvb3AxDTALBgNVBAcMBFRlc3QxDTALBgNVBAgMBFRlc3QxCzAJBgNVBAYTAlVTMB4XDTI2MDYxMDIxMTg1M1oXDTI3MDYxMDIxMTg1M1owXzESMBAGA1UEAwwJbG9jYWxob3N0MQ0wCwYDVQQLDARUZXN0MQ8wDQYDVQQKDAZIYWRvb3AxDTALBgNVBAcMBFRlc3QxDTALBgNVBAgMBFRlc3QxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApSDLZB9y0gV5W9HEmV49GAo4PH9JTmfISUCTGYZ5z6pwU0ierFz0Qm....OCNkLF4fj5iQAqyp+6lF7e1Wj50oaKCTsLkxV+3bn2PVdI7rYR9wS6t6V7MuoaLbgcL/RY8/ec3qUC6NvQIDAQABoyQwIjAgBgNVHREEGTAXggpHV1dZRkc2NU1Rgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAD8URUGKn4Em8AtVBrLxfwxyvPxWHXUONERbFKizIV2xkTcxgNnoKKUaHX2A8f0DW1OQ1KsiR2mp8ygeZcqgsCcEpPGnzYnfknD58nEDOXPpg2vy64ppIXzXPbR6PUBQo9zuIH5n+JlFhR5dP0WugqdNarKwtNCSjDRmjiLki4quuM8Wd4kSflHZmFwehqUH0Hc4mtdvrrCZUrz3RnK0N/oBW3Mbr5/0gj6CzC4YgKqCipRzCvJ9RKrewOumPLhg5m2Zb6NfDJXVFG4WhrYF+dRX0Dljngy2eLsTOdg4nlenRZYZWZL6/UpnpjSik/J3AFB7CPLStC280QP6m/89R5o=","token_type":"Bearer","expires_in":-1,"passcode":"TldFNU9ETXpPR1F0WkRZNVpDMDBaVFV4TFdGallqRXRNamMxWVRjMlpHTXhPRE5sOjpZVEF5TlRVeFlqSXRPR05rTVMwME56STFMVGhrTlRZdE1USmtNamxpT0dSbVpURmg="}%

curl -ivk -H 'Authorization: Bearer eyJqa3UiOiJodHRwczovL2xvY2FsaG9zdDo4NDQzL2dhdGV3YXkva25veGNyZWRzL2tub3h0b2tlbi9hcGkvdjEvandrcy5qc29uIiwia2lkIjoiS1M2enJFSUsxSFJTbUQ4Ri1....1ZSIsImtub3guaWQiOiI1YTk4MzM4ZC1kNjlkLTRlNTEtYWNiMS0yNzVhNzZkYzE4M2UifQ.VJOd0pJFwQpWFWv7Xo661pKFMl8md_1UmYf1kLdQIgeVfLhhwWINAKqpD-9Od6YwWIXlfr3SBGbPoHeMQYZp1fEOt4fx1gyFo08VGhDSJMI63FX93KpvDrdeECKwcKimIhnh9H9VEQLP56WOBqn3eYoc8aJFua4Ydh9dC0b0AbnVSrDqoS3hOJLwGsj602NvsIU5IoxmYz8s7rNO7CN6qynxmTp-w4g1Q3skmqU8zki9DvEMJXMRdMsflssFDWrybw0UvzMjjmKQxzKqcb9jsnM3lrsqit7-JEg6kPNA5M5IWIKgkIgt-P_iYAr6ouXt0BxxGfJplK_rF2qxkD98xg' 'https://localhost:8443/gateway/knoxidf/knoxtoken/v1/oauth/tokens?doAs=tom'

{"access_token":"eyJqa3UiOiJodHRwczovL2xvY2FsaG9zdDo4NDQzL2dhdGV3YXkva25veGlkZi9rbm94dG9rZW4vdjEvb2F1dGgvandrcy5qc29uIiwia2lkIjoiS1M2enJFSUsxSFJTbUQ4Ri1FckhnOWc2bHlSQ1A1WUcxLUN0TFFaM2U2byIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJ0b20iLCJhY3QiOn....ZTZvIiwiaXNzIjoiS05PWFNTTyIsIm1hbmFnZWQudG9rZW4iOiJ0cnVlIiwia25veC5pZCI6IjQwYTFmNmNmLWRmYzQtNDU3Ny05MmNjLWEwMTI5M2RkYWZiZCJ9.kUi8Mc7E7njrrh3B-UWgDjJVlWm23rRmd6p9en79Q-6Q_I5qw1LQf6bqUPqTwZ35JgZwfcSodFcSuitJwgOOoAbhx3qZR8mTVhoqNyoUtSqmtixkSvMQwXTBZtcWDKyjc208LZCs6Vv21T_oHXHuInSUZnTjghoM_gh1JrcIkxvLPaz8utL-aWc_1cJvNKNvQtz5uuU_FynLLhBCJQ-dJnKOlJ4-HXZwlnA9QhaEQDW-07n-R7ZhM_urqrrmYdYKNlyRztoCiD7M13pSwdjxf4AQura1vV7AyRwEEfI1gTPZ7L2xP52dVBU1R_sBz83NuXzSOumpGWJa8x4eWOIXsA","refresh_token":"d7622c25-4514-463d-a608-37aadbba0cce","issued_token_type":"urn:ietf:params:oauth:token-type:access_token","token_type":"Bearer","expires_in":-1}

image

@github-actions

Copy link
Copy Markdown

Test Results

22 tests   22 ✅  2s ⏱️
 1 suites   0 💤
 1 files     0 ❌

Results for commit 8d2a990.

@lmccay lmccay requested review from hanicz and smolnar82 June 11, 2026 00:03
* <p>This is equivalent to calling {@code getActorChain().get(0).get("sub")}
* if the chain is not empty.</p>
*
* @return the subject of the most recent actor, or null if the chain is empty

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe return Optional<String> instead of null?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this brings anything meaningful to the table. It really isn't expected that this would be an Optional return value. If there is an empty Map then a return for a given key will be a null. Adding the ceremony around checking for ifPresent type checks in this case is outside of what the contract would expect. I would even argue that the getActorChain method should return null but I went with the empty List to be somewhat safer. It really isn't optional to have the 'sub' as part of an actorChain that is non-empty. If you are looking for a specific key in an empty map or you are using a key that is invalid then it isn't really optional. If this were a map like the token metadata that we have elsewhere and certain metadata items are indeed optional, it makes sense for the contract to call that expectation out in the interface and nudge the ifPresent type checks.

@lmccay lmccay changed the title Knox 3334 Knox 3334 - Introduce ActorChainPrincipal for RFC 8693 instead of ImpersonatedPrincipal Jun 11, 2026
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.

2 participants