Credential Issuance: OAuth 2.0 Token Exchange compatibility

Issue #1374 closed
Thomas Bellebaum created an issue

Moved to here from Github.

The draft specifies a method for effectively exchanging an access token (and optionally some verifiable presentations) for a verifiable credential at a new credential endpoint (Resulting in Step 7 in the diagram).

This functionality is somewhat related to OAuth 2.0 Token Exchange, where security tokens (of any type) are exchanged for new security tokens (of any type).

Some important differences:

  • Different request parameters: The request parameters for the Credential- and Token-exchange mechanisms are quite different, though there is a natural mapping for the most part.

    No distinction between format and type: We would either need to define additional parameters, or define a general URI scheme, like appending the format to the type (see example below)

Is it possible to build the Issuance procedure on top of Token Exchange?
If it was, it would probably be much simpler to generalize the mechanism from OpenID to general OAuth.

Here is what I think such a request could look like (encoding omitted and additional line breaks included for readability):

POST /token HTTP/1.1
Host: server.example.org
Content-Type: application/x-www-form-urlencoded
Authorization: BEARER czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&requested_token_type=urn:<something>:<something>:health_card:ldp_vc
&subject_token_type=urn:<something>:<something>:proof-of-posession
&subject_token={...}

The subject security token would be something along the lines of the proof parameter in the current draft, including the verificationMethod (representing did or sub_jwk):

 {
    "type": "RsaSignature2018",
    "created": "2018-09-14T21:19:10Z",
    "proofPurpose": "authentication",
    "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1",
    "challenge": "2H4dB9xl-FZQL-pixV-WJk0eOt4CXQ-1NXKW",
    "domain": "https://issuer.example.com"
    "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..l9d0YHjcFAH2H4dB9xlWFZQLUpixVCWJk0eOt4CXQe1NXKWZwmhmn9OQp6YxX0a2LffegtYESTCJEoGVXLqWAA"
}

In the response, the credential resp. acceptance token is conveyed in the access_token parameter. As Token Exchange explains, this is for backwards compatibility. The type is indicated by the issued_token_type parameter. The c_nonce and c_nonce_expires_in parameters would have to be added to this endpoint, but the current draft does this anyways at the token endpoint.

Comments (13)

  1. Thomas Bellebaum reporter

    Note: The type could also be communicated via the resource or audience request parameters, though that would be a stretch to their original meaning.

  2. Torsten Lodderstedt

    I honestly think mapping credential issuance to token exchange is a big stretch. Sure, in the end most things we do in the protocol is somehow a token exchange (including code for access token and user info). I would compare the credential endpoint to the userinfo endpoint. Would you try to build userinfo based on token exchange?

  3. Jeremie Miller Account Deactivated

    Thanks Thomas for pointing out the overlap, I find it a very interesting exercise to think about credential issuance as a form of token exchange. There certainly should be some relevant lessons learned that apply here.

    Torsten, I don’t think comparing it to the userinfo endpoint is fair, as a credential is a standalone cryptographic envelope that is being generated in response to the information associated with another given cryptographic envelope. It is far more like a token exchange than a simple REST API response.

  4. Torsten Lodderstedt

    The userinfo response is an (optionally) signed assertion of end-user claims, which are processed by the RP. A credential has the same properties + cryptographic binding.

    An access token in contrast is opaque to the client and allows access to an API. Token Exchange allows to exchange an access token for another access token. A typically use case is an API receiving a request with a certain access token and exchanging that for another access token used to authorize a subsequent call to a down stream API.

    The credential endpoint issues a credential based on the authorization conveyed in the access token.

    That’s a different use case.

  5. Thomas Bellebaum reporter

    Interesting viewpoint on userinfo. I always thought of them kind of like a sort of token introspection with a focus on subject claims. That analogy might even go further once token introspection responses can be signed as JWSs.

    But the use cases for Token exchange reach further than that.
    For example, Section 3 of Token Exchange allows to request not only access tokens, but also ID tokens and other types of Security Tokens.
    A more general notion of “access token for e.g. downstream API calls” (=> Security Tokens) which includes these types of tokens might very naturally include Verifiable Credentials as well.

    By analogy:
    An ID token includes claims about the subject’s authentication. A RP might require it for it’s access control decision.
    A COVID Vaccination VC would include claims about a subject’s vaccination status. A restaurant owner might require it for their (law-compliant) decision to let the subject in.

    @Torsten Lodderstedt Where do you draw the line between a Security Token (including ID tokens) and a Verifiable Credential?

  6. Torsten Lodderstedt

    Security Token is a term introduced by the token exchange spec (as far as I remember), I think in an attempt to somehow unify all kinds of tokens. I haven’t found it useful in my work so far.

    In my mental model, there are two very distinct concepts from the perspective of a client/RP:

    • Access Token: issued by an AS, represents the permission to access an API (RS) on behalf of (typically) a user. The content (and even the format) is opaque to the client. Format, structure and content is subject to a “contract” between AS and RS.
    • Identity Assertion: a set of claims issued by an IDP. The client acting as a RP interprets this claims (e.g. to identify a user or to meet access control decisions). ID tokens and verifiable credentials fall into this category.

  7. Thomas Bellebaum reporter

    I am unsure about the history of the wording, but OIDC Core uses it as well:

    The ID Token is a security token

    I agree with your distinction, although the lines become a bit blurry sometimes in their usage. Take a drivers license as an example. Although it states claims about the ability to drive and would thus likely fall into the assertion category, it represents something like a “contract between a state and the police”, allowing me to drive a car. One does not even have to be able to read ones own drivers license to use it.
    I assume this notion of “enabling tokens” to be the intended notion of security tokens, which is why it does indeed cover issuing tokens you identify with identity assertions (like urn:ietf:params:oauth:token-type:id_token) not by accident, but by design.

  8. Kristina Yasuda

    I have brainstormed on this (“Identity Credential” Issuance using Oauth2.0 Token Exchange specification - HackMD) and believe that using Token Exchange is a very different approach that using OAuth2.0 for credential issuance. The token exchange approach is stateless and the input to the Token Exchange endpoint would have to pretty much be a “verifiable credential, just not in the w3c spec compliant format“.

    Hence I suggest we resolve this issue. unless there is an absolute benefit to add few parameters to the token exchange specification to make it usable for credential issuance too?

  9. Giuseppe De Marco

    Differently, I think that would be fine obtaining an access token submitting a VP to a token exchange endpoint, the VP may be presented as urn:ietf:params:oauth:token-type:jwt with appropriate encapsulation, eg: json-ld in JWT.

    That would be very interesting to me, because it opens a wide possibility to obtain a mechanism of interoperability between OIDC4UC and the classical OAuth2 infrastructures. In certain contexts it becomes possible to obtain an access token (Bearer or DPoP) through the submission of a VP. It’s not little at all.

    Obtaining instead a VC using a Token Exchange sounds strange (even though I’m used to strange things). I’d use an access_token, release by an IDP, to a credential issuance endpoint of the IDP

  10. Kristina Yasuda

    Differently, I think that would be fine obtaining an access token submitting a VP to a token exchange endpoint, the VP may be presented as urn:ietf:params:oauth:token-type:jwt with appropriate encapsulation, eg: json-ld in JWT.

    yes, that is possible. all I am saying is that will be a very different approach from OID4VP and should be a separate specification.

    Pending close as I do not believe these is a consensus to pursue this path in OID4VP.

  11. Kristina Yasuda

    Atlantic Connect call, agreed to close on the grounds that credential issuance using OAuth Token exchange should be a different spec.

  12. Log in to comment