Building with Digital Credentials

Your starting point for integrating verifiable, user-centric identity into your applications.

Comparing Digital Credential Standards

PropertyW3C VCSD-JWTISO mDocOpenID4VP
Credential FormatJSON-LD, JWTJWT (with disclosures)CBOR, COSEProtocol (format-agnostic)
Signature/Proof MechanismJWS, Linked Data ProofsJWS (ES256, EdDSA)COSE_Sign1Depends on credential format
Supported Libraries/SDKsjsonld-signatures, did-jwt-vcsd-jwt-python (Python), sd-jwt-js (TypeScript)spruceid/isomdl, OWF identity-credentialOpenID4VP, spruceid/openid4vp
Example Issuance FlowIssuer creates VC, signs with private key, delivers to walletIssuer creates SD-JWT, signs, delivers with disclosuresIssuer encodes data in mDoc, signs with COSE, delivers to walletIssuer issues credential, wallet presents via OpenID4VP
Example Verification FlowVerifier checks signature, validates claims, resolves DIDVerifier checks signature, validates disclosures, holder bindingVerifier parses mDoc, checks COSE signature, validates dataVerifier requests credential via OpenID4VP, validates response
DID SupportYes (core to spec)OptionalOptional (mDL may use DIDs)Yes (for subject/issuer identification)
Selective Disclosure SupportLimited (ZKP extensions)Yes (Data Integrity BBS+)Yes (via namespaces)Depends on credential format
Mobile/Browser SupportHigh (many wallets, browser libs)Growing (wallets, libs emerging)Mobile-first (iOS, Android)High (browser, mobile, cross-platform)
Interoperability NotesWidely adopted, many wallet/libsPrivacy by design, growing supportStrong binding, mobile optimizedProtocol for cross-ecosystem flows
Reference Spec/DocsVC Data ModelSD-JWT IETF DraftISO 18013-5OpenID4VP Spec

Getting Started

The digital credential ecosystem comprises several key components: Digital Wallets for users to store and manage their credentials, Issuer Services that create and sign credentials, and Verifier Tools used by applications to request and validate credentials. Choosing the right standards (like W3C Verifiable Credentials, SD-JWT, mdoc) depends on your specific use case, regulatory requirements, and desired level of interoperability.

Consider factors like the type of claims, security needs, and the target platforms when making your decision.

Integration Guides

W3C Verifiable Credentials (VC) are a flexible, extensible standard for expressing credentials in JSON-LD or JWT format. Widely supported by wallets and libraries.

Issuing Example

// Pseudocode for Issuing a W3C VC (JWT)
function issueCredential(subjectData, issuerPrivateKey) {
  const claims = {
    "@context": ["https://www.w3.org/2018/credentials/v1"],
    type: ["VerifiableCredential", "YourCustomCredential"],
    issuer: "did:example:issuer123",
    issuanceDate: new Date().toISOString(),
    credentialSubject: {
      id: subjectData.id,
      ...subjectData.attributes
    }
  };
  const signedVcJwt = signJwt(claims, issuerPrivateKey);
  return signedVcJwt;
}

Verifying Example

// Pseudocode for Verifying a VC-JWT
async function verifyVcJwt(vcJwt, issuerPublicKey) {
  // 1. Decode JWT (don't trust payload yet)
  // 2. Verify signature using issuer's public key
  // 3. Validate claims (e.g. expiration, structure)
  const isValid = await jwt.verify(vcJwt, issuerPublicKey, {
    algorithms: ['ES256']
  });
  return isValid;
}

Apple

Seamless Web Identity Verification with Apple Wallet IDs

WWDC 25 • Session 232 • 32 min

Apple's Wallet & WebKit teams have introduced a standards-based way to prove identity online without the friction of photo uploads. By combining ISO 18013-5/7 mobile documents (mdocs), the W3C Digital Credentials API, and Apple Wallet's secure enclave, the flow gives users a one-tap, privacy-respecting alternative to legacy KYC checks. The demo and engineering walkthrough are captured in WWDC 25 Session 232

Watch the full session on Apple Developer →

Why This API Changes the Game

User trust & claritySelective disclosureFewer abandoned checkoutsNo more manual reviewStandards first

Component Overview

ComponentPrimary Role
Server backendBuilds & signs ISO 18013-7 request; stores HPKE private key; decrypts & validates the returned mdoc.
Website frontendCalls navigator.credentials.get() on a user gesture and forwards the encrypted response to the backend.
Browser (Safari/WebKit)Implements the Digital Credentials API, shows the picker & consent sheet, and relays encrypted payloads.
Operating system (iOS/iPadOS/macOS)Checks signatures in a secure sandbox, displays system UI, and routes the full request to Wallet or another credential app.
Document source (Wallet or credential app)Supplies only the requested fields, HPKE-encrypted & signed, back to the website.

Request Flow

This is everything that happens before the user taps "Allow." It originates on your backend, surfaces in your frontend, and finishes when iOS passes the full, signed request to the credential source.

Component Responsibilities

This diagram shows the journey of a digital credential request from your backend to the user's device.

┌────────┐ Build & sign   ┌────────────┐ Digital Credentials ┌───────────┐  route   ┌────────────────┐
│Server  │──────────────▶│ Website    │────────────────────▶│ Browser   │──────────▶│      iOS       │
│backend │               │ frontend   │                      (Safari)  (System UI)└────────┘               └────────────┘                     └───────────┘          ▼
                            Full request & consent                  ┌────────────────┐
                            release────────────────────────────────▶│ Document Source│
                                                                     └────────────────┘

This table summarizes the main responsibilities of each component in the request flow.

ComponentResponsibility
Backend (server)Assemble the JSON payload: document type, requested elements, encryptionInfo (nonce + HPKE recipient key), and one or more readerAuthenticationAll signatures.
Frontend (browser JS)On a user gesture, call navigator.credentials.get() with the payload.
Safari / iOSDisplay picker ▶︎ consent sheet ▶︎ forward full request to Wallet or another provider.

Example Code

This is a Node-style pseudo-code example for building and signing the credential request on the server side.

Server-side Build Example
// ① Generate HPKE keys + nonce
const { publicKey, privateKey } = hpke.generateKeyPair();
const nonce = crypto.randomBytes(16);

// ② Compose Device Request
const deviceRequest = {
  docType: "org.iso.18013.5.1.mDL",
  nameSpaces: {
    "org.iso.18013.5.1": {
      given_name: false,
      family_name: false,
      age_over_21: false,
      portrait: false,
      driving_privileges: false
    }
  },
  encryptionInfo: {
    recipientKey: publicKey,
    nonce
  }
};

// ③ Sign for Wallet & any other providers
const signedPayload = signWithABC(deviceRequest); // ABC = Apple Business Connect
// Optionally add more signatures for local apps and push into readerAuthenticationAll

return signedPayload;

This is a frontend JavaScript example for invoking the Digital Credentials API and handling the response.

Frontend Invocation Example
// ④ Kick off the flow on click
async function verifyIdentity() {
  try {
    const requestData = await fetch("/build-mdoc-request").then(r => r.json());

    const credResponse = await navigator.credentials.get({
      mediation: "required",
      digital: {
        requests: [{ protocol: "org-iso-mdoc", data: requestData }]
      }
    });

    await fetch("/validate-mdoc", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(credResponse)
    });
  } catch (e) {
    console.error("MDOC flow failed, falling back", e);
  }
}

Partial Requests — Why They Exist

Before the user even sees a consent sheet, iOS parses a partial request inside a strict sandbox. This stripped-down object holds only safe-to-display data: what is being requested, who is requesting, and the authentication certificates. Parsing it early blocks malformed or malicious payloads from ever touching sensitive OS components. Only after the user taps Allow does the full, raw ISO 18013 request reach Wallet or the credential app.

Info: For security, iOS parses only a partial request in a strict sandbox before showing the consent sheet. The full credential request is sent to the Wallet or credential app only after the user taps Allow.

Android

Android Digital Credentials Integration

Android • Digital Credentials • Coming Soon

🤖Guidance for integrating digital credentials on Android is coming soon.
Stay tuned for updates!

Code Samples & SDKs

Many open-source libraries and SDKs can help you get started. Look for tools that support:

  • W3C Verifiable Credentials (VCs) creation and verification (JSON-LD and JWT profiles).
  • SD-JWT creation, presentation, and verification.
  • Mobile Document (mdoc / ISO 18013-5) parsing and verification.
  • OpenID for Verifiable Presentations (OpenID4VP) for verifier and wallet interactions.
  • DID (Decentralized Identifiers) resolution and management.

Check platforms like W3C VC Test Suite & Implementations, and search for libraries specific to your programming language (e.g., for Node.js, Python, Java, Rust).

API Reference

API reference documentation coming soon.

Tutorials & Use Case Implementations

Step-by-step guides for common scenarios coming soon.

Community & Support

Join the conversation, ask questions, and contribute to the ecosystem:

Ready to Try Digital Credentials?

Try the DemoImplement digital credentials