Skip to content

Verifiable Credentials

Think of a physical ID card. It was issued by an authority you trust (a government, an employer), it contains specific facts about you (name, date of birth, photo), and anyone can look at it to verify those facts — without calling the authority that issued it.

A Verifiable Credential (VC) is the digital equivalent. It’s a signed data structure that says: “This authority certifies these facts about this person.” The signature is cryptographic, so anyone can verify it’s genuine and untampered — without contacting the issuer.

The key difference from a normal login token: a login session is temporary and tied to one service. A Verifiable Credential is something you keep in a digital wallet on your phone and present whenever needed — to different services, in different contexts, even offline.

A few concrete scenarios where VCs change what’s possible:

Age verification without identity disclosure. A streaming service needs to confirm you’re over 18. Today, that means uploading a scan of your ID — handing over your full name, address, and document number to prove a single fact. With a VC, you present a credential that says “over 18” and nothing else. The service never sees your name.

Offline identity at a border or checkpoint. An officer’s tablet can verify your credential by checking the cryptographic signature — no network connection, no API call back to the issuing server. The credential carries its own proof.

Corporate access across systems. An employee’s credential, issued from their company badge, works with the building access system, the internal HR portal, and a partner’s client portal — without each system needing a separate account or federation agreement.

European Digital Identity Wallet (EUDIW). The EU’s eIDAS 2.0 regulation requires member states to offer citizens a digital wallet for identity credentials. IDToken Seal VCs are designed to be compatible with this ecosystem from day one.

The issuance flow builds on the same X.1280 authentication that IDToken Seal uses for all login methods. The user experience is identical — the output is different.

  1. A wallet app (or a service acting on behalf of the user) requests a credential with specific scopes
  2. IDToken Seal shows the standard login page — the user enters their token ID
  3. The X.1280 mutual authentication happens: the service displays a code, the mobile app receives it via push, the user confirms and performs face verification
  4. After authentication succeeds, IDToken Seal builds a Verifiable Credential containing only the claims the user consented to share
  5. The signed credential is returned to the wallet — the user now holds it and can present it to any verifier
Wallet AppIDToken Seal (Issuer)Mobile App1. Request credential (type + scopes)2. Login pageEnter tokenId3. X.1280 (OTP + face)4. Auth verified5. Build VCFilter claims + sign6. Verifiable Credential (vc+jwt)7. Stored in walletPresent anywhereCredential held

The important point: no new authentication method is needed. The same OTP + face verification that powers OIDC and SAML login also produces Verifiable Credentials. The VC is just a different — more portable — output format.

Most Verifiable Credential systems face a trust problem: how does the verifier know the issuer is legitimate? Many early VC platforms relied on blockchain-based registries to solve this. IDToken Seal takes a different approach.

Every IDToken Seal VC includes an evidence field that points back to the Visible Digital Seal used during authentication. This means the identity claims in the credential didn’t come from a user-typed form or a social login — they were extracted from a government passport or organizational credential, verified through the ISO 22385 PKI trust chain managed by a Trust Service Operator.

The chain of trust looks like this:

Government passport → read via NFC chip → VDS credential (signed by a certified authority) → verified during X.1280 authentication → Verifiable Credential (signed by IDToken Seal, with evidence linking back to the VDS)

A verifier checking an IDToken Seal VC can trace the identity all the way back to the original document — without blockchain, without a proprietary trust registry, and without contacting the IDToken Seal server in real time.

VC issuance uses the same scope-based selective disclosure as all other IDToken Seal integration methods. The credential type determines which scopes are required, scopes expand to specific claims, and the user approves what to share on their mobile app.

Derived claims are particularly valuable in VCs. A credential containing ageOver18: true proves a predicate (“this person is over 18”) without revealing the underlying date of birth. Similarly, isEuCitizen confirms citizenship status without disclosing the specific nationality.

The user’s consent is cryptographically bound — the granted scopes are included in the ECDSA signature from the mobile app during authentication. The server cannot add claims after the fact.

All three output formats use the same underlying X.1280 authentication flow. The choice depends on what the consuming system needs.

FeatureVerifiable CredentialsOIDCSAML
Token formatJWT-VC (vc+jwt)JWT (id_token)XML assertion
StandardW3C VC Data Model 2.0OpenID Connect CoreSAML 2.0
Holder storageWallet app (persistent)Browser sessionBrowser session
Offline verificationYes (signature + cached status list)No (requires token endpoint)No (requires IdP metadata)
Selective disclosureVia scopes → credentialSubjectVia scopes → claimsVia attribute mapping
Issuer identityDID (did:web:)HTTPS issuer URLSAML Entity ID
RevocationBitstring Status ListToken expiryAssertion expiry
Best forDigital wallets, eIDAS 2.0, offlineCloud services, modern web appsEnterprise SSO, legacy systems

The sections below cover the credential format, types, examples, revocation mechanism, issuer identity, and wallet discovery protocol. This is the implementation detail — the sections above explain the concepts.

IDToken Seal issues VCs in JWT-VC format (vc+jwt) as defined by the W3C Verifiable Credentials Data Model 2.0. The JWT contains:

PropertyValue
JWT header typvc+jwt
JWT header algES256 (ECDSA P-256)
issIssuer DID (did:web:auth.idtokenseal.id3.eu)
subHolder’s tokenId
jtiUnique credential identifier (UUID)
nbfIssuance timestamp
expExpiration timestamp
vcThe Verifiable Credential claim object

The vc claim contains the W3C-compliant credential structure with @context, type, credentialSubject, evidence, and credentialStatus.

IDToken Seal supports three credential types, each mapping to the existing scope system:

Credential TypeScopes UsedClaims in credentialSubject
IDTokenSealIdentityCredentialidentity:fullgivenName, familyName, dateOfBirth, nationality, documentNumber, trustLevel
IDTokenSealAgeVerificationidentity:age_verificationageOver18, givenName, familyName
IDTokenSealBasicIdentityidentity:basicgivenName, familyName, trustLevel

The credential type determines which claims appear in the credentialSubject. Just like IDToken Seal’s other integration methods, users see a consent screen on their mobile app and can deny individual scopes.

A decoded IDTokenSealIdentityCredential JWT-VC payload:

{
"iss": "did:web:auth.idtokenseal.id3.eu",
"sub": "vds-token-uuid",
"jti": "urn:uuid:3f8c9a7e-1b2d-4e5f-a6b8-c9d0e1f2a3b4",
"nbf": 1711324800,
"exp": 1711411200,
"vc": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://idtokenseal.id3.eu/ns/credentials/v1"
],
"type": ["VerifiableCredential", "IDTokenSealIdentityCredential"],
"credentialSubject": {
"id": "vds-token-uuid",
"givenName": "Jean",
"familyName": "Dupont",
"dateOfBirth": "1985-06-15",
"nationality": "FRA",
"documentNumber": "12AB34567",
"trustLevel": 3
},
"evidence": [{
"type": "VisibleDigitalSeal",
"standard": "ISO 22376",
"verificationMethod": "ECDSA-P256",
"schemeOperator": "Otentik",
"manifestId": "0A1B2C"
}],
"credentialStatus": {
"id": "https://auth.idtokenseal.id3.eu/credentials/status#1234",
"type": "BitstringStatusListEntry",
"statusPurpose": "revocation",
"statusListIndex": "1234",
"statusListCredential": "https://auth.idtokenseal.id3.eu/credentials/status"
}
}
}

An IDTokenSealAgeVerification credential contains only the minimum claims needed — no date of birth, no document number:

{
"iss": "did:web:auth.idtokenseal.id3.eu",
"sub": "vds-token-uuid",
"jti": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"nbf": 1711324800,
"exp": 1711411200,
"vc": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://idtokenseal.id3.eu/ns/credentials/v1"
],
"type": ["VerifiableCredential", "IDTokenSealAgeVerification"],
"credentialSubject": {
"id": "vds-token-uuid",
"ageOver18": true,
"givenName": "Jean",
"familyName": "Dupont"
},
"evidence": [{
"type": "VisibleDigitalSeal",
"standard": "ISO 22376",
"verificationMethod": "ECDSA-P256",
"schemeOperator": "Otentik"
}]
}
}
Evidence FieldDescription
typeVisibleDigitalSeal — the credential source
standardISO 22376 — the VDS international standard
verificationMethodECDSA-P256 — the signature algorithm used to verify the VDS
schemeOperatorThe scheme operator that governs the issuing CA (e.g., Otentik)
manifestIdThe VDS manifest identifier, linking to the credential schema definition

IDToken Seal uses the W3C Bitstring Status List for credential revocation. Each issued credential receives a unique index in a published bitstring. When an enrollment is revoked, the corresponding bit is flipped and the status list is updated.

Status FieldValue
typeBitstringStatusListEntry
statusPurposerevocation
statusListIndexThe credential’s position in the bitstring
statusListCredentialURL of the published status list

The status list is itself a Verifiable Credential (a signed JWT containing the gzipped bitstring), published at a well-known URL. Verifiers fetch and cache it to check revocation status without contacting the issuer for each verification.

IDToken Seal uses a did:web Decentralized Identifier as the VC issuer:

did:web:auth.idtokenseal.id3.eu

The DID resolves to a DID document published at /.well-known/did.json, which contains the same ECDSA P-256 public key already exposed at /.well-known/jwks.json. This means:

  • Verifiers resolve the issuer DID by fetching the DID document over HTTPS
  • The verification key in the DID document matches the key used to sign the VC
  • Key rotation is handled by updating the DID document (same as JWKS rotation)
  • No blockchain or distributed ledger is required — trust is anchored in DNS + TLS + the VDS PKI chain
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/jws-2020/v1"
],
"id": "did:web:auth.idtokenseal.id3.eu",
"verificationMethod": [{
"id": "did:web:auth.idtokenseal.id3.eu#key-1",
"type": "JsonWebKey2020",
"controller": "did:web:auth.idtokenseal.id3.eu",
"publicKeyJwk": {
"kty": "EC",
"crv": "P-256",
"x": "...",
"y": "...",
"kid": "...",
"use": "sig",
"alg": "ES256"
}
}],
"assertionMethod": ["did:web:auth.idtokenseal.id3.eu#key-1"],
"authentication": ["did:web:auth.idtokenseal.id3.eu#key-1"]
}

IDToken Seal publishes credential issuer metadata at /.well-known/openid-credential-issuer, following the OpenID for Verifiable Credential Issuance (OID4VCI) specification. This allows OID4VCI-compatible wallets to discover:

  • Which credential types are available
  • The supported format (jwt_vc_json)
  • The cryptographic suites supported (ES256)
  • The credential endpoint URL
{
"credential_issuer": "https://auth.idtokenseal.id3.eu",
"credential_endpoint": "https://auth.idtokenseal.id3.eu/credentials/issue",
"credentials_supported": [
{
"format": "jwt_vc_json",
"types": ["VerifiableCredential", "IDTokenSealIdentityCredential"],
"cryptographic_binding_methods_supported": ["did:web"],
"cryptographic_suites_supported": ["ES256"],
"display": [{
"name": "IDToken Seal Identity Credential",
"description": "Full identity credential backed by a government-issued VDS",
"locale": "en"
}]
},
{
"format": "jwt_vc_json",
"types": ["VerifiableCredential", "IDTokenSealAgeVerification"],
"cryptographic_binding_methods_supported": ["did:web"],
"cryptographic_suites_supported": ["ES256"],
"display": [{
"name": "IDToken Seal Age Verification",
"description": "Age verification credential (over 18) without revealing date of birth",
"locale": "en"
}]
},
{
"format": "jwt_vc_json",
"types": ["VerifiableCredential", "IDTokenSealBasicIdentity"],
"cryptographic_binding_methods_supported": ["did:web"],
"cryptographic_suites_supported": ["ES256"],
"display": [{
"name": "IDToken Seal Basic Identity",
"description": "Minimal identity credential with name and trust level",
"locale": "en"
}]
}
]
}

This metadata endpoint enables progressive adoption: wallets can discover IDToken Seal as an issuer today, and full OID4VCI protocol support (pre-authorized code flow, credential offers, deferred issuance) can be added incrementally.