Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
This section elaborates the theory behind the Wallet:
Wallet Basics - Learn what the Wallet Kit is and what it does.
Architecture - Explore the architecture and components.
Feature List - Explore all features in an overview list
Important: Please be informed that, beginning from December 2023, the Wallet Kit will no longer receive new features. Furthermore, the Wallet Kit is planned for discontinuation by the end of Q3 2024. However, all functionalities offered by the Wallet Kit are now integrated into our new libraries, APIs, and apps in the walt.id identity repo. Giving you more modularity, flexibility and ease-of-use to build end-to-end digital identity and wallet solutions.
Read the transition guide here. For any clarification or questions, feel free to contact us.
This documentation will help you understand how the Wallet works and how you can use it. However, it presumes a certain level of knowledge about Self-Sovereign Identity (SSI) so
if you are already familiar with SSI, you can jump to the introduction of the Wallet.
if you are new to SSI, please continue with our introduction to Self-Sovereign Identity.
Learn what SSI is and how it works.
Self-Sovereign Identity (SSI) is a user-centric approach to digital identity that gives people and organizations full control over their data. As a result, SSI enables anyone to easily share their data and reliably prove their identity (i.e. who they are and anything about them) without sacrificing security or privacy.
In other words, SSI enables you to “bring your own identity” and this is true for potentially any type of information - from your core identity (e.g. name, age, address) to your education and work records, your health and insurance data, bank account and financial information, etc.
Moreover, SSI can be used to model the digital identities of people, organizations and things.
At the end of the day, SSI promises a digital world in which interactions are effortless and worry-free. It is simply the next evolutionary step in identity management, a new paradigm in which our digital identities are no longer fragmented and locked into silos that are under someone else’s control, but only at our own disposal to be shared securely and privately.
SSI allows us to model digital identity just like we are used to the way identity works in the non-digital world based on paper documents and cards. There are just some minor twists.
For example, instead of our identity documents being made of paper or plastic, they are digital credentials made of bits and bytes and instead of storing them in wallets made of leather, they are stored in digital wallets on our phones. Importantly, these digital credentials can be reliably verified by anyone they are shared with online or offline.
In doing so, SSI enables decentralized ecosystems in which different parties can exchange and verify identity-related information. These ecosystems look like three-sided marketplaces, so that every party can take on three roles:
Issuers - Parties who “issue” identity-related data to people or organizations (“Holders”) in the form of digital credentials. They are the original data sources of an SSI ecosystem. For example, a government issues digital passports to citizens or a university issues digital diplomas to graduates.
Holders - Individuals or organizations who receive digital credentials that contain data about themselves from various sources (“Issuers”). By aggregating and storing such credentials in digital wallets, Holders can build holistic digital identities that are under their control and can easily be shared with third parties ("Verifiers").
Verifiers - Parties who rely on data to provide products and services can reliably verify and process data that has been provided by others (“Holders”). Verifiers, also called “Relying Parties”, are usually organizations or individuals in their professional capacity.
Usually, a single party plays only one of these roles per interaction. However, it is perfectly normal for a party to take on different roles in different interactions.
For example:
A university (Holder) is being accredited to issue certain types of educational credentials by a national authority (Issuer).
A university (Issuer) issues a digital diploma to a graduate (Holder), who can share this information with a recruiter (Verifier) in the course of a job application.
After the recruiting process, a recruiter (Issuer) issues the results of an applicant’s assessment (e.g. skills, referral) to the applicant (Holder), who can share this information with a new manager or another recruiter (Verifier).
A manager (Issuer) issues the results of a performance review to his employee (Holder) who can share this information with HR (e.g. to improve talent development programs).
Learn about the technologies and concepts on which SSI is based.
Understanding SSI requires the understanding of a few core concepts:
Registries, which serve as a shared and trusted record of certain information. In other words, they serve as a “layer of trust” and a “single source of truth”.
Cryptographic keys, which convey control over digital identities and enable core functionality such as encryption and authentication.
Decentralized Identifiers (DIDs), which establish a public key infrastructure by linking keys to unique identifiers that allow different parties to find and interact with each other.
Verifiable Credentials (VCs) which are digital identity documents that can easily and securely be shared with and verified (incl. validity, integrity, authenticity, provenance) by anyone in a privacy preserving way. Importantly, they are never (!) stored on a blockchain due to privacy and compliance reasons.
Protocols enable the exchange of data (VCs) between different parties.
Wallets, which store our keys (control) and VCs (identity data) and enable the management and sharing of our digital identities and data via easy-to-use applications.
The following graphic shows the SSI tech stack:
The following graphic shows how SSI works and highlights the core concepts (in blue):
Think of these core concepts as different building blocks that are available in different variations and can be put together in different ways:
As a result, there are different “flavours” of SSI depending on which variations of which building blocks have been used and how they have been put together.
Importantly, the differences in terms of technologies that are being used illustrate why interoperability has always been one of the most important topics within the industry and why the development and use of open standards (e.g. by the W3C, Decentralized Identity Foundation, OpenID Foundation and others) are vital for technology and vendor selection.
The following section explains all concepts in more detail.
Registries serve as a single source of truth in which all participants of an SSI ecosystem can trust. Depending on the ecosystem, registries make information accessible to anyone or just a limited group. Registries are important because they enable:
(Distributed) Public Key Infrastructures (DPKIs) which establishes an open distribution system for public keys which can be used for encryption and authentication among others.
Trust Registries which contain reliable information about people, organisations, things and even credentials (e.g. data models, status and validity information) to ensure that different parties can trust each other and the identity-related data they exchange.
Different technologies can be used to implement Registries. For example:
Blockchains or L1: Typically blockchains are used because it is unfeasible (or even impossible) to tamper with them. The fact that no single organisation can change the contents of a blockchain or manipulate the terms by which it is governed are very aligned with the requirements for identity ecosystems. Today, we see a growing number of developers and organizations focusing on so-called permissioned blockchains (i.e. only a selected group can “write”) like Ethereum Quorum/Enterprise. Permissionless blockchains, like Ethereum, are still used, but less than the permissioned alternatives for a variety of reasons like scalability, costs, lack of customisable governance frameworks.
L2: Layer two networks sit on top of blockchains and aggregate data before anchoring it. The main idea behind them is to circumvent common challenges of public, permissionless blockchains like scalability and cost issues. The most popular implementations in the context of identity are “ION” (for Bitcoin) and “Element” (for Ethereum).
Other Distributed Ledger Technologies (DLTs): Sometimes other DLTs are utilised like the Interplanetary File System (IPFS) though its use for digital identity remains limited.
Domain Name Service (DNS): Considering certain drawbacks of DLTs and their relatively slow adoption by the mass market, DNS can also be used to serve as a registry. Though it is not fully decentralised (considering its underlying governance framework), DNS has many advantages like its maturity and global adoption.
Importantly, SSI can be implemented without registries, particularly without blockchains, because identity data (or at least personal data of individuals) is never anchored due to privacy and compliance reasons. However, by combining SSI with blockchains (or other technologies), robust and trustworthy identity ecosystems that utilise transparent DPKIs and reliable Trust Registries can emerge.
DIDs are important because they establish a (distributed) public key infrastructure (DPKI) and allow parties to find each other, authenticate and encrypt and verifiably sign data.
A variety of “DID methods'', which are different implementations of the DID specification, exist. Considering that DID methods differ in terms of how they are created, registered and resolved, different methods come with different advantages and disadvantages.
For example, while DIDs are often anchored on Registries, such as EBSI (did:ebsi) or the Domain Name Service (did:web), new methods emerged that do not require Registries because their distribution is based on peer-to-peer interactions (e.g. did:key).
As example, the identifier did:ebsi:2A9RkiYZJsBHT1nSB3HZAwYMNfgM7Psveyodxrr8KgFvGD5y of the method did:ebsi would resolve to the following DID document:
Our open source products enable you to use different DID methods for different identity ecosystems. Every relevant functionality (e.g. generation, anchoring, resolution) is supported .
Verifiable Credentials (VCs) and Verifiable Presentations (VPs) are digital credentials that contain actual identity data of people or organisations and are standardized by the W3C. They are digital equivalents of paper-based identity documents like passports or diplomas.
VCs are created and signed by “Issuers”, the data sources within an SSI ecosystem. Issuers are typically organisations (e.g. governments, universities, banks) who provide people (or other organisations) with VCs that prove identity-related attributes.
For example, a university acts as an Issuer, if it issues diplomas (VCs) to its graduates.
VCs typically contain at least:
the Issuer’s DID
the recipient’s DID (also called “Holder”)
information about the VC’s validity (e.g. expiration date, references to revocation mechanisms)
the recipient’s identity attributes (e.g. name, age, address, …)
the signature of Issuer (also called “proof”) other information (e.g. semantic contexts, issuance date, evidence related to the issuance process, references to external VC data models/templates)
Here is an illustrative example of a VC:
VPs are composed and signed by “Holders”. They can contain identity information from one or multiple VCs and are created for the purpose of presenting them to a “Verifier”. In other words, VPs are the format with which the contents of VCs are shared by the person or organisation that is described by the VCs.
For example, a graduate presents a VP to an employer that contains information from her digital passport and diplomas.
VPs typically contain at least:
VCs or parts of VCs (individual attributes)
the recipient’s signature (to ensure so-called “Holder binding”)
Here is an illustrative example of a Verifiable Presentation:
Our open source products enable you to act as an "Issuer" (create and issue VCs), as a Holder (manage and share VCs/VPs) and as a Verifier (request and verify VCs/VPs).
Different authentication and data exchange protocols are used to securely transfer identity data (e.g. VCs, VPs) between parties (e.g. from an Issuer to a Holder). They typically establish a mutually authenticated and encrypted data channel between the communicating parties.
The most common data exchange protocols used for SSI are:
OIDC4SSI / SIOP (Self-Issued OpenID Connect Provider): An extension of a mature authentication and authorisation protocol called "OpenID Connect" (OIDC).
DIDComm: A novel protocol specifically designed for SSI and maintained by the Decentralized Identity Foundation (DIF).
Credential Handler API: A proposed browser-extension that may be used to connect the user's identity wallet to a web-application.
Our solutions enable you to use different data exchange protocols like OIDC/SIOP as required by different ecosystems.
The Wallet Kit (or "wallet backend") as well as the Issuer and Verifier Portals (or "Issuer and Verifier backends") are built as abstraction layers over the SSI Kit. They provide user data separation (user contexts of the underlying data stores) and high-level APIs for the interaction with the web frontends and the credential exchange protocols such as OIDC and SIOP.
Moreover, the wallet backend can be seen as an abstraction over the "Custodian" component of the SSI Kit, whereas the Issuer and Verifier backends build on top of the "Signatory" and "Auditor" components, respectively.
It has always been our goal to provide developers and organizations with great tools, so they can focus on delivering holistic identity solutions. Taking the lessons learned from previous products, we decided to redesign our current offering, resulting in what we now call The Community Stack. A collection of open-source products providing everything to launch any identity solution with ease. You can learn more about it .
Starting from December 2023, the Wallet-Kit will halt feature enhancements, leading to a complete discontinuation planned for end-Q3 2024. It's essential to plan your transition to the new stack effectively.
The table below indicates which components of the Wallet-Kit are already supported in the new stack.
If you have any question, please .
All relevant new libaries and APIs have found it's place in the repo.
Wallet-Kit Feautres | The Community Stack |
---|
The Wallet enables you to launch an identity wallet or extend an existing app with identity capabilities:
Learn about Self-Sovereign Identity (SSI).
Welcome to our Introduction to Self-Sovereign Identity (SSI) for developers and technical readers.
Before you get started, feel free to explore other (less technical) resources that will help you and your team to get a more holistic understanding of SSI and digital identity in general:
.
DIDs are unique identifiers (URIs) which are standardised by the . DIDs are typically linked to "DID Documents" which contain metadata like keys, service endpoints or proofs.
Since mid-Jan Q1/23 the Wallet Kit extended it's multi-issuer configurability to a complete multi-tenancy supported system.
All API endpoints for issuer configuration have the option for setting a tenantId.
The default tenantId is "default".
POST /issuer-api/{tenantId}/config/did/create
POST this JSON body to the specified URL:
Method being one of: [ key, web, ebsi, iota, cheqd, jwk ]. Only the method is required. All "didWeb" prefixed options are only needed for creating a did:web.
Response: did:key:z6MknaJ7YLdkCq1QV2tcwVSY5uVfUKGfBdigo7g4PyipTnCc
GET /issuer-api/{tenantId}/config/getConfiguration
POST /issuer-api/{tenantId}/config/setConfiguration
The configuration was amended to include the "issuerDid" attribute with the DID from "Creating a DID for a tenant".
Verifiable Credential templates/types setup
You can import a DID document using:
The value "default" of --as-issuer
refers to the tenantId.
By specifying vc templates --help
you can also view other VC template commands (besides import you can list, export and remove)
GET /issuer-api/{tenantId}/config/templates
By default, only the template ID will be shown, but the full template will not be loaded.
GET /issuer-api/{tenantId}/config/templates/{templateId}
Response for "VerifiableId" credential:
POST /issuer-api/{tenantId}/config/templates/{templateId}
For this demo, we will add the example w3c-ccg credential CrudeProductCredential:
/issuer-api/{tenantId}/config/templates/{templateId}
Issuer web portal
Web based user interface for issuing credentials to the web wallet
Wallet configuration
Possibility to configure list of supported wallets (defaults to walt.id web wallet)
Credential issuance
Support for issuing verifiable credentials to the web wallet, based on OIDC for credential issuance specification
Verifier web portal
Web based user interface for requesting credential presentations through the web wallet
Wallet configuration
Possibility to configure list of supported wallets (defaults to walt.id web wallet)
Presentation exchange
Support for presentation exchange based on OIDC for verifiable presentations (SIOP) specification
User Account/Wallet Management |
E-Mail/Password |
web3 address |
Key Management Create and mange Keys/DIDs in user wallets |
ed25519 |
secp256k1 |
secp256r1 |
rsa |
DID Management Create and mange Keys/DIDs in user wallets |
did:key |
did:jwk |
did:web |
did:cheqd |
did:iota |
did:ebsi | Not yet fully supported |
Credential Issuance (OID4VC) |
W3C as JWT |
W3C as SD-JWT |
W3C as JSON-LD | Not supported |
Credential Verification (OID4VP/SIOPv2) |
W3C credentials (JWT) |
W3C credentials (SD-JWT) |
W3C credential (JSON-LD) | Not supported |
Other Credential Features |
Credential Templates |
Credential Revocation | Not yet supported |
Policies |
Open-Policy Agent Policies |
The wallet backend provides a simple command line interface, to run and/or configure the backend, including the issuer and verifier backends.
Make sure you have Docker or a JDK 16 build environment including Gradle installed on your machine
Cloning the project
2. Change directory
3. Build docker container
4. Create an alias
4. Run the project (with alias)
6. Run the project (without alias)
Cloning the project
2. Change directory
3. Build the project
4. Create an alias
Note: The alias will only exist during the current terminal session and must be set again in any sessions their after
5. Run the project (with alias)
6. Run the project (without alias)
To get info about available options of the run command, use:
waltid-walletkit run --help
More options how to build the project can be found here.
For configuring keys and DIDs (especially for the Issuer or Verifier backends), the wallet backend integrates some commands from the SSI Kit for key and DID management.
The config command lets you define the context in which you want to execute the command, by specifying the arguments --as-issuer, --as-verifier or --as-user [userID] or their shortcuts -i, -v, -u [userID], before the respective subcommand.
E.g.
This command lists the DIDs available in the context of the issuer backend.
To get info about available options of the config command, use:
waltid-walletkit config --help
For more details about the integrated commands, you may want to refer to the documentation of the SSI Kit, which you find here:
Here are the most important things to know about the Wallet Kit:
It is open source (Apache 2). You can use the code for free and without limitations.
It is an out-of-the-box solution that you can simply re-use or even white-label such as for building pilot projects quickly.
It is customisable in a sense that you can individualise the app based on your requirements: You can rebrand the app, build your own UI and add new features. ****
It is composable in a sense that you can plug your existing (d)apps into the wallet backend in order to supercharge your (d)apps with SSI capabilities.
It abstracts complexity such as low-level functionality related to key handling, data storage, signing and interactions with third party systems.
It is built on open standards to ensure interoperability and prevent lock-in effects.
It is flexible in a sense that you can deploy and run wallets on-premise, in your (multi) cloud environment or directly integrate our libraries.
It enables you to use different identity ecosystems like Europe’s emerging identity ecosystem (EBSI, ESSIF) in anticipation of a multi-ecosystem future. (Consult the to find out which ecosystems the Wallet Kit supports.)
Like the wallet-backend, the issuer and verifier portals are built on top of the SSI Kit, to leverage its functionality for issuing, signing and verifying credentials, provided by the Signatory and Auditor components resepectively.
Since the issuer and verifier backends are currently integrated with the wallet-backend project, refer to the Architecture section for details.
To save you the roundtrip, in case you ended up on this page, here's the architecture diagram once more:
The Issuer and Verifier Portals are demo web portals showcasing the scenarios of getting verifiable credentials issued into the wallet by a certified issuer or presenting a credential to a relying party. They can be used as reference implementations for issuers and verifiers to implement their own service platforms.
For credential and presentation exchange, we make use of the OIDC/SIOP protocols described in OIDC.
There are 3 ways to integrate the verification flows into your application:
Same-device (web-based) flow
Cross-device flow (with QR code)
Via webhooks (callback)
In all cases, first make sure you have your tenant configured with all the verification policies, etc. that fit your requirements.
Then start the presentation flow, using the methods described below.
GET /verifier-api/<tenantId>/present?walletId=walt.id&vcType=VerifiableId
Supported parameters:
Key | Description | Example |
---|
Answers with a redirect (header "Location") to the verification URL (at your specified wallet). e.g.
(a local wallet at localhost was configured in this example case)
By telling the wallet what vcType is required, it will usually filter the list of credentials in the user UI to only display relevant credentials of the specified type.
In the same-device flow the browser gets navigated to this API URL, with the given parameters
The walletkit redirects to the wallet and on completion, the walletkit redirects the browser back to the application.
Example flow
Navigate the browser to:
https://wallet.walt-test.cloud/verifier-api/default/present?walletId=walt.id&vcType=VerifiableId&vcType=Europass&verifierUiUrl=https://myservice.example.com/callback/
The browser will be redirected to the wallet. The user will be presented the presentation request and asked to confirm it.
Eventually the browser will be redirected back to the application like this:
https://myservice.example.com/callback/success/?access_token=abc123
Note the subpath /success/
being added to the verifierUiUrl
!
GET /verifier-api/{tenantId}/presentXDevice
Supported parameters:
For starting a cross-device presentation flow, call this API with the required parameters to create a presentation request.
As a response, you get an object containing a requestId
and a url
.
Your application should now render the url
from the response object as a QR code, or deep-link.
GET /verifier-api/{tenantId}/verify/isVerified
Supported parameters:
This API will return a status 404 Not found
, while it is waiting for the cross-device request to be fulfilled.
When the request is fulfilled, it will return a status 200 OK
with the redirection URL in the response body.
GET /verifier-api/<tenantID>/auth?access_token=abc123
Parameters
As seen in the first example, you can optionally set a callback:
https://wallet.walt-test.cloud/verifier-api/default/present?walletId=walt.id&vcType=VerifiableId&verificationCallbackUrl=http://wallet.local:5555/callback/5dd9f971-9cd2-4c41-a40f-5340ac6d1fd3
(Note &verificationCallbackUrl=
)
When setting a callback, the Wallet Kit will then call this callback as webhook when the user shares a credential (in the walt.id demo wallet: actually clicks "Share credentials").
Before answering the user, the Wallet Kit will send out an HTTP Post request using the parameters described below.
When the callback answers HTTP statuses
Statuses:
OK (200),
NoContent (201),
or Accepted (202)
the Wallet Kit will mark the callback as accepted and continue its normal operation.
When the callback answers HTTP statuses
Statuses:
MovedPermanently (301),
Found (302),
TemporaryRedirect (307),
or PermanentRedirect (308)
the Wallet Kit will abort its operation and redirect the user (using the Location
header) to the Location
specified by the callback.
This is useful for redirecting to pages based on what credentials the user shares or change depending on the data of the credentials.
When the callback answers HTTP statuses
Statuses:
Unauthorized (401),
or Forbidden (403)
the Wallet Kit will invalidate the status and set overallValid to false, even if the selected VerificationPolicy
s would result in an overallValid = true
.
When you set up your webhook to listen for such a Wallet Kit callback, you have a variety of data to work with:
state: (UUID) ID of the verification session
subject: (DID) DID of the user that created the shared presentation
auth_token: (JWT[Subject]) Signed representation of subject = DID
vps: (List[VPVerificationResult])
VPVerificationResult:
vp: (JWT) Signed representation of the Verifiable Presentation
Including DIDs, issuance dates (attribute iat
, nbf
), etc...
and obviously the actual Verifiable Credential (in attribute vc
)
vcs: (List[JWT])
Signed Verifiable Credentials sourced from the Verifiable Presentation (VC in attribute vc
, issuance date iat
nbf
, Subject DID sub
, ...)
verification_result: (VerificationResult)
valid: Boolean
overall valid state
policyResults: Map[Policy -> Boolean]
e.g. policyResults={SignaturePolicy=true, ChallengePolicy=true, PresentationDefinitionPolicy=true}
(Empty values that are not set [= null] are omitted for this example, e.g. no expirationDate was set, thus you'll receive "expirationDate": null
)
Demo showing an identity/SSI use case from a person’s (Holder’s) perspective.
Test the Wallet
Visit the .
Create an account or log into an existing account.
Request VCs directly from the wallet by (1) clicking the “Request Credentials” button (2) choosing the “Issuer Portal” (3) selecting a credential type.
Claim the VC from the Issuer Portal.
Accept the VC.
Present the VC to a .
You can also experience an end-to-end use case demo by using the“” (incl. issue and verify VCs).
Each project can be easily built using docker:
Now, launch the containers using the described in the previous section, which also sets up the necessary API mappings for the web frontends to find the API endpoints.
We operate the following as public services for demo and trial purposes only:
Web wallet
Verifier portal
Issuer portals
The deployed services are not meant for production use and no guarantee for data integrity is given. All user data may be scratched without prior warning at our own discretion.
The stable deployment is updated manually whenever a stable release build is ready:
Web wallet:
Issuer portal:
Verifier portal:
A deployment of the bleeding edge developments is updated in a rolling fashion on every successful build of the master branch of the wallet backend project.
This deployment should not be considered stable and should not be used for demo purposes, unless you want to try out a bleeding edge feature, that is not yet available in the stable deployment.
The rolling deployment is available for demo and trial at:
Web wallet:
Issuer portal:
Verifier portal:
To authenticate with the stable or rolling deployments use any email address and password. Your data will be kept separate based on the email address, however, no password protection is enabled on these services.
Don't store any personal or sensitive data on our public services, as no password protection is enabled.
Issuance is very simple, in fact, you only need to call a single HTTP POST endpoint:
POST /issuer-api/{tenantId}/credentials/issuance/request
Wallet When issuing a credential, you will have to pre-select what type of wallet shall be used.
There are three types of wallets:
Mobile wallets:
Cross device flow: User uses another device (desktop pc, laptop) than where their wallet is installed (smartphone).
In this case, you will use the virtual wallet "x-device", which creates an "openid-initiate-issuance://..." URL.
Web wallets:
Same device flow: User uses the same device that their wallet is installed on.
In this case, you will have to additionally ask what web wallet the user is using (if you aren't forcing them to use your or an specific web wallet).
e.g. "walt.id", which creates an "..." URL.
App wallets
Theoretically same device flow, but also uses the virtual wallet "x-device" for creating an "openid-initiate-issuance://..." URL.
In the default configuration you can use the wallet "walt.id" (), or the virtual wallet "x-device" for the cross device flow ("openid-initiate-issuance://...").
The selected walletId is the id configured in the mappings seen in wallet_kit-configuration.m
Using our prebuild frontend applications for the different parties (holder, verifier, issuer), you can easily offer a full-fledged solution to your customers and clients by connecting them to the .
- The frontend solution for holders
- The frontend solution for verifiers
- The frontend solution for issuers
For building the project JDK 16+ is required.
For importing, building and running the project in your Kotlin/Java IDE, refer to your IDE documentation.
For a plain Gradle build, independent of your IDE, simply execute:
For building the project NodeJs v14+ and Yarn 1.22+ is required.
In the nuxt configuration in nuxt.config.js
, you may want to adjust the API proxy mappings, which by default point to either our rolling public deployment or localhost:
Uncomment or adjust to your needs:
Build and run the project using:
The service is started on port 3000 by default.
For production build and other build options, follow the instructions in the README.md
of the project.
For building the project NodeJs v14+ and Yarn 1.22+ is required.
In the nuxt configuration in nuxt.config.js
, you may want to adjust the API proxy mappings, which by default point to either our rolling public deployment or localhost:
Uncomment or adjust to your needs:
Build and run the project using:
The service is started on port 8000 by default.
For production build and other build options, follow the instructions in the README.md
of the project.
For building the project NodeJs v14+ and Yarn 1.22+ is required.
In the nuxt configuration in nuxt.config.js
, you may want to adjust the API proxy mappings, which by default point to either our rolling public deployment or localhost:
Uncomment or adjust to your needs:
Build and run the project using:
The service is started on port 4000 by default.
For production build and other build options, follow the instructions in the README.md
of the project.
To setup the issuer portal backend a few things may need to be considered and some configuration may be required, depending on your situation.
Since the issuer portal backend is implemented in the same service as the wallet backend, refer to the wallet backend setup section for .
The configuration of the issuer portal backend can be adapted, by modifying the file
config/issuer-config.json
Configure the URLs via which the issuer portal UI and backend API will be reachable from an external source, e.g. a web browser, or the wallet backend requesting credential issuance:
Configure the DID used to sign issued credentials. Refer to for options to initialize a DID for the backend.
By default, the issuer backend will choose the first available DID in its data store. To enforce, which DID to use, set it in the issuer-config.json like so:
The issuer portal supports an issuance flow, that is triggered directly from the issuer portal into the SSI wallet. To support this kind of issuance flow, you need to configure the known wallets and how to connect to them:
This example shows the known wallet configuration for the walt.id web wallet, in issuer-config.json:
Here's a complete example for the issuer-config.json:
Data, such as dids and keys, are currently stored in the issuer subfolder, like so:
<data_root>/data/issuer
In the future various options to configure the issuer data storage may be provided.
To set up an issuer portal backend, it is crucial to define the DID by which issued credentials should be signed.
The wallet backend intergrates a subset of commands from the walt.id SSI Kit, to accomplish simple key and DID management.
For simplicity the examples will use the command placeholder
waltid-walletkit
The actual command depends on your execution environment, in the case of the docker container this could translate to something like:
docker run -p 8080:8080 -e WALTID_DATA_ROOT=/data -v $PWD:/data waltid/walletkit
To manage keys and dids for the issuer, use the config command, with the command flag --as-issuer, or its shortcut -i:
The following examples show typical use cases and scenarios of setting up an issuer backend for various ecosystems.
Create a new _Secp256k1_** key**
Sample output
Create a new _did:ebsi_
Sample output
Register the DID on the EBSI blockchain
Set the _issuerDid_** config property**
issuer-config.json
Create a new _did:web_
Run the following command, replacing the _domain** (-d) and **path_** (-p) arguments**, matching your web server on which you can publish the did document:
Observe the command output:
Publish the DID document on the web server
Copy the DID document from the above command output, and publish it on your web server, on the path printed by that same command.
The DID document in this example should be resolvable from this URL:
https://walt.id/.well-known/my-issuer/did.json
The domain and path will be different in your case.
Set the _issuerDid_** config property**
issuer-config.json
If you want to use an existing DID, that you own, for issuance, you can import it, given that you have access to the associated private key and DID document. If the DID is resolvable through the standard mechanism of the given DID method, only the private key is required.
The private key should be available in JWK or PEM format.
Import private key from JWK file
In this example, we import a private key from the file priv.jwk:
Output
Now we can import the DID, either by importing the DID document from a local JSON file, OR by resolving it from a public registry or likewise, depending on the DID method.
Option 1: Resolve and import DID
In this example, we import a did:key, for which the DID document can be derived without external DID registry, and associate it with the previously imported key ID:
Option 2: Import DID document
In case, the DID document cannot be resolved or derived, we can also import the DID document from a local JSON file:
The relevant output for both import options, will look similar to this:
Output
Set the _issuerDid_** config property**
issuer-config.json
The Wallet Kit supports credential issuance and presentation exchange via the OpenID Connect (OIDC) standards:
On the following pages you can find sequence diagrams of the integrated end-to-end flows.
To setup the verifier portal backend a few things may need to be considered and some configuration may be required, depending on your situation.
Since the verifier portal backend is implemented in the same service as the wallet backend, refer to the wallet backend setup section for .
The configuration of the verifier portal backend can be adapted, by modifying the file
config/verifier-config.json
Configure the URLs via which the verifier portal UI and backend API will be reachable from an external source, e.g. a web browser, or the wallet backend responding to a credential presentation request:
The verifier portal supports the OIDC/SIOPv2 credential presentation flow, that is triggered directly from the verifier portal requesting credentials from an SSI wallet. To support this kind of verification flow, you need to configure the known wallets and how to connect to them:
This example shows the known wallet configuration for the walt.id web wallet, in verifier-config.json:
By default, the verifier backend will apply some basic verification policies to the verifiable presentations and credentials, presented by the wallet. The default verification policies are:
SignaturePolicy
checks the signature of the credential
ChallengePolicy
verifies that the presentation was signed against the challenge requested by the verifier backend
VpTokenClaimPolicy
verifies that the SIOP response (presentation from the wallet) matches the vp_token claim
In order to enforce other policies to be executed on the presented credentials, you can use the additionalPolicies
property in the verifier configuration.
This also allows for configuring custom dynamic policies, and supports specification of policy arguments.
The verifier backend supports the verification policy management commands provided by the SSI Kit, using the following CLI subcommand:
This example shows the configuration of additional policies in verifier-config.json:
Here's a complete example for the verifier-config.json:
Data, such as dids and keys, are currently stored in the verifier subfolder, like so:
<data_root>/data/verifier
In the future various options to configure the verifier data storage may be provided.
We apologize that our current implementation does not yet support the Stardust Upgrade from IOTA. As such, you cannot issue or verify credentials associated via a did:iota. Please refer to our for more information on when our products will be updated to include this latest changes.
Depending on your preference, start exploring with the deep dive or a tutorial.
Deep dive
- See how IOTA was integrated into the SSI-Kit. The Wallet-Kit uses the SSI-Kit internally; therefore, we get all the functionality with the Wallet-Kit + more for easier integration with any app.
- Learn more about the OIDC4VP profile used for Login with IOTA
Tutorials
- Learn how to configure the wallet kit + other needed frontend projects to build a Login With IOTA use-case
Demo
The verification flow is started from the Verifier web portal. The Verifier requires a certain type of credential to be presented, and lets the user connect to a previously configured, known Wallet. The Wallet, receiving the SIOP authorization request, can check if all required credentials are available, and optionally trigger a credential issuance flow for possibly missing credentials. If all required credentials are available the user selects the credentials to present (if multiple credentials of the same type are available) and the Wallet generates the SIOP response, containing an id token and the verifiable presentation, and redirects back the verifier portal for verification:
To setup the wallet backend a few things may need to be considered and some configuration may be required, depending on your situation.
Configuration and data are kept in sub folders of the data root (by default the current working directory):
config/
data/
To override the data root, one can set the environment variable:
WALTID_DATA_ROOT
The configuration of the wallet backend can be adapted, by modifying the file
config/wallet-config.json
Configure the URLs via which the wallet UI and API will be reachable from an external source, e.g. a web browser, or a verifier service requesting a presentation exchange:
To enable OIDC credential issuance from within the wallet, you need to configure where the wallet finds the issuer APIs and possibly how to authenticate with the OIDC service.
For each known issuer configure a unique id, a description and the OIDC base URL. From this base URL, the wallet will try to resolve the OIDC discovery document at <base-url>/.well-known/openid-configuration
.
If you need to authenticate with the OIDC issuer service, you can configure the client_id and client_secret in two ways:
In wallet-config.json
In a separate file
To keep the secrets separated from the main config, you can keep them in a separate file, relative to the data root:
secrets/issuers.json
You can make use of this separate secrets file, e.g. in a Kubernetes or Docker Swarm deployment, to keep the passwords in a safe secret object. Also, it enables you to separate the secrets from the default configuration, which you may want to check in to version control.
Here's a complete example for the wallet-config.json:
User data (dids, keys, credentials) are currently stored in subfolders for the user id, like so:
<data_root>/data/<user@email.com>
It is planned to allow users to define their own storage preferences, in the future.
By default, the wallet backend exposes its API endpoints bound to localhost, port 8080.
To override the default bindings, set the following environment variables:
WALTID_WALLET_BACKEND_BIND_ADDRESS
WALTID_WALLET_BACKEND_PORT
To set binding address and port, you can also use the command arguments of the run command like so:
To set the bind address to "192.168.0.1" and the port to 8081:
To bind to all interfaces (on the default port):
Learn how to build a login with IOTA use-case
In this tutorial, you will learn how to configure the wallet kit + other needed frontend projects to build a Login With IOTA use-case. The tutorial is divided into two sections. First, we will set up and configure the backend handling the business logic, followed by the frontend projects which are provided for an easy and fast lauch.
Make sure you have Docker installed on your machine
Cloning the project
2. Change directory
3. Running the project
To make sure only Verifiable Credentials with a "did:iota" can pass the verification (login), we will create a policy and use it in our verifier configuration.
IOTA policy
Registering the policy
The Wallet-Kit has multi tenant support, which means multiple customers, or tenants, can use a single instance of the wallet-kit, with each tenant having their own data and configurations isolated from others. And we will now create + use our IOTA tenant to register the policy
The Wallet-Kit has multi tenant support, which means multiple customers, or tenants, can use a single instance of the wallet-kit, with each tenant having their own data and configurations isolated from others. And we will now create our IOTA tenant to handle all IOTA related operations.
First, we get the configuration of the default tenant and use it as a baseline for the configuration of our IOTA tenant.
Using the response, we just got from the default tenant configuration, we will update additionalPolicies
as well as the verifierApiUrl
as follows:
Let's now set the above configuration object as the configuration for our IOTA tenant.
To have the fully working Login With IOTA Demo up and running, we need three more projects:
The Waltid-Wallet - To create an IOTA DID and get a Verifiable Credential based on an IOTA DID issued
The Waltid-Issuer-Portal - The application responsible for issuing a Verifiable Credential to the DID IOTA holder (Wallet)
The Waltid-Verifier-Portal - The application in which the holder will log in to using a Verifiable Credential based on a DID IOTA
Make sure you have node.js installed on your machine
Cloning the project
2. Change directory
3. Install dependencies
4. Run the project
Cloning the project
2. Change directory
3. Install dependencies
4. Run the project
Cloning the project
2. Change directory
3. Checkout feat-iota brunch
4. Install dependencies
5. Run the project
Now that we have the backend and all frontend applications up and running, we can start the Login with IOTA flow.
Make sure you set the newly created IOTA DID as default DID of the wallet in the ecosystem overview as shown in the video
All our products are open source under the permissive **** license. This means:
You can use, modify and distribute our products for free and without strings attached.
You can use our products to build pilots or even production systems.
You can deploy, run and manage our products on-premise or in your own cloud environments.
if you are using our products. We are curious to learn about your experience and happy to spread the word about your project via our newsletter or case studies.
Run our products with the support of our experts.
All our products are open source under the permissive **** license. This means:
You can use, modify and distribute our products for free and without strings attached.
You can use our products to build pilots or even production systems.
You can deploy, run and manage our products on-premise or in your own cloud environments.
To complement our free products, we offer services for clients who want to manage our products by themselves:
Consulting
Custom development and integration
Support / SLAs
if you want to learn more.
The web wallet supports a custom issuance flow, that can be triggered from the issuer portal and makes use of the OIDC for verifiable presentations (SIOP) flow, to commute between issuer portal and wallet. The user starts at the issuer portal and selects the credentials they want to get issued. The issuer portal redirects to a, previously configured, known wallet, using the SIOP flow outlined above. The wallet creates the SIOP response, posts it to the issuer portal, and in return receives the issued credentials, given that the credential presentation was verified successfully:
If you are working on one of the web frontends (e.g. web-wallet, issuer-portal, verifier-portal), you may want to run the wallet backend container standalone, to connect your local web frontend build with it.
Edit the configuration files in waltid-walletkit/config
, according to your needs and run the container like so:
Note: Running the web frontend containers standalone, makes little sense, as they depend on an API gateway to connect to the backend APIs. This API gateway is set up by the docker-compose configuration, mentioned above.
The easiest and fastest way to get the wallet backend, frontend, and issuer and verifier portals started, is by using our docker-compose configuration, located in the project, in the subfolder:
./docker/
.
Simply start the services using:
This configuration will publish the following endpoints by default:
Web wallet on [HOSTNAME]:8080
API: /api/
Verifier portal on [HOSTNAME]:8081
API: /verifier-api/
Issuer portal on [HOSTNAME]:8082
API: /issuer-api/
Note: __ [HOSTNAME] is your local computer name. If you use localhost instead, some features, particularly with regards to credential exchange, will not work correctly.
In case the HOSTNAME is not picked up automatically, you might need to set it in an env-file and refer to it by: docker-compose --env-file env-file-with-hostname up.
Visit the ./docker
folder for adjusting the system config in the following files:
docker-compose.yaml - Docker config for launching containers, volumes & networking
ingress.conf - Routing config
config/wallet-config.json - wallet backend configuration
config/verifier-config.json - verifier backend configuration
config/issuer-config.json - issuer backend configuration
The issuance flow is triggered from the Wallet. The user chooses from a list of issuer portals known to the wallet backend, and triggers the issuance of any credential type the issuers support. Optionally, the Issuer can require a Verifiable Presentation of certain types of credentials, to be sent with the initial authorization request. If the authorization is successful, the issuer portal provides an authorization code and access token, for the wallet to retrieve the issued credentials:
- issue credentials
(currently, only did:key support) - receive and store credentials
- issue credentials
(currently, only did:key support) - receive and store credentials
- verify credentials
(currently, only did:key support) - receive and store credentials
- verify credentials
(currently, only did:key support) - receive and store credentials
In The Community Stack, we no longer have the notion of a credential template. The issuance will simply happen by providing the full W3C data schema, which will then be signed. A list of credentials schemas can be found
Similar. A list of all policies can be found .
Not yet supported. However, the new also give you great flexibility until we will reintroduce Open-Policy Agent policies.
The web redirection URL is configured in the tenant configuration parameter , or can be overridden using the verifierUiUrl
URL parameter.
The verifierUiUrl
is called with the sub-path /success and an access_token
parameter, which can be used to .
Use the access token to retrieve the verification result from the walletkit like described in .
Key | Description | Example |
---|
The requestId
from the response object can be used to query the verification request status, using the API endpoint described .
The wallet can scan the rendered QR code and parse the presentation request. Eventually it will post the presentation response to the walletkit backend, which will update the .
When the request is fulfilled, the response of the API, will contain a URI with the access_token
parameter, which can be used to fetch the presentation result using the API.
Key | Description | Example |
---|
The application calls this API, after starting a , using the request ID received in the response object for the state
parameter of this API.
From the redirection URL, the application can parse the access_token
parameter, to fetch the .
Key | Description | Example |
---|
The response of this request will be a verification result, like described in the section section.
Answers with a redirect (header "Location") to the issuance URL, e.g.
Since the issuer portal backend is implemented in the same service as the wallet backend, refer to the wallet backend setup section for .
Get the bearer token from , and then execute these commands:
Also refer to
Also refer to
Also refer to
For details of using verification policies and creating custom dynamic policies, refer to the corresponding section of the .
Since the verifier portal backend is implemented in the same service as the wallet backend, refer to the wallet backend setup section for .
POST /verifier-api/{tenantId}/config/policies/create/{name} Use swagger to
GET /verifier-api/{tenantId}/config/getConfiguration Use swagger to
POST /verifier-api/{tenantId}/config/setConfiguration Use swagger to
Creating a "did:iota" and registering it on the IOTA tangle. Thankfully, the Wallet frontend, which we can now reach under , already implements that logic, so we can easily open the settings, view Ecosystems, choose IOTA and register our DID. This will send a request to our running wallet-kit instance requesting the creation of DID as well as and registration of it with the IOTA tangle.
Claiming a VerifiableID Credential. Visit where our walt-id-web-wallet is running and issue yourself a VerifiableId by clicking the "Request Credential" button and selecting the Walt.id Issuer portal (the other frontend we spun up earlier) running on . Now what we have the Verifiable Credential, we can use it and login to the application.
Login into the Verifier Portal. Visit where our walt-id-verifer-portal is running and click the "Login With IOTA" button to start the login flow. In background, the verifier portal will call our running instance of the wallet-kit, requesting a verification of the present credential. Using our custom policy from earlier, it will check that the subject of the present Verifiable Credential is an "iota:did". On the result screen of the verification, you will see a list of all the policies which were validated and if the validation has been successful.
tenantId | Path parameter, the tenant ID for this request | /verifier-api/default/verify/isVerified?... |
state | The request ID as returned by the | state=req123 |
tenantId | Path parameter, the tenant ID for this request | /verifier-api/default/auth?... |
access_token | The access token, as returned in web redirection URL or cross-device verification response | access_token=abc123 |
The Wallet Kit makes it easy for you to build and launch your own wallet. Now, you can think of wallets as secure data hub for organizations and individuals which allows them to act as "Holders", i.e. they can store, manage and share keys, identity data (e.g. Verifiable Credentials) and other secrets.
Practically speaking, a wallet is a tool that allows anyone to collect and present identity data in order to access services (e.g. sign up, login, check-out) or procure products in a seamless and privacy preserving fashion.
Since there are different types of wallets, it is important to mention that our Wallet Kit enables so-called custodial wallets, which means that keys and data are ultimately stored by the wallet provider (e.g. by you). While this means less control for end-users, it also means a better user experience (e.g. no need to handle private keys or seed phrases) and less risk (e.g. loss of data). Also, end-users enjoy full data portability, which means that they can switch wallets (and take their keys and data with them) at any time without having to fear lock-in effects.
The Wallet Kit provides various high-level functionalities. For example:
Web app
Web-based user interface (UI) for managing credentials and DIDs.
User context separation
Separation of user contexts in the data stores (key store, credential store, DID store).
User data management
DIDs
Credentials
Ecosystems integrations
did:ebsi
DID creation
DID registration
did:web
DID creation
DID web registry
did:key
DID creation
Verifiable Credential and Presentation exchange
Support for credential and presentation exchange based on the OIDC and SIOP specs
OIDC4CI - OIDC for credential issuance
OIDC4VP - OIDC for verifiable presentations (SIOP)
Credential issuance via SIOP protocol (custom protocol)
Important: Please be informed that, beginning from December 2023, the Wallet Kit will no longer receive new features. Furthermore, the Wallet Kit is planned for discontinuation by the end of Q3 2024. However, all functionalities currently offered by the Wallet Kit will be integrated into our new libraries, APIs, and apps under The Community Stack. This is aimed at providing a more modular, flexible, and efficient solution for your needs. For any clarification or queries, feel free to contact us as we aim to make this transition as smooth as possible.
There are different ways to get started with the Wallet Kit, either you use the backend service provided by the Wallet Kit via an API and build your own frontend, or you run the Wallet Kit (backend service) and our pre-build frontend applications for the different parties (holder, verifier, issuer).
Docker Compose: Quick way to launch and try out the latest builds of our backend API and the frontend applications. No build environment required, adaptation of default config may be necessary, depending on your setup.
Local Docker Build: Quickly build the individual services (backend & frontend) using Docker and launch the docker images. No local build environment required, besides docker.
Local Build: Build and run the services (backend & frontend) locally on your machine. Requires build environment, including JDK 16, Gradle, NodeJs and Yarn.
Dependency (JVM): The Wallet Kit ("wallet backend") can be used directly as JVM-dependency for Maven or Gradle.
CLI tool: The Wallet Kit comes with a command-line interface to conveniently configure the issueer DID among other configuration options.
REST API - Use the Wallet Kit API.
Frontend Applications - Offer a full solution by connecting our pre-build frontends to the Wallet Kit backend.
If you just want to try out the Wallet Kit (backend) and the Issuer and Verifier Portals (frontends), you may directly use our public deployments, which don't require any configuration or build environment.
tenantId | Path parameter, the tenant ID for this request | /verifier-api/default/present?... |
walletId | Wallet ID as configured in the tenant configuration | walletId=walt.id |
vcType | Credential type that should be requested in the presentation request. Can be specified multiple times | vcType=VerifiableId&vcType=Europass |
pdByReference | pdByReference=false |
verifierUiUrl | verifierUiUrl=https://myservice.example.com/verification/callback/, will be called like: https://myservice.example.com/verification/callback/success/?access_token=abc123 |
verificationCallbackUrl |
tenantId | Path parameter, the tenant ID for this request | /verifier-api/default/presentXDevice?... |
vcType | Credential type that should be requested in the presentation request. Can be specified multiple times | vcType=VerifiableId&vcType=Europass |
pdByReference | pdByReference=false |
The wallet can also be used as direct dependency for JVM-based applications. In this case an existing application can easily be transformed into an SSI wallet backend.
The following illustrates how the wallet-backend can be used via Gradle:
Repositories
maven("https://maven.walt.id/repository/waltid/")
maven("https://maven.walt.id/repository/waltid-ssikit/")
Dependency
implementation("id.walt:waltid-walletkit:<version>")
The code-base as well as more detailed instructions can be found at GitHub
If true, the presentation definition will be passed as a URI in the presentation request (see ), otherwise a full PD object is included in the parameter.
Web redirection URL, on which the verification result will be received. The browser will be navigated to this URL with the sub-path /success, containing an access_token parameter, which can be used to obtain the verification result, overrides the configuration parameter in the tenant configuration
Webhook to actively callback with the verification result (see also ), the URL needs to be configured as allowed webhook in the tenant configuration.
If true, the presentation definition will be passed as a URI in the presentation request (see ), otherwise a full PD object is included in the parameter.
We offer our products as a managed cloud service for clients who do not want to deploy, manage and run our products by themselves.
The Cloud Platform includes:
All products
Enterprise use cases
Fully managed cluster
Cloud SLA / support
Get in touch if you want to learn more.
Login With IOTA
Learn how to set up Login With IOTA