Skip to content

End-to-End Example: Berlin Digital Bank

Organization Overview

Field Description
Name Berlin Digital Bank (BDB)
Sector Financial Services
Use Case Digital account opening (Level of Assurance: High)
Goal Verify the identity of new customers using the EUDI Wallet

Stage A: Plan

Use Case Definition
Berlin Digital Bank (BDB) enables digital account opening for new customers with a high level of assurance (LoA High). During onboarding, BDB must verify a customer’s name, date of birth, and residence using their Personal Identification Data (PID) credential from an EUDI Wallet.

Protocol and Profile Selection
Since the use case requires a high LoA, BDB’s presentation request must conform to the High Assurance Interoperability Profile (HAIP). For the EUDI Wallet Ecosystem, the full PID presentation flow is described in the EUDI Architecture & Concept documentation. Since customers may hold their PID in either SD-JWT VC or mDoc format, the verifier must accept both formats.

Attribute Selection

  • SD-JWT format: given_name, family_name, date_of_birth, address
  • mDoc format: given_name, family_name, date_of_birth, resident_address

BDB has defined its use case, identified required attributes, and determined the applicable interoperability and assurance requirements.

With a clearly defined use case, BDB fills in the intent form. BDB is invited to a Kick-Off call, after which they obtain access to the National EUDI Wallet Closed Beta by email invitation, and the German EUDI Ecosystem Sandbox Registrar.

Logging into the Sandbox registrar, BDB configures and issues an access certificate and a registration certificate.

Now that BDB has issued their access certificate and registration certificate, they can include them in their Presentation Request. As soon as they do, they will be recognisable to the EUDI Wallet Closed Beta App as a Relying Party in the EUDI Ecosystem Sandbox.


Stage B: Integrate

Wallet Invocation Setup

BDB has designed an account-registration flow that will lead a new customer into a PID presentation. To make the presentation request available to customers, an OpenID4VP Authorization Request is signed and hosted by BDB at its request_uri, following the EUDI Wallet Ecosystem flow rules. The presentation request is hosted as a Pushed Authorization Request.

BDB uses a deeplink to invoke the EUDI Wallet from its onboarding webpage. The deeplink uses a custom URI scheme defined by ETSI:

haip-vp://https://berlin.digitalbank.example/presentation_request

Note: In the HAIP, the custom uri scheme haip:// is required. This is not a requirement for the sandbox environment today.

Integrate OpenID4VP Verifier Component; SD-JWT and mDoc parsing enabled

There are open source OpenID4VP libraries available that support usually different profiles. BDB researches which open source libraries could support their use case. Berlin Digital Bank finds an open source library that supports PID presentation conforming to HAIP. The library helps BDB to perform the steps as described in the EUDI Wallet Ecosystem PID Presentation. This includes:

  • Generating keys
  • Generating an Authorization Request
  • Signing an Authorization Request
  • Decrypting an Authorization Response
  • Parsing and verifying an Authorization Response

Configure credential requests for required attributes only

Subsequently, BDB designs an example of what their authorization request could look like:

{
  "iss": "https://berlin.digitalbank.example",
  "aud": "https://wallet.example.org", 
  "iat": 1698163200,
  "exp": 1698166800,
  "client_id": "x509_hash:007ac9762a0e74d0a1a3cfd37e3cc3f2bd97055fcad79ef6355d7a4f0aaeb8da", // The value behind the colon is a hash of "berlin.digitalbank.example"
  "response_type": "vp_token",
  "response_mode": "direct_post.jwt",
  "scope": "openid",
  "nonce": "n-abcdef1234567890",
  "state": "s-xyz987654321",
  "redirect_uri": "https://berlin.digitalbank.example/post-registration",
  "client_metadata": {
    "jwks": {
      "keys": [
        {
          "kty": "EC",
          "kid": "ec-key-1",
          "use": "enc",
          "alg": "ES256",
          "crv": "P-256",
          "x": "f83OJ3D2xF4yG9mXQnKkT7H5Y3WZxR5m7yZy2P1XQ0",
          "y": "x_FEzRu9zM6T5nHcJZJx4Z3VtP4yKQz5xA6cD7E8F9"
        }
      ]
    }
  },    
  "verifier_info":{
    "data": "eY43rfc...",
    "format": "registration_cert"
  },
  "response_uri": "https://response.example",
  "dcql_query": {
    "credentials": [
        // PID in SD-JWT format
        {
            "id": "pid",
            "format": "dc+sd-jwt",
            "meta": {
                "vct_values": ["https://demo.pid-provider.bundesdruckerei.de/credentials/pid/1.0"]
            },
            "claims": [
                {"path": ["given_name"]},
                {"path": ["family_name"]},
                {"path": ["address", "street_address"]},
                {"path": ["birthdate"]}
            ]
        },
        // PID in mDoc format
        {
            "id": "pid-mdoc",
            "format": "mso_mdoc",
            "meta": {
                  "doctype_value": "eu.europa.ec.eudi.pid.1"
            },
            "claims": [
                  {
                    "id": "first_name",
                "path": ["eu.europa.ec.eudi.pid.1", "given_name"]
              },
              {
                    "id": "last_name",
                "path": ["eu.europa.ec.eudi.pid.1", "family_name"]
              },
              {
                    "id": "resident_address",
                "path": ["eu.europa.ec.eudi.pid.1", "resident_address"]
              },
              {
                    "id": "date_of_birth",
                "path": ["eu.europa.ec.eudi.pid.1", "birth_date"]
              }
            ]
        },
    ]
  },
    "credential_sets": [
    {
      "purpose": "Identification",
      "options": [
        [ "pid" ],
        [ "pid-mdoc" ]
      ]
    }
    ]
}

Pay extra attention to:

client_id: The prefix for the client_id used in this example is x509_hash, which describes the client_id_scheme used in the presentation.

client_metadata: Includes the JWKS for encryption; other metadata is provided in the Registration Certificate.

credential_sets: Allows acceptance of equivalent credentials in SD-JWT or mDoc format.

verifier_info: Contains the encoded Registration Certificate, establishing verifier trust.

vct_values: Please note that the current vct_values for an sd-jwt request is subject to change. In the future, we expect to use the value urn:eudi:pid:de:1 for the German PID Provider. In the long run, relying parties across Europe can query for a PID from any member state using the vct_value urn:eudi:pid:1.

At this point, BDB has integrated an OpenID4VP component that can take care of all the key actions taken during a PID presentation, and knows how to generate properly configured Authorization Requests.

The OpenID4VP library helps to decrypt and parse the content, now BDB needs to make sure that they can handle the data relayed in the Presentation Response. As such, BDB once again relies on the PID Rulebook to understand German EUDI Wallet specific handling of special characters. Finally, BDB implements validator code that checks whether the response follows the PID schema and all required attributes have been relayed correctly.

Stage C: Operate

  • Test in Sandbox with the National EUDI Wallet
  • Explore & expand future services (e.g., mortgage applications)
  • Maintain service, manage logs and certificate lifecycle
  • Prepare for production with logging and monitoring