openid / OpenID4VCI

65 stars 18 forks source link

OID credential issuer identifier #396

Open fabrii opened 1 week ago

fabrii commented 1 week ago

Hi!

We can see in the specification the following text:

12.4. Relationship between the Credential Issuer Identifier in the Metadata and the Issuer Identifier in the Issued Credential The Credential Issuer Identifier is always a URL using the https scheme, as defined in Section 10.2.1. Depending on the Credential Format, the Issuer identifier in the issued Credential may not be a URL using the https scheme. Some other forms that it can take are a DID included in the issuer property in a [VC_DATA] format, or the Subject value of the document signer certificate included in the x5chain element in an [ISO.18013-5] format.

We were thinking about using OIDs, managed by ISO & ITU-T (ISO/IEC 8824-1 Information Technology - Abstract Syntax Notation One (ASN.1))

For example:

"issuer": "urn:oid:2.16.858.0.0.0.3.0",

Is this aligned with the spec?

Thank you

jogu commented 1 week ago

Could you share a bit more about the design of your system, e.g. what credential format this is for etc please?

fabrii commented 1 week ago

This is for a ldp_vc credential.

Example

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://example.com/api/contexts/transport/driverlicense-v1"
    ],
    "type": [
        "VerifiableCredential",
        "DriverLicenseCredential"
    ],
    "id": "urn:uuid:f3d85c09-965a-4dea-9681-3f4120df6bdb",
    "issuer": "urn:oid:2.16.858.0.0.0.3.0",
    "issuanceDate": "2022-12-01T18:08:24Z",
    "credentialSubject": {
        "id": "did:key:z2DfPjA1yT6cWbLjxavov7PpqNipHUNW8QMuj6SQPPm11zP",
        "name": "X"
    },
    "credentialStatus": { type: 'StatusList2021Entry', .... },
    "proof": {
        "type": "RsaSignature2018",
        "created": "2022-12-01T18:08:24Z",
        "proofPurpose": "assertionMethod",
        "verificationMethod": "urn:oid:2.16.858.0.0.0.3.0#1",
        "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJSUzI1NiJ9..H5da7Jq118Wo31QrJsUY3Z1C7--kyUoXHoo5N2WDWfz9ma5TdilcE4Os5CGQEuOAWTF3wXIYj6qne4nZ1nGGj2Nz7KjH5xsetzAIWexTzq8hzz8ACanmbb3SIE7O9zJlA79F5TkYDFo72PXJpu0NLmksY-LUh9fLWxQcNYQvwWVUYX2h_gk8S_UnvvFDRbkAVJZT-QvpQ4kvWmv6SPWMZyw1ghVrdJLSe_k1VCmdDl4RQ66zjAmxzOkjgqCTsQEm-qpBD3eDLx_VioFOK9Qz9AReoHctnfvx-bj3Y6bDq5U7gmSIy_OfWuw48Dejz7AvbgQq2uHm9DTQN71WFxleAA"
    }
}

Every issuer will have a unique oid identifier, valid and unique in the entire world. We also have a Verifiable Data Registry with issuers public keys, and a custom document loader that can handle urn:oid:2.16.858.0.0.0.3.0#1 keys. Personally, I’m not a fan of using HTTPS URLs as issuer identifiers, since the issuer’s domain could change over time. An assigned OID, however, remains permanent.

jogu commented 2 days ago

Thanks for adding the extra detail, that helps!

I get it, it's an interesting idea, and in my personal opinion I think it's technically allow in the VCI specification. However I'd very strongly discourage anyone from actually implementing in that way though because it will hugely harm interoperability.

I appreciate the concerns about https relying on domain names that can change over time, but in practice it's very rare that anyone ever 100% stops using a domain (registrations tend to stay in place for a very long time, just with permanent redirects to new sites), and the issuer urls aren't intended to be visible to the end users so it really doesn't matter if they (say) have an old brand name in them after a re-brand/rename happens. If you're really sure it's a problem there are ways to mitigate it whilst still using https, for example having a central directory type service that hosts the well-known files for all issuers in an ecosystem, however I'm not sure that is necessary.

If we want these specifications and VCs in general to be successful we need to do our best to all implement these standards in common ways, and this will also reduce the burden on implementers.

fabrii commented 2 days ago

Could you please explain me in more detail about the interoperability concerns?

From our architectural perspective, it seems that we will always require a Central Registry to ensure the authenticity of credential issuers and provide a reliable source for their public keys. From a verifier’s point of view, one approach to ensure interoperability could be to implement conditional logic based on the OID. If the issuer's OID starts with a specific prefix (e.g., "2.16.858"), the verifier can determine which Registry URL to query for the corresponding public keys.

jogu commented 2 days ago

Hi Fabrii,

Could you please explain me in more detail about the interoperability concerns?

Sure! Basically it's that no one else is doing this, so it wouldn't be interoperable with other ecosystems and "off-the-shelf" verifiers, wallets & issuers likely wouldn't be usable.

From our architectural perspective, it seems that we will always require a Central Registry to ensure the authenticity of credential issuers and provide a reliable source for their public keys.

This doesn't need OIDs though. You can do a central registry just by centrally hosting the .well-known endpoint, or by using OpenID Federation, or by having a list of trusted issuer urls somewhere.

From a verifier’s point of view, one approach to ensure interoperability could be to implement conditional logic based on the OID. If the issuer's OID starts with a specific prefix (e.g., "2.16.858"), the verifier can determine which Registry URL to query for the corresponding public keys.

Unfortunately requiring special code to cope with one implementation or ecosystem isn't going to help with general interoperability.

As another example, it's probably likely the OpenID Foundation conformance tests for the VCI & VP protocols would fail implementations where the issuer is an OID - because the purpose of those tests is generally to ensure implementations both conform to what is defined in the standard and are interoperable.

fabrii commented 1 day ago

Would this be a correct approach?

1) Each issuer exposes ".well-known/openid-credential-issuer" metadata endpoint, as mentioned in the spec. The issuer identifier in the CV must be equal with the domain of the well-known endpoint. 2) In credential registry, publish a list of trusted issuers ids (domains). Each verifier must know beforehand the registry url, so they can obtain this list. This list must be validated also in the holder Wallet, to not accept credentials from unverified issuers. Is there any spec about the format of this list?

I am having a hard time understanding where the issuer's public keys should be published and the correct value for the verificationMethod attribute, if we are not using did:key. For example, if my issuer id is "https://myissuerdomain.com", my verificationMethod would be "https://myissuerdomain.com#1"? How can a documentLoader load the associated "DID Document" used to validate this signature, in a standarized way? As of today, we had this information in a jwks endpoint in the registry, but we have "proprietary" code to convert this JWK to the DID Document that is used to validate the signature.

Are we forced to use did:key and DID Configuration to support interoperability?

Thank you very much.