Verifiable Credentials

Verifiable Credentials are a W3C standard for issuing cryptographically signed, temper-evident claims and data. They are used in the Gaia-X specification as the basis for Self-Descriptions of both Participants and Service Offerings, and are furthermore used in GAIA-X-Med as the basis for Contracts.

This page aims to give first a very brief outline of credential structure (refer to the W3C specification for more details), followed by a description of how credentials are issued and verified inside the GAIA-X-Med project in particular.

Introduction

Verifiable Credentials

A Verifiable Credential is a digital means that allows an issuer to make a statement about a subject (which can be the issuer themselves) that can be cryptographically confirmed by a verifier to be authentic in both origin and content.

This makes Verifiable Credentials a useful basis for allowing trustworthy statements between Gaia-X participants, such as providing personal information or service descriptions.

A Credential consists of its credential subject and, if it is signed, a signature. Furthermore there is some metadata, including the VC context.

Credential subject & Claims

The credential subject contains one or more claims about the subject of the Verifiable Credential. This is the message the Credential is supposed to convey to the verifier.

Signature

Adding a signature (sometimes also called proof block) to a Credential makes it Verifiable. It consists of some sort of cryptographic proof that allows the Verifier to attest that the Credential was actually issued by the issuer, and furthermore that its contents were not tampered with. This is usually accomplished by including a digital cryptographic signature.

Context

The context provides the vocabulary of a VC, and is therefore similar to a schema. It defines VC types and their valid attributes.

The context is of particular importance when canonizing a VC; i.e., transforming the somewhat-freeform JSON of a VC into a normalized format. It ensures that the canonization process produces the correct and reproducible result.

In VCs used in GAIA-X-Med, the context documents are provided by the Registry Service.

Verifiable Presentations

Instead of handing out one’s Verifiable Credentials by themselves, they are usually presented in form of a Verifiable Presentation. This also allows for bundling multiple Verifiable Credentials that thematically belong together.

A Verifiable Presentation can be signed and therefore verified in the same way that a Verifiable Credential can, namely by including a digital signature (or proof block). In GAIA-X-Med, this is especially relevant for Contract Negotiation, where this signature guarantees immutability of the Contract claims.

Decentralized Identifiers (DIDs)

Decentralized Identifiers (or DIDs) do not strictly belong to the Verifiable Credential specification, but are often used in tandem. They consist of a DID document that contains some information as well as a DID URL pointing to that document.

In GAIA-X-Med, every credential issuer is expected to possess and make publicly accessible a DID document containing the public key (in JWK format) that corresponds to the private key they use to sign their credentials with. The issuer’s DID URL is contained within a credential’s proof block, allowing verifiers to easily look up the public key needed to verify a credential’s signature.

Role of credentials inside GAIA-X-Med

The usage of Verifiable Credentials in GAIA-X-Med aligns with the Gaia-X Trust Framework 22.04 in that they are used as the basis for Self-Descriptions.

Additionally, their usage in Participant authentication was inspired by the Eclipse Dataspace Components.

Issuance of a Verifiable Credential

The Verifiable Credential is created by compiling the claims and necessary metadata according to the type of credential. Furthermore, the correct Context must be added to the VC.

Creating the signature / proof block

The proof block is created using the following values:

Key

Value

type

"JsonWebSignature2020"

created

Current timestamp, e.g. "2023-07-26T11:40:27.040Z"

proofPurpose

"assertionMethod"

verificationMethod

DID URL of the issuer, e.g. "did:web:example.com:johndoe"

jws

Digital signature (see below)

Creating the digital signature (JWS)

The signature is a standard JSON Web Signature which consists of header, (detached) payload and signature parts.

The header part should contain, base64-encoded:

{
  "alg": "RS256",
  "b64": false,
  "crit": [
    "b64"
  ]
}

The JWS payload is a hash generated in the following way:

  1. The entire credential JSON (sans Proof block, if present) is canonized using URDNA2015. There are libraries available for this (e.g. jsonld). Note: This step requires fetching of the JSON-LD @contexts specified in the credential; if the contexts aren’t cached beforehand, this requires internet access.

  2. The resulting canonized string is hashed using SHA256.

Note: Even though the payload of a JWS is usually base64-encoded, this is not the case here; the SHA256 string is used verbatim. This is technically non-standard but done in accordance with how the Compliance Service 22.04 works. When choosing a JWS implementation, make sure it can handle this edge case.

After generating header and payload, the signature is created and base64-encoded as usual.

Since the JWS is using a detached payload, it is removed from the JWS string.

Example Verifiable Credential (Self-Description)

{
    "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://registry.gaia-med.org/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#"
    ],
    "type": [
    "VerifiableCredential"
    ],
    "id": "https://gaia-x.eu/.well-known/participant.json",
    "issuer": "did:web:identity.gaia-med.org:demo:alice",
    "issuanceDate": "2023-06-07T12:00:00.000Z",
    "credentialSubject": {
    "id": "https://gaia-x.eu/.well-known/participant.json",
    "type": "gx:LegalParticipant",
    "gx:legalName": "Alice",
    "gx:emailAddress": "alice@gaia-med.org",
    "gx:phoneNumber": "0123-4567890",
    "gx:legalRegistrationNumber": {
        "gx:vatID": "DE123"
    },
    "gx:headquarterAddress": {
        "gx:countrySubdivisionCode": "DE-SH"
    },
    "gx:legalAddress": {
        "gx:countrySubdivisionCode": "DE-SH"
    },
    "gx-terms-and-conditions:gaiaxTermsAndConditions": "70c1d713215f95191a11d38fe2341faed27d19e083917bc8732ca4fea4976700"
    },
    "proof": {
    "type": "JsonWebSignature2020",
    "created": "2023-07-26T11:40:27.040Z",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "did:web:identity.gaia-med.org:demo:alice",
    "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..DzROLYYttONm6X5O6U0H-QFOswVK0W021OT2ld3OXNbBipiKIlh4wuwMcTsUKdoC4YGLHTX4q03SFI7PFdMBfmldtUdjlmUfyWBqb_nfOU9xB_o68DIaHQSH-SSeT3zLW_4m3OGAldVlTMYdLjv5tLRPzfODMnaViquN-WYvKItkAF7zyeRoO2SbnqXhPaTsTRyR3kPgLuxEOkPdB9nUX6Y6kzOvBVb9cvOV-affrsAatkD-g1bbdSNU_GKGDlaBO_SDrTKLxQLeqE19gJlAr6VE534AsW9IuXc10D0bgVjmM3buYIH6HjrSpKdSyDkn58BkZw-xqJn_vTkeCOMs_oBMgd0sh8A0U5vgBCXLv2Fv6LvxXwvKUIZxzSuZnPvh5jcf-DjK3sFKn65duzl_g3SQXO-MwXDWyTaOBLzaKhdiSigaDgrIAEPK5WCuNK1_ZMTmmCXDOllf2nn3lmVpRaBDrWjpBy-rg6HS5iF57i5SCEN3Uf6jUv4ARmbDZGlWRLCBYXGjaY_OlqRjOIpgTUYyKEMkkXxAkSVigYk4bDaO0_sD2w344DOjbC_CMCFjlosQi1KkGg-m-tuJKQ30xLDi8EYAxIypAA7wrSjOpnTGnCozFHzV85yLZGCJ8gwNhIduorvO8uuzxvglAJtzkKGNVvz9WnDKICxBqcdZpzc"
    }
}

Verification of a Verifiable Credential

Verification of a Verifiable Credential consists of the following steps:

  1. The issuer’s DID document, which contains their public key, is fetched from the DID URL contained in the credential’s proof block (under verificationMethod).

  2. The full JWS string, is reconstructed by calculating the payload, in the same way as when it is created for signing:

    1. The proof block is stripped from the full credential JSON.

    2. The remaining JSON is canonized according to URDNA2015.

    3. The canonized string is hashed using SHA256.

  3. The resulting JWS is verified against the issuer’s public key.

Verification fails if the JWS is invalid, or if the Verifiable Credential does not contain a proof block.

Important

Take special care during JWS verification as the payload is not base64-encoded. When choosing a JWS implementation, make sure it can handle this edge case. Some (like jwcrypto for Python) require base64-encoding the payload anyway before verification.

Verification of a Verifiable Presentation

Verifiable Presentations containing a proof block can also be verified as a whole. The algorithm is as follows:

  1. Verify the Verifiable Presentation itself as described in Verification of a Verifiable Credential.

  2. Verify each Verifiable Credential contained in the Verifiable Presentation.

Distribution of credentials using DID URLs

To not having to transmit one’s full Self-Description credential with every request, a Self-Description can be distributed by only specifying the corresponding DID URL.

To make a Self-Description credential discoverable through a DID, it needs to be linked from the latter. This is accomplished by adding a URL to the Self-Description VP inside the DID’s service block, for example:

{
  "id": "did:web:example.com:johndoe",
  "@context": "https://www.w3.org/ns/did/v1",
  "service": [
    {
      "id": "#self-description-url",
      "type": "SelfDescription",
      "serviceEndpoint": "https://example.com/johndoe/vp.json"
    }
  ],
  // ...
}

A Participant or Service Offering Self-Description is therefore discoverable by only specifying its DID URL, in this case did:web:example.com:johndoe.

Fetching and verifying a credential from a DID URL therefore is accomplished using the following steps:

  1. Resolve the DID URL back to a normal URL.

  2. Fetch the DID document from the URL.

  3. Read the credential serviceEndpoint link from the DID document’s service block, from the object with the ID #self-description-url.

  4. Fetch the credential from the URL.

  5. Verify the downloaded credential.

Tooling

We have developed Python and TypeScript libraries that can be used to work with Verifiable Credentials and DID Documents, including:

  • Resolution of DID (WEB) URLs and fetching of DID Documents,

  • Resolution and fetching of Verifiable Presentations via their DID URLs (as long as the DID Document contains a valid service entry, see Distribution of credentials using DID URLs above),

  • Verification of Verifiable Presentations and Verifiable Credentials,

  • Creation and signing of Verifiable Presentations and Verifiable Credentails.

Note

The libraries are tailored towards usage for GAIA-X-Med-relevant credentials and DID documents. They could possibly be used for more generic applications, but we make no guarantees.