Token Delegation (a form of extension grant) is when an authorized user/service needs to make futher service calls to downstream dependencies. All the examples below use the asymmetric algorithm RS256 which is means it uses a public and private key pair.
A common flow could be: UI
-> BFF
-> Resource API
Here the user is authenticated at the UI
. This means they have a token that grants them access to do their work. Best practice would be Authorization Code + PKCE. This token is used when the user interacts with the the BFF
.
Example JWT (JSON Web Token) generated at jwt.io that could be used between UI
and BFF
:
1 | eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2p3dC5pby8iLCJhdWQiOiJiZmYtYXBpIiwiaWF0IjoxNjI1NzY5MzI2LCJleHAiOjE2MjU3Njk5MjYsInVzZXItZnVsbG5hbWUiOiJDYXJsIFBhdG9uIiwidXNlci1pZCI6IjE2ZDMyMTc3LTgxY2YtNDg0OC04NWYzLTYxNTRhZDg0NzJhZSJ9.EYKK4GjD_GokVLcVP5Po1pY8AH6nXiPwG9iDK3-dRUh27XrJ_LW4ZgD-7m0bl0MYIWkqhWZbZFNUTpdhBXtZNBDMQzDaF-Y9S0XhlGfnQiHDM6-f_o0xoB-GYO0K1d9l1Ixi-gwkCIrViJ4hWItxridSdR1hsMaCzTvRv4HVjE6DU1NrpCdD8KDHGTFi55IFTv7PWbQoEabZxZ2CYVfHPSmajv_cfG9BIC_Vm04meKrU2wbWDU9R3vkiwxX00RK_Vmjj90hafe3cbEHJ2aRtkIjXOkBx-r6Zifibhmwf8SENZOdpRCt1fpV1oHd6bLtj_9_dyMiPvVkHB3DD0lebDQ |
The decoded payload is
1 | { |
The BFF
may check any of these claims to validate the token.
- “iss” (Issuer) Claim
- “aud” (Audience) Claim
- “iat” (Issued At) Claim
- “exp” (Expiration Time) Claim
- The
user-x
claims are not part of rfc7519, these are custom claims I made up and can be anything.
The delegation token comes into play when the BFF
needs to make a call to the Resource API
. The current token claims may not satisfy this request as additional claims or scopes may be required.
Example based on scottbrady91.com
Here we would take the token above and pass it as a form field parameter of &token=
along with the scope we need, the example below is &scope=calendar.edit
. This assumes the client resource-api
has been provisioned to have these scopes and the required additional claims are returned.
1 | POST /token |
The response JWT could be
1 | eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2p3dC5pby8iLCJhdWQiOiJyZXNvdXJjZS1hcGkiLCJpYXQiOjE2MjU3NjkzMjYsImV4cCI6MTYyNTc2OTkyNiwidXNlci1mdWxsbmFtZSI6IkNhcmwgUGF0b24iLCJ1c2VyLWlkIjoiMTZkMzIxNzctODFjZi00ODQ4LTg1ZjMtNjE1NGFkODQ3MmFlIiwidXNlci1hY2Nlc3MiOiJyZXNvdXJjZS1hcGkiLCJzY29wZSI6WyJjYWxlbmRhci5lZGl0Il19.SW1f7_XVkWE4B_XtjF_Ti6-Z6Zs9XozJz0YIW768NM2n0e2Wf8pHh9jme_dTpwtLAS2_fJt5taVkdYC1d8nK38_aeW6qEYrdaj29FO--D-hJAdxOGSM1gbUwXbuKjawMSMCkwmVO8g9bPJ8ayBx07KURAa0ke8KeGL_GlvsBsInGzJaGC6SuPdkynQu2H0pfaduD0IHVvpVucg1p-fRSg5D7joNIcpxIaHne2SOkz9xNMLNOQuluifQ2Us_hpzc31h5Bn7GJBzMd8ZNFIp8C5AJnqyM5EG7M0suvHkJ-ThXPYO1VgTGVpparfXU547NM-d_W7IY1MFg1gMLWDj2chg |
The decoded payload is
1 | { |
This token can then be used to query Resource API
with endpoints that require these new claims such as
- The
calendar.edit
scope - The claim
user-access
to equalresource-api
These checks would be anything that is sensible to your business requirements. Its would also be best practice to check aud=resource-api
.