info@yenlo.com
eng
Menu
WSO2 12 min

eIDAS 2.0, EUDI Wallet ft. WSO2 Identity Server: Issuance of a Verifiable Credential

Hasitha Amal Da Silva, Integration Consultant at Yenlo
Hasitha Amal Da Silva
Integration Consultant
eIDAS dots

WSO2 keeps adding support for new identity standards as they land, and Digital Identity Wallets are the latest one. In this blog series I want to walk through what’s possible with WSO2 Identity Server here. We start with the minimal setup and work towards fully EUDI ARF compliant behavior for issuing a credential to an EUDI wallet.

Today’s post covers how the latest release of WSO2 Identity Server issues verifiable credentials from an organization into a personal wallet. First, some background.

What is the EU Digital Identity Wallet (EUDI Wallet)? 

eIDAS 2.0 is a new EU regulation. It forces every member state to give its citizens a safe, sovereign and universally accepted way to prove not just who they are, but also their officially registered details and qualifications. Rather than interfacing directly between organizations, the wallets sit in between, giving the citizen full agency over what information to share, with whom, and when.

Today, when you check in to a hotel, rent a car, buy alcohol, or open a bank account, organizations must check your identity. So you hand over your ID card, passport or driver’s license. Often someone makes a copy, instantly holding more information on you than strictly necessary and keeping it around for far too long.

Soon, an app will cut down that unnecessary exposure of your own data.

The EUDI Wallet is the bridge between citizens and the digital world. It’s a secure container on your smartphone that lets you present your documents and details instantly, wherever you need them.

Current state of EUDI Wallet development 

All EU Member States must certify at least one wallet provider and be able to issue core credentials into those wallets by the end of 2026. From 2030, around 80 percent of EU citizens are expected to be able to use the wallet.

There is now a widely accepted Architecture and Reference Framework (ARF) created through eIDAS 2.0. This guides the technical implementation of wallets across multiple EU countries. Examples include the NL Wallet (Netherlands), the German EUDI Wallet (Germany), and many other countries.

A handful of vendors are tackling pieces of this same problem from different angles:

General wallet implementations for enterprise and employee scenarios.

These can be used to test against a PID provider (a government agency or university, for example) or a relying party. They’re built to the same specification as an EUDI Wallet.

  • Lissi: sells API software (the Lissi Connector) that businesses use to verify or issue credentials to an EUDI wallet, and also ships a working EUDI Wallet prototype (the Lissi Wallet) that users install to store and present their own credentials. That’s the wallet used later in this post. 

Infrastructure, SDKs and APIs to build a wallet or surrounding components. 

  • Walt.id open sources the building blocks for issuing and checking EU digital IDs and credentials. Its Community Stacks are free, so a university can wire up digital diploma issuance without signing a restrictive vendor contract first. 
  • Sphereon connects a company’s existing internal software to the EU digital ID system. It bakes in automated compliance and audit logging, which means a bank running older core systems can verify a customer’s tax information and generate the legal proof regulators require in the same step. 
  • SpruceID ships developer toolkits for plugging EU compliant digital identities into existing apps and systems. The modular design means, for example, an airline’s engineering team can add a “Login with European Digital ID” button without rewriting their existing security stack. 

What’s needed to run the wallet flow end to end 

EUDI ARF trust triangle diagram with the PID or QEAA issuer, the user EUDI Wallet instance and the relying party

As you can see from Figure 1, the flow expected around an EUDI Wallet Instance is as below: 

  1. The user chooses to store their personal credentials/attributes from a trusted issuer (government, a university, a hospital) into the Wallet. Once this is done, the wallet holds a cryptographically verifiable credential inside the user’s mobile device. 
  1. When the user must prove their identity or claim to a relying party (e.g. an energy provider, telecom provider, bank or employer), that party will request a presentation of the credentials from the user’s wallet. 
  1. When the wallet sends back the presentation created based on existing verifiable credentials, the relying party validates the origin and ownership of the credentials based on the issuer’s information through federated trusted lists, populated in advance following the process set out in EUDI ARF. 

Where does WSO2 Identity Server fit? 

As you can see from Figure 1, the EUDI wallet will expect a certain protocol from potential issuers and relying parties, namely OpenID4VCI and OpenID4VP. And this is where WSO2 Identity Server can be very useful. As a proven and tested IAM product worldwide, WSO2 Identity Server is now officially able to issue verifiable credentials to an EUDI wallet (Step 1) and work is in progress for future releases to support validation of a verifiable presentation using OpenID4VP. 

Issuing a verifiable credential to Lissi Demo Wallet 

Let’s start with the first goal and set the scenario. You’re operating under a trusted government entity that uses WSO2 Identity Server 7.3.0 to serve citizens, and you want to check first whether WSO2 can connect to a wallet built to the EUDI standard. I’ll use the Lissi demo wallet for this, since it’s easy to set up and compliant with the EUDI ARF. WSO2 has already published a user guide for this, and I’ll add the steps I had to work out myself to get it running. 

Prerequisites 

  1. Download WSO2 Identity Server from wso2.com/products/downloads 
  1. Download the Lissi Demo wallet app and set up demo access with a free account. 

Configuration changes in WSO2 

You will need to append the following configuration to wso2-is/repository/conf/deployment.toml: 

[verifiable_credentials]
enable = true

Need for a domain accessible from your mobile. When you are done with all the steps of this guide locally, you will need a secure way to expose your WSO2 server to the mobile app. I found this easier to do using a Docker setup with nginx proxying all calls to and from WSO2 Identity Server. Then I exposed the nginx server through port 80 from Visual Studio Code.

Steps within WSO2 Identity Server 

  1. Create a user with claims you wish to include in the wallet (e.g. given_name, last_name, emailaddress). 
  1. Create a credential template as per the WSO2 guide, step 1. 
  1. Register the Digital Wallet Application. Since the Lissi demo wallet expects a specific Client ID, you will need to create this application through the WSO2 REST API as per Appendix A below. 
  1. Allow the newly created application to request the credential as per the WSO2 guide, step 3. 
  1. To work with Lissi as an Issuer, the application must support a new authorization type, as mentioned in the WSO2 guide. You must create a new authorization type openid_credential as per Appendix B below, then retrieve the ID of the created resource and link it to the application you created in step 3. 
  1. Retrieve the credential offer URI from the Management Console and generate a QR code from it using any online tool, as per the WSO2 guide, step 4. Make sure to set the content type to “Text”. 
WSO2 Identity Server console with the Yenlo Demo VC ID credential template, user attributes and credential offer URI
QR code generator with the WSO2 Identity Server credential offer URI entered as text

7. Now you can follow through with the last step in the WSO2 guide and scan the QR code from the Lissi Wallet App. You will see that the WSO2 login page is shown, and after entering credentials, the verifiable credential will be shown in the Lissi App. 

Lissi Wallet asking the user to accept the Work ID credential issued by WSO2 Identity Server
Lissi Wallet overview showing the new work_id verifiable credential
Lissi Wallet detail view of the work_id credential with given name, family name and email

There you go. You have now seen how WSO2 Identity Server 7.3.0 can act as an OID4VC Issuer to provide credentials to an EUDI-compatible wallet. 

Next steps? 

Getting WSO2 Identity Server to issue credentials is a solid first step, but there’s more to build. The 2026 wallet certification deadline means most member states, and the vendors serving them, are still working out how the rest of the flow behaves in practice, credential presentation and validation included. In upcoming posts we’ll cover OpenID4VP support once it lands in a future WSO2 IS release, and what changes as the EUDI ARF itself keeps evolving. If you need help aligning WSO2 IS with your existing stack, or support migrating to 7.3.0 to get these wallet features working, Yenlo is WSO2’s leading partner in Europe. 

Appendix 

A: Creating the Digital Wallet Application with the WSO2 REST API 

curl --request POST \
  --url https://<WSO2_HOSTNAME>/api/server/v1/applications \
  --header 'access-control-allow-origin: https://<WSO2_HOSTNAME>/t/carbon.super/console' \
  --header 'authorization: Basic YWRtaW46YWRtaW4=' \
  --header 'content-type: application/json' \
  --data '{
    "inboundProtocolConfiguration": {
      "oidc": {
        "clientId": "9c481dc3-2ad0-4fe0-881d-c32ad02fe0fc",
        "grantTypes": [
          "authorization_code",
          "refresh_token"
        ],
        "publicClient": true,
        "allowedOrigins": [],
        "callbackURLs": [
          "https://oob.lissi.io/vci-cb"
        ],
        "pkce": {
          "mandatory": true,
          "supportPlainTransformAlgorithm": false
        },
        "refreshToken": {
          "renewRefreshToken": true,
          "expiryInSeconds": 86400
        }
      }
    },
    "accessUrl": "",
    "imageUrl": "",
    "name": "Digital Wallet App",
    "advancedConfigurations": {
      "skipLogoutConsent": true,
      "discoverableByEndUsers": false,
      "skipLoginConsent": true
    },
    "authenticationSequence": {
      "type": "DEFAULT",
      "steps": [
        {
          "options": [
            {
              "idp": "LOCAL",
              "authenticator": "basic"
            }
          ],
          "id": 1
        }
      ]
    },
    "templateId": "digital-wallet-application",
    "templateVersion": "1.0.1"
  }'

The resulting application ID will be in the response header Location: 

https://<WSO2_HOSTNAME>/api/server/v1/applications/3afe9cd6-cb2b-42cc-bb33-ccf3e6709aee

B: Creating a new authorization type, and linking it to the newly created application 

B.1: Create the authorization type 

curl --request POST \
  --url https://<WSO2_HOSTNAME>/api/server/v1/api-resources \
  --header 'accept: application/json' \
  --header 'authorization: Basic YWRtaW46YWRtaW4=' \
  --header 'content-type: application/json' \
  --data '{
    "name": "EUWallet API",
    "identifier": "euwallet_api",
    "description": "EUWallet API representation",
    "requiresAuthorization": true,
    "authorizationDetailsTypes": [
      {
        "type": "openid_credential",
        "name": "openid_credential",
        "description": "openid_credential",
        "schema": {
          "type": "object",
          "required": [
            "type",
            "credential_configuration_id",
            "locations"
          ],
          "properties": {
            "locations": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              }
            },
            "type": {
              "type": "string",
              "enum": [
                "openid_credential"
              ]
            },
            "credential_configuration_id": {
              "type": "string"
            }
          }
        }
      }
    ]
  }'

The resulting resource ID will be in the response header Location: 

https://<WSO2_HOSTNAME>/api/server/v1/api-resources/6b68310c-9a21-4f41-aa19-cc520c51f77c

B.2: Link the new authorization type to the Digital Wallet Application 

curl --request POST \
  --url https://<WSO2_HOSTNAME>/api/server/v1/applications/{{01_application_id}}/authorized-apis \
  --header 'accept: application/json' \
  --header 'authorization: Basic YWRtaW46YWRtaW4=' \
  --header 'content-type: application/json' \
  --data '{
    "id": "{{step05_adt_id}}",
  "authorizationDetailsTypes": []
  }'

Whitepaper: API Security

API Security
Download Whitepaper
eng
Close