---
# System prepended metadata

title: Combining Token Exchange and Bearer Flow to achieve Identity Chaining

---

# Combining Token Exchange and Bearer Flow to achieve Identity Chaining

## TLDR;
In previous proposals, rs.example.com always asked as.example.com to exchange a token before presenting to rs.example.org. This required as.example.com to know which AS to use, something not supported in the current token exchange protocol. It also created the possibility of the connection breaking between as.example.com and as.example.org resulting in a long wait between calls for rs.example.com. 

Instead of rs.example.com using token exchange to receive token for example.org via its own AS (as.example.com) this document proposes an approach that uses a combination of token exchange and bearer flow, both initiated by rs.example.com to acchieve Identity Chaining. 

## Flow

![](https://hackmd.io/_uploads/ryYiHTxrh.png)

- [01] client requests token from as.example.com to access rs.example.com.
- [02] as.example.com returns token.com to access rs.example.com
- [03] client uses received token to access rs.example.com
- [04-07] rs.example.com needs to access a resource outside of example.com domain.
        - [04] rs.example.com performs token exchange with as.example.com. It uses as.example.org as a resource.
        - [05] as.example.com performs checks, reduces scope and claims and returns a new token with as.example.org as an audience.
        - [06] rs.example.com uses this token to perform a bearer-flow/client assertion flow with as.example.org to receive a token for rs.example.org.
        - [07] as.example.org performs required checks, transcribes claims, includes own claims, etc. and returns token.org.
- [08] rs.example.com accesses rs.example.org using token.org.
- [09] rs.example.org is able to perform fine grained authorization based on token.org that also contains claims from example.com. If successful, data is returned.
- [10] rs.example.com returns data to the user.

## Considerations

- It is assumed that rs.example.com knows about rs.example.org and its IDP. In case it doesn't it is possible to perform an authorization request towards rs.example.org to receive its IDP informations (between step 03 and 04).
- as.example.com is able to govern over what external authorization server it trusts and which it doesn't (step 04). This also includes what claims should be transcribed, (could leverage SD-JWT and other selective disclosure options in future).
- Because token.com(as.example.org) which is used as an assertion to receive a token from as.example.org, is audienced to only as.example.org it is not possible to replay the token against rs.example.com
- The bearer flow performed between rs.example.com and as.example.org expects specific behavior (new grant_type?). We expect as.example.org to:
        - deny the request if audience != as.example.org to prevent resources to use access tokens of the user.
        - transcribe claims from assertion token into returned access token (which claims to transcribe is deployment specific and out of scope for this spec, spec can give non-normative guidance on what to transcribe)
        - validate trust relationship (is example.com allowed to federated to example.org)
        - perform all other checks from bearer-flow.
- rs.example.com needs to verify that as.example.org has correctly transcribed all claims.


## High-governance variant

Whilst above works for many use-cases some may require a more strict control on which AS is picked, do not want to expose the AS to the resource at all or resource does not necessary know the sovereign AS. Network restrictions such as Firewall may also prevent them from contacting it directly.

To keep the protocol aligned and not introduce new flows the following approach is proposed:

### TLDR;

The flow of 1. performing internal token exchange to scope down the token and 2. performing a bearer flow to sovereign AS stays the same but the actor/component, who is performing these flows changes.

Instread of rs.example.com performing these flows it is offloaded to a third, more trusted participant (which can also be as.example.com itself) to not disclose information to rs.example.com.

### Flow

![](https://hackmd.io/_uploads/SJ3qBpxHn.png)

The flow is very similar to above with added steps [04] and [09]
- [01] client requests token from as.example.com to access rs.example.com.
- [02] as.example.com returns token.com to access rs.example.com
- [03] client uses received token to access rs.example.com
- [04] client requests a token for rs.example.com from a 3rd component (TBN)
- [05-08] 3rd component needs to obtain a token for a resource outside of example.com domain.
        - [05] the 3rd component performs token exchange with as.example.com. It uses as.example.org as a resource.
        - [06] as.example.com performs checks, reduces scope and claims and returns a new token with as.example.org as an audience.
        - [07] the 3rd component uses this token to perform a bearer-flow/client assertion flow with as.example.org to receive a token for rs.example.org.
        - [08] as.example.org performs required checks, transcribes claims, includes own claims, etc. and returns token.org.
- [09] The 3rd component returns a token for rs.example.org to rs.example.com
- [10] rs.example.com accesses rs.example.org using token.org.
- [11] rs.example.org is able to perform fine grained authorization based on token.org that also contains claims from example.com. If successful, data is returned.
- [12] rs.example.com returns data to the user.