Overview
SSI runtimes
Introduction
Role-based SSI guide. Walk through the three roles, understand data boundaries, and compare examples across web, server, and mobile SDK runtimes.
Self-sovereign identity becomes easier to understand when each responsibility has a clear owner. An Issuer creates a Verifiable Credential, the Holder keeps it in a mobile secure vault, and a Verifier requests and verifies a Verifiable Presentation (VP).
Important note
[Issuer validates and signs VC] -> [Holder stores VC on mobile] -> [Holder consents and creates VP] -> [Verifier validates VP]
Key concepts
Issuer
Validates source data, signs the credential, and sends a credential offer through DIDComm.
Holder
Keeps the credential in one mobile secure vault and decides when to disclose claims.
Verifier
Requests only the claims it needs and validates signatures, challenge, and credential status.
DID registry
Publishes and resolves DID Documents through CertNet, did:web, ION, or an internal registry.
Credential boundaries
Introduction
Identra separates responsibilities clearly: the Issuer creates VCs, the Holder phone is the only vault, and the Verifier only requests and verifies VPs.
Most important rule
Web and server never receive a holding SDK. They cannot import, export, or back up user VCs.
DID registry is not locked to CertNet
CertNet is the default sandbox provider. The same SDK can publish and resolve DID Documents on CertNet, did:web, ION, or an internal registry depending on deployment policy.
Important note
Illustrative SDK, not for production use. Package names and contracts shown in this Overview are sample documentation.
Credential issuance
Issuer
STEP 01 of 03 in the role-based SSI flow.
Who creates a credential and where does the code run?
The issuer checks data, signs a VC, and sends it to the user. It may integrate on internal web, server, or app.
Data and key boundary
Organization signing keys must be protected for the runtime, preferably by an HSM on server.
Reference
| Runtime | SDK example | When to use |
|---|---|---|
| Web client | @identra/web with Browser JavaScript or TypeScript | Internal issuer tools with a controlled key policy |
| Server | @identra/node or identra-go | Protected signing services backed by HSM or managed KMS |
| Mobile app | @identra/react-native, Android SDK, or iOS SDK | Managed internal issuer applications |
Flow steps
- Initialize: Initialize the SDK for the current runtime.
- Create DID: Create or load the issuer DID on the selected DID registry.
- Sign VC: Sign a Verifiable Credential for the recipient DID.
- Send offer: Send the credential offer over DIDComm.
Code example
1. Choose runtime
2. Choose SDK and language
import { Identra } from '@identra/web';
// Illustrative SDK, not for production use.
const identra = new Identra({
environment: 'sandbox',
didRegistry: {
defaultProvider: 'certnet',
providers: ['certnet', 'did:web', 'ion', 'internal-ledger']
},
mediatorUrl: 'https://mediator.sandbox.identra.dev'
});
// Runs for the issuer on web, server, or an internal app.
const issuer = await identra.issuer.create({
did: 'did:identra:university',
keyProtection: 'platform-secure-storage'
});
// A DID Document can be published to multiple registries; CertNet is only the default sandbox provider.
await issuer.publishDidDocument({
registries: ['certnet', 'did:web']
});
const credential = await issuer.issue({
// The Holder DID is obtained after connection setup or from the business system.
subjectDid: 'did:identra:holder',
type: 'UniversityDegree',
claims: { degree: 'Information Technology', graduationYear: 2026 }
});
// The credential is not placed in the QR; the QR only bootstraps the DIDComm connection.
await issuer.didcomm.sendCredentialOffer({ credential, connectionId });Details
The Holder DID is obtained after connection setup or from the business system. The credential is not placed in the QR; the QR only bootstraps the DIDComm connection.
Credential verification
Verifier
STEP 03 of 03 in the role-based SSI flow.
How does the verifier trust a VP?
The verifier receives a VP, extracts holder and issuer DIDs, resolves DID Documents through the matching registry provider such as CertNet, did:web, or ION, then checks signatures, challenge, and revocation status.
Data and storage boundary
A verifier may run on web, server, or app, but it must not store VCs as a Holder.
Guidance
- Create request: Create a presentation request with a replay-resistant challenge.
- Show QR: Display a QR containing the DIDComm invitation.
- Receive VP: Receive the VP over the newly established connection.
- Resolve and verify: Resolve holder and issuer DIDs through the registry provider and verify.
Code example
1. Choose runtime
2. Choose SDK and language
import { Identra } from '@identra/web';
// Illustrative SDK, not for production use.
const identra = new Identra({
environment: 'sandbox',
didRegistry: {
defaultProvider: 'certnet',
providers: ['certnet', 'did:web', 'ion', 'internal-ledger']
},
mediatorUrl: 'https://mediator.sandbox.identra.dev'
});
// Runs for the verifier on web, server, or an app.
const verifier = await identra.verifier.create({
did: 'did:identra:jobs-example'
});
const request = await verifier.createPresentationRequest({
credentialType: 'UniversityDegree',
// Request only the required claims to reduce holder disclosure.
fields: ['degree', 'graduationYear'],
challenge: crypto.randomUUID()
});
const qrDataUrl = await verifier.createQr(request);
const presentation = await verifier.didcomm.waitForPresentation(request.id);
const result = await verifier.verify({
presentation,
// The SDK resolves the DID Document from the matching registry provider.
resolveDid: (did) => identra.didRegistry.resolveDidDocument(did),
checkCredentialStatus: true
});
if (result.verified) grantAccess();Was this page helpful?
Let us know what you think to help us improve.