OpenID4VCI Credential Offer Endpoint Discoverability

Issue #1946 resolved
Timo Glastra created an issue

We’ve been working on an implementation of the OpenID4VCI specification and have solely focused on issuing credentials to cloud wallets.

Since draft 10 of the spec, the credential_offer_endpoint has been added as an optional parameter to the Client Metadata, which allows an issuer to directly send a credential offer to the Client/Wallet. For this to work, the Issuer must first get access to the Client Metadata.

There’s several ways for the Issuer to obtain the Client Metadata, I’ll list two approaches here:

  • (a) Using OpenID Dynamic Client Registration
  • (b) Using Inline Registration in the Authorization Request using SIOPv2

The flows are also documented in the diagram below:

Both of these flows are not ideal for the intended use case we have, because it requires the Wallet to initiate the interaction and share its credential_offer_endpoint with the Issuer.

In our use case, companies that own cloud wallets are registering with the Issuer to receive a Verifiable Credential as proof of their registration. During this process, these companies communicate their wallet’s DID to the Issuer via a pre-authorization flow. Once the flow is complete, the Issuer is prepared to send a credential offer to the Client, but has no idea of its endpoint. Since we’re primarily working with DIDs as the identifiers, we’ve been thinking about using a service endpoint in the did document to discover the credential_offer_endpoint. An example of how a did document with such a service would look like is as follows:

{
  "@context": [
    "<https://www.w3.org/ns/did/v1",>
    "<https://w3id.org/security/suites/ed25519-2018/v1">
  ],
  "id": "did:web:cloud-wallet.com",
  "controller": [
    "did:web:cloud-wallet.com"
  ],
  "verificationMethod": [
    {
      "id": "did:web:cloud-wallet.com#key-1",
      "type": "Ed25519VerificationKey2018",
      "controller": "did:web:cloud-wallet.com",
      "publicKeyBase58": "HusXphamXrZHa1oqCdR4HpJ1Zqe9RDueejC4gwTATMTv"
    }
  ],
  "authentication": [
    "did:web:cloud-wallet.com#key-1"
  ],
  "assertionMethod": [
    "did:web:cloud-wallet.com#key-1"
  ],
  "service": [
    {
      "id": "did:web:cloud-wallet.com#service-0",
      "type": "oid4vc-credential-offer",
      "serviceEndpoint": "https://cloud-wallet.com/credential-offer"
    }
  ]
}

In this flow, the Issuer could initiate the interaction, if it has knowledge of the DID it wants to interact with (which is the case in our workflow). I understand OpenID4VCI does also work without DIDs, but maybe it could be added as an optional flow for discovering the credential_offer_endpoint?

One thing to consider is whether it’s useful to have a specific endpoint for the oid4vc-credential-offer or whether there is a more general approach that could be used, that will a) allow to reuse the common approach of using well-known endpoints to discover metadata and b) be extensible for other endpoints in the future.

Having a way for a client to define a well-known Client Metadata endpoint would also work, but a lack of experience with the existing OpenID / OAuth specifications, makes it hard for us to determine the implications of this change. If we were to have a well-known endpoint for Client Metadata, there would still be the issue of how to discover the Client Metadata endpoint.

We’re having a similar discoverability issue with the SIOPv2 flow, where we want to send a SIOPv2 did-auth request to the DID. For that we need to know the authorization endpoint. Currently our approach is to use DID Linked Domains, verify the domain linkage, and then see if any of the domains has a /.well-known/openid-configuration exposed. Having a service type for exposing the openid Issuer would make this process more explicit. An example of such a service could look as follows.

{
  "service": [
    {
      "id": "did:web:cloud-wallet.com#service-1",
      "type": "openid-issuer",
      "serviceEndpoint": "https://cloud-wallet.com"
    }
  ]
 }

This issue is primarily focused on the discoverability of the credential_offer_endpoint. The flow from SIOPv2 is added for context.

Comments (8)

  1. Kristina Yasuda

    Thank you so much for sharing your implementation experience! this is supe valuable! I believe how to discover credential_offer_endpoint is out of scope of VCI rn - are you suggesting to add an implementation considerations section how to discover it?

    another way to discover credential_offer_endpoint that we had in mind was an interoperability profile or a trust framework specifies it so the implementers of that profile/members of the framework know the URL.

  2. Timo Glastra reporter

    are you suggesting to add an implementation considerations section how to discover it?

    That would be a great starting point, and prevent the discovery issue for us partly.

    another way to discover credential_offer_endpoint that we had in mind was an interoperability profile or a trust framework specifies it so the implementers of that profile/members of the framework know the URL.

    That’s an interesting approach. Would there be a specific reason in this case why discoverability of the issuer metadata is part of the spec, but client metadata / the credential offer metadata would be something defined in an interop profile?

  3. Kristina Yasuda

    Would there be a specific reason in this case why discoverability of the issuer metadata is part of the spec, but client metadata / the credential offer metadata would be something defined in an interop profile?

    credential issuer is a server, so a standardized mechanism to discover its metadata can be used (ie what is defined in section 10.1). However, when the Wallet does not have a backend (everything is handled locally in the native app), it is very hard to discover the metadata before the transaction (no equivalent of a /.well-known/openid-credential-issuer). so having metadata supported by the wallet like its endpoints/custom url schemes is one of the pragmatic solutions.

  4. Berend Sliedrecht

    Hi,

    Thank you for the quick responses! I would like to highlight the importance of establishing a method for identifying wallet metadata. While an interoperability profile can handle this for cloud wallets, including this definition in the specification would enhance interoperability beyond specific profiles. It would be beneficial to ensure that the specification remains independent of wallet architecture, and incorporating the discovery of cloud wallet metadata would align with this goal.
    After conducting further research on discovery mechanisms, we have concluded that defining a .well-known/openid-credential-wallet is the most suitable option. This configuration would include an optional field called credential_offer_endpoint and can be hosted by the cloud wallet. It’s worth noting that native wallets cannot host such an endpoint, but they can still utilize deep links and QR codes.
    Interested to hear your thoughts!

  5. Log in to comment