-
Notifications
You must be signed in to change notification settings - Fork 6
V5 draft #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V5 draft #79
Changes from all commits
4d55a8d
06594fd
84a26e1
4516ec6
bbdc15d
b9574d8
02bb442
f30adf4
823e216
6575c28
0306d60
98f860a
e9ab8e7
81d11ed
1c32830
6aeadc2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
This file was deleted.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,267 @@ | ||||||
| ## Appendix B: OpenID Federation Digital Credentials Profile | ||||||
|
|
||||||
| ### Introduction | ||||||
|
|
||||||
| This specification profiles OpenID Federation [[ref: OpenID Federation]] for use with digital credentials, specifically focusing on credential issuance via OpenID for Verifiable Credential Issuance [[ref: OID4VCI]] and credential presentation via OpenID for Verifiable Presentations [[ref: OID4VP]]. | ||||||
|
|
||||||
| The profile simplifies federation usage by limiting scope to trust chain resolution and metadata discovery, while omitting more complex features such as federation policies and trust marks. | ||||||
|
|
||||||
| #### Scope | ||||||
|
|
||||||
| This profile applies to: | ||||||
|
|
||||||
| - Credential issuers publishing OID4VCI metadata | ||||||
| - Credential verifiers publishing verifier metadata | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For consistency
Suggested change
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The inconsistency is intentional. See Terminology: "Note that this specification does not distinguish the role and the technical service of the verifier the same way it does for Issuer and Credential Issuer."
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what that has to do with naming it OID4VP vs verifier metadata?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry. I misread the suggestion. The OID4VP uses the term "Verifier metadata" (in chapter 5.9). Should we use those terms?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest to combine OID4VP verifier metadata |
||||||
| - Wallets resolving trust chains to establish trust in issuers and verifiers | ||||||
|
|
||||||
| This profile does not apply to and does not require conforming implementations to support: | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this include:
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a good question. Do we want to use OpenID Federation for that? Personally, I would leave this out to keep the first version as simple as possible. To me, trust towards the wallet or the wallet provider seems a high-assurance requirement. I believe that many use cases can live with non-trusted wallets. If others feel like this is an important feature, please suggest the wording that should be included.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, that's why I think it should be added to the "This profile does not apply to" section, so it's expliclty out of scope for now |
||||||
|
|
||||||
| - Chapter 6 (Federation Policy) of OpenID Federation | ||||||
| - Chapter 7 (Trust Marks) of OpenID Federation | ||||||
| - Chapter 12 (OpenID Connect Client Registration) of OpenID Federation | ||||||
|
|
||||||
| ### Terminology | ||||||
|
|
||||||
| This specification uses the terms defined in OpenID Federation [[ref: OpenID Federation]], OpenID for Verifiable Credential Issuance [[ref: OID4VCI]], OpenID for Verifiable Presentations [[ref: OID4VP]], and SD-JWT VC [[ref: SD-JWT VC]]. | ||||||
|
|
||||||
| **Entity Identifier**: As defined in OpenID Federation, a URL that uniquely identifies a federation entity. | ||||||
|
|
||||||
| **Entity Configuration**: As defined in OpenID Federation, a signed JWT published at the Entity Identifier's `/.well-known/openid-federation` endpoint containing metadata and authority hints. | ||||||
|
|
||||||
| **Trust Chain**: As defined in OpenID Federation, a sequence of Entity Statements from a Leaf Entity through intermediate entities to a Trust Anchor. | ||||||
|
|
||||||
| **Issuer**: The role of the entity issuing credentials as defined in [[ref: W3C VCDM]] | ||||||
|
|
||||||
| **Credential Issuer**: The technical service used to issue credentials as defined in [[ref: OID4VCI]] | ||||||
|
|
||||||
| **Verifier**: The entity that requests, receives, and validates Presentations as defined in [[ref: OID4VCI]]. Note that this specification does not distinguish the role and the technical service of the verifier the same way it does for Issuer and Credential Issuer. For the purposes of this specification Verifier may refer to either the role or the technical service. (Thus, the reference to the definition in [[ref: OID4VCI]] and not the one in [[ref: OID4VP]].) | ||||||
|
|
||||||
| ### Credential Issuance | ||||||
|
|
||||||
| #### Entity Identifier | ||||||
|
|
||||||
| **Requirement: The Credential Issuer MUST use the value of the `credential_issuer` in its OID4VCI issuer metadata as its Entity Identifier.** | ||||||
|
|
||||||
| The Credential Issuer's Entity Configuration can be found by appending the string `/.well-known/openid-federation` to the Entity Identifier. | ||||||
|
|
||||||
| #### Issuer Metadata Publication | ||||||
|
|
||||||
| **Requirement: The Credential Issuer MUST place the OpenID4VCI issuer metadata into the Entity Configuration, in the `openid_credential_issuer` property.** | ||||||
|
|
||||||
| **Requirement: The Credential Issuer MUST place the public key material of the keys it uses to sign Digital Credentials in the `jwt_vc_issuer` property. The `jwt_vc_issuer` property MUST include the `jwks` property that contains the Issuer's JSON Web Key Set as defined in RFC7517.** (The `jwt_vc_issuer` property MUST NOT include the `jwks_uri` property.) | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason why we are exlcuding jwks uri?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think also maybe we shouldn't call it
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nklomp the idea is that if you want to include the keys in the Entity Configuration to be a part of the signed JWT, you include the keys, not a reference to a resource that can change any time.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @TimoGlastra, my idea was to mirror
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes but this is focussed on a single credential format. In our case we are potentially supporting multiple credential formats, not neccesarily JWT-bound. We can build on the jwt-vc-isuser, but just call it Otherwise if we want to support W3C Data Integrity we have to come up with a new approach, just because it's named JWT VC Issuer. |
||||||
|
|
||||||
| **Requirement: If the `openid_credential_issuer` property is found in the Entity Configuration, the Wallet MUST use only this medatada and ignore the regular issuer metadata published in the well-known location defined in OID4VCI.** | ||||||
|
|
||||||
| The Credential Issuer MAY place additional metadata into the `federation_entity` Entity Type Identifier. | ||||||
|
|
||||||
| **Requirement: The metadata in the `openid_credential_issuer` property MUST override the metadata in the `federation_entity` property.** For example, if both `openid_credential_issuer.display.name` and `federation_entity.organization_name` exist, the Wallet MUST show the value of `openid_credential_issuer.display.name` as the name of the Issuer. | ||||||
|
|
||||||
| #### Example: Credential Issuer Entity Configuration | ||||||
|
|
||||||
| The following JSON document is a non-normative example of the decoded payload of a Credential Issuer's Entity Configuration. | ||||||
|
|
||||||
| ```json | ||||||
| { | ||||||
| "iss": "https://credential-issuer.example", | ||||||
| "sub": "https://credential-issuer.example", | ||||||
| "iat": 1616239022, | ||||||
| "exp": 1616239322, | ||||||
| "metadata": { | ||||||
| "federation_entity": { | ||||||
| "organization_name": "Example Credential Issuer", | ||||||
| "contacts": ["[email protected]"] | ||||||
| }, | ||||||
| "openid_credential_issuer": { | ||||||
| "issuer": "https://credential-issuer.example", | ||||||
| "display": [ | ||||||
| { | ||||||
| "name": "Example Issuer", | ||||||
| "locale": "en-US", | ||||||
| "logo": { | ||||||
| "uri": "https://credential-issuer.example/logo.png", | ||||||
| "alt_text": "Example Logo" | ||||||
| } | ||||||
| } | ||||||
| ], | ||||||
| "credential_issuer": "https://credential-issuer.example", | ||||||
| "authorization_endpoint": "https://credential-issuer.example/authorize", | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be reasonable to also put the authorization server's metadata into the EC? I think often it is hosted by the same entity as the credential issuer (as is hinted towards it here, by using the same domain), which would reduce the number of requests that need to be done.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good suggestion, IMHO. Perhaps we should first agree how we want to present the JWKS (#79 (comment)). |
||||||
| "authorization_servers": ["https://credential-issuer.example/authorize"], | ||||||
| "credential_endpoint": "https://credential-issuer.example/credential", | ||||||
| "credential_configurations_supported": { | ||||||
| "sd_jwt_vc_example": "..." | ||||||
| } | ||||||
| }, | ||||||
| "jwt_vc_issuer": { | ||||||
| "jwks": [ | ||||||
| { | ||||||
| "kty": "EC", | ||||||
| "kid": "MJ2BW-rNshp9sjh3SvwnBIkEsYsU92xVtC3-Fv_lcKc", | ||||||
| "alg": "ES256", | ||||||
| "crv": "P-256", | ||||||
| "x": "JTEE5QghmkA_-7_pZoKIluRzGNvQGtzmpNvb_nAswhE", | ||||||
| "y": "A_iBfIseHsdfE7CmI3lIYtKMdfyXXOIpPX_o6O0h0wY", | ||||||
| "use": "sig" | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| }, | ||||||
| "jwks": [ | ||||||
| { | ||||||
| "kty": "EC", | ||||||
| "kid": "MJ2BW-rNshp9sjh3SvwnBIkEsYsU92xVtC3-Fv_lcKc", | ||||||
| "alg": "ES256", | ||||||
| "crv": "P-256", | ||||||
| "x": "JTEE5QghmkA_-7_pZoKIluRzGNvQGtzmpNvb_nAswhE", | ||||||
| "y": "A_iBfIseHsdfE7CmI3lIYtKMdfyXXOIpPX_o6O0h0wY", | ||||||
| "use": "sig" | ||||||
| } | ||||||
| ], | ||||||
| "authority_hints": [ | ||||||
| "https://trustregistry.example" | ||||||
| ] | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| The JWKS in the `jwt_vc_issuer` property contains information about the keys used to sign Digital Credentials. The JWKS on the root level of the Entity Configuration contains information about the key used to sign the Entity Configuration. In the example, the same key is used, but the keys MAY be different. | ||||||
|
|
||||||
| #### SD-JWT VC Credentials | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't specify where to resolve the signing keys. I think we need to define a custom entity type with jwks field
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use jwt_vc_issuer (referring to 5.1 in https://datatracker.ietf.org/doc/draft-ietf-oauth-sd-jwt-vc/?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why aren't we using cnf with kid for SD-JWT VC and kid for VCDM2 SD-JWT? We already publish the JWKS, so then it is just a matter of mapping the kid to the JWK and matching that against the JWKS
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think we can reuse the already published JWKS, as you shouldn't reuse the Federation keys for non-federation operations. So we do need a new entity in the federation.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not it is a set
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not it is a set
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because:
https://openid.net/specs/openid-federation-1_0.html#section-3.1-1.10.2 |
||||||
|
|
||||||
| **Requirement: When the Issuer issues credentials in the [[ref: SD-JWT VC]] format, the Issuer MUST place its Entity Identifier in the `fed` claim of the credential.** | ||||||
|
|
||||||
| ##### Example: SD-JWT VC with Federation Claim | ||||||
|
|
||||||
| The following non-normative example shows a decoded payload of an [[ref: SD-JWT VC]] credential with the `fed` claim: | ||||||
|
|
||||||
| ```json | ||||||
| { | ||||||
| "iss": "https://credential-issuer.example", | ||||||
| "fed": "https://credential-issuer.example", | ||||||
| "iat": 1683000000, | ||||||
| "exp": 1883000000, | ||||||
| "vct": "https://credentials.example.com/identity_credential", | ||||||
| "is_over_65": true, | ||||||
| "address": { | ||||||
| "street_address": "123 Main St", | ||||||
| "locality": "Anytown", | ||||||
| "region": "Anystate", | ||||||
| "country": "US" | ||||||
| } | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| #### W3C VCDM Credentials | ||||||
|
|
||||||
| **Requirement: When the Issuer issues credentials in the [[ref: W3C VCDM]] format, the Issuer MUST place a `termsOfUse` property into the credential. The `type` of this `termsOfUse` property MUST be the string `OpenIDFederation` and the `policyId` MUST be the Issuer's Entity Identifier.** | ||||||
|
|
||||||
| ##### Example: W3C VCDM Credential with termsOfUse | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't define how to resolve the signing key. Can be the same as SD-JWT VC (since both use jwt signing). But we should mention that it specifically applies to jwt signed w3c creds
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why aren't we using cnf with kid for SD-JWT VC and kid for VCDM2 SD-JWT? We already publish the JWKS, so then it is just a matter of mapping the kid to the JWK and matching that against the JWKS |
||||||
|
|
||||||
| The following non-normative example illustrates the use of the `termsOfUse` property: | ||||||
|
|
||||||
| ```json | ||||||
| { | ||||||
| "@context": [ | ||||||
| "https://www.w3.org/ns/credentials/v2" | ||||||
| ], | ||||||
| "id": "urn:uuid:c65d364e-2560-4e08-be03-9c3d944d609d", | ||||||
| "type": [ | ||||||
| "VerifiableCredential" | ||||||
| ], | ||||||
| "issuer": "did:web:credential-issuer.example", | ||||||
| "validFrom": "2025-12-01T00:00:00Z", | ||||||
| "validUntil": "2028-12-31T23:59:59Z", | ||||||
| "credentialSubject": { | ||||||
| }, | ||||||
| "termsOfUse": { | ||||||
| "type": "OpenIDFederation", | ||||||
| "trustFramework": "Example Federation", | ||||||
| "policyId": "https://credential-issuer.example" | ||||||
| } | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| #### Note on Credential Issuer vs. Issuer | ||||||
|
|
||||||
| The Issuer defined in the digital credential (the value of the `iss` claim in SD-JWT VC credentials or the value of the `id` of the `issuer` property in W3C VCDM credentials) is not necessarily the same entity as the Credential Issuer defined in the property `credential_issuer` in the OID4VCI metadata. | ||||||
|
|
||||||
| For example, the OpenID Federation Entity Identifier of the Issuer of the credential could be `https://university-of-utopia.example.edu` and the OpenID Federation Entity Identifier of the Credential Issuer could be `https://credentials.ministryofeducation.example.edu`. | ||||||
|
|
||||||
| If the Issuer chooses to make this kind of distinction between the entity issuing the credential and the technical service used for issuance, it is RECOMMENDED that the Entity Configuration of the technical service has an `authority_hints` value pointing to the Issuer's Entity Identifier and the Issuer publishes a Subordinate Statement about the technical service. | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is too open ended. If we want to support it we should make the authoritiy hints and subordinate statement mandatory
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Do you mean that the JWKS is published in the Entity Configuration, or that it is published as SD-JWT metadata? How does the verifier of a VCDM2 SD-JWT find the Entity Configuration of the Issuer?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't follow. It should not be mandatory to make the distinction between the Issuer ( Support for authority hints and subordinate statements in general is, of course, mandatory, since you can't implement OpenID Federation without them. |
||||||
|
|
||||||
| ### Credential Presentation and Verification | ||||||
|
|
||||||
| #### Client Identifier Scheme | ||||||
|
|
||||||
| **Requirement: The Verifier MUST use the `openid_federation:` prefix as defined in [[ref: OID4VP]] Section 5.9.3.** | ||||||
|
|
||||||
| #### Verifier Metadata Publication | ||||||
|
|
||||||
| **Requirement: The Verifier MUST place verifier metadata into the Entity Configuration, in the `openid_credential_verifier` property.** | ||||||
|
|
||||||
| ### Trust Establishment | ||||||
|
|
||||||
| **Requirement: To establish trust with the Issuer (ensure that the Issuer can be trusted), the Verifier MUST resolve the Trust Chain from the Issuer's Entity Configuration until it finds a Federation Entity it trusts.** | ||||||
| **Requirement: The Verifier MUST verify that the credential is signed with a key included in the `jwt_vc_issuer` metadata in the Entity Configuration of the Issuer. The `jwks` property in the `jwt_vc_issuer` must contain a key with the `kid` value equal to the `kid` header in the [[ref: SD-JWT VC]] credential.** | ||||||
|
|
||||||
| #### Example: Verifier Entity Configuration | ||||||
|
|
||||||
| The following JSON document is a non-normative example of the decoded payload of a Verifier's Entity Configuration. | ||||||
|
|
||||||
| ```json | ||||||
| { | ||||||
| "iss": "https://credential-verifier.example", | ||||||
| "sub": "https://credential-verifier.example", | ||||||
| "iat": 1616239023, | ||||||
| "exp": 1616239323, | ||||||
| "metadata": { | ||||||
| "federation_entity": { | ||||||
| "organization_name": "Example Credential Verifier", | ||||||
| "contacts": ["[email protected]"] | ||||||
| }, | ||||||
| "openid_credential_verifier": { | ||||||
| "jwks": { | ||||||
| "keys": [ | ||||||
| { | ||||||
| "kty": "EC", | ||||||
| "crv": "P-256", | ||||||
| "x": "f83OJ3D2xF4Z1s3QpLQe4qVb8K7q6y1v3z4Yb6k9J0", | ||||||
| "y": "x_FEzRu9q3u4bWz5n9X2L4q1U8T7c6v5s2d1a0b3C4", | ||||||
| "alg": "ES256", | ||||||
| "use": "enc", | ||||||
| "kid": "ec-key-1" | ||||||
| } | ||||||
| ] | ||||||
| }, | ||||||
| "encrypted_response_enc_values_supported": [ | ||||||
| "A128GCM", | ||||||
| "A192GCM", | ||||||
| "A256GCM" | ||||||
| ], | ||||||
| "vp_formats_supported": { | ||||||
| "dc+sd-jwt": { | ||||||
| "sd-jwt_alg_values": ["ES256"], | ||||||
| "kb-jwt_alg_values": ["ES256"] | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| }, | ||||||
| "jwks": [ | ||||||
| { | ||||||
| "kty": "EC", | ||||||
| "kid": "y4nC8uTvcM5uJxOIvUqFjXb2EA6xPGdnt8zvjW94m6U", | ||||||
| "alg": "ES256", | ||||||
| "crv": "P-256", | ||||||
| "x": "K6dA9ayt4P8xBN6SFiCZYOI2qeaFda7VV5wnmHWcl7w", | ||||||
| "y": "CdE30dUX0geK4NL8IMC9u-rRMOLC9WaScJIGK5rxtKI" | ||||||
| } | ||||||
| ], | ||||||
| "authority_hints": [ | ||||||
| "https://trustregistry.example" | ||||||
| ] | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ### Subordinate Statements | ||||||
|
|
||||||
| Intermediaries and Trust Anchors MAY authorize their subordinates to issue or request certain credential types by placing metadata values like `openid_credential_issuer.credential_configurations_supported` or `openid_credential_verifier.dcql_query` in the Subordinate Statements. | ||||||
|
|
||||||
| The meaning of such statements SHOULD be specified in ecosystem rulebooks and are out of the scope of this specification. | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this include:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps. Maybe we also need a requirement along the lines of "The conformant Verifier Agents MUST support resolving the trust chains from the Entity Configuration of the Issuer of a Digital Credential".