I am currently implementing an OAuth token exchange STS and am struggling a bit. The standard is defined in https://www.rfc-editor.org/rfc/rfc8693 My use case involves a chain of system-to-system calls, triggered by a user (principal) action. I want to make sure that authorization on endpoint levels is done by a mix of scopes and white-listed client_ids. In addition I'd like to keep the customer context.
I see that the token exchange scenario is valid here. The specification gives an example where the resulting token contains the actor to whom access was delegated. However, the specification puts the logical system (aka OAuth client) into the "sub" claim of the nested actor information, as shown here:
{
"aud":"https://service26.example.com",
"iss":"https://issuer.example.com",
"exp":1443904100,
"nbf":1443904000,
"sub":"user@example.com",
"act":
{
"sub":"https://service16.example.com",
"act":
{
"sub":"https://service77.example.com"
}
}
}
I find this a bit odd. I would expect the "sub" claim to carry an actual subject, if the actor token was a personalized token as well (say, "adminuser"). In my opinion, the system that was conducting the token exchange would send as an actor token a client_credentials token. This does not contain a "sub" claim, but only the "cid" (client_id) claim. This claim should be included in the "act" claim of the resulting token, so I would expect the resulting token to look like this:
{
"aud":"https://service26.example.com",
"iss":"https://issuer.example.com",
"exp":1443904100,
"nbf":1443904000,
"sub":"user@example.com",
"cid":"3rd_client_that_conducted_token_exchange",
"act":
{
"cid":"2nd_client_id",
"act":
{
"cid":"initial_client_id"
}
}
}
I'm not sure if there is a required structure for the "act" claim (as far as I see, no). Is there a best practice to follow here? Curious for your thoughts! :)