Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Setting Up a Compliance-Friendly KYC Integration Using DIDs

A developer tutorial for building a KYC system that uses decentralized identity to meet regulatory requirements without centralizing user data.
Chainscore © 2026
introduction
INTRODUCTION

Setting Up a Compliance-Friendly KYC Integration Using DIDs

Learn how Decentralized Identifiers (DIDs) enable privacy-preserving Know Your Customer (KYC) processes for Web3 applications, balancing regulatory compliance with user sovereignty.

Traditional KYC processes create a significant privacy and security burden for users. Centralized databases storing sensitive documents like passports and utility bills are prime targets for data breaches. Furthermore, users must repeat the verification process for every new financial service, creating friction and data silos. Decentralized Identifiers (DIDs) and Verifiable Credentials (VCs) offer a paradigm shift. With this architecture, a user undergoes verification once with a trusted issuer, receiving a digitally signed, tamper-proof credential stored in their personal wallet. They can then selectively present proof of this credential—without revealing the underlying document—to any service that requires it.

A DID is a new type of identifier, standardized by the W3C, that is controlled by the user, independent of any centralized registry or authority. It typically looks like did:ethr:0xabc123... or did:key:z6Mk.... The core components of a DID-based KYC system are the Issuer (a licensed KYC provider), the Holder (the end-user), and the Verifier (your dApp or protocol). The issuer creates a Verifiable Credential, such as proof of identity or accreditation, and signs it cryptographically. The holder stores this VC in a secure digital wallet. When interacting with your platform, the holder presents a Verifiable Presentation, which is a packaged proof derived from their VC.

For developers, integrating this flow requires interacting with core standards. The did:ethr method, for example, uses Ethereum addresses as DIDs, with keys controlled by the user's wallet. A basic credential schema on-chain might define the required claims. When a user requests access, your smart contract or backend can request a Verifiable Presentation. Using a library like veramo or daf, you would verify the cryptographic signature of the presentation against the issuer's DID and check that the credential's claims (e.g., isOver18: true) satisfy your compliance rules. This is done without ever seeing the user's birthdate or national ID number.

The primary compliance benefit is selective disclosure and data minimization. Instead of submitting a full passport scan, a user can prove they are over 18 and a resident of a specific jurisdiction by presenting zero-knowledge proofs derived from their VC. This reduces your liability as a service provider. Furthermore, because credentials are cryptographically verifiable, you gain high assurance in their authenticity. It's crucial to work with KYC issuers whose own compliance and identity verification processes are robust, as your trust is delegated to the credential's signer.

To implement this, start by defining your compliance requirements: what attributes must be verified? Next, choose a DID method and supporting infrastructure. For Ethereum ecosystems, did:ethr is common. You'll need to integrate a verifier SDK into your backend. A basic check in a Node.js service using Veramo could involve calling agent.verifyPresentation() to validate the proof's signature and status. Your smart contract can also include a function that checks a provided verifiable presentation, ensuring only credentialed users can execute certain functions, thus embedding compliance directly into your protocol's logic.

This approach future-proofs your application for a more decentralized web. It aligns with emerging regulatory frameworks like the EU's eIDAS 2.0, which recognizes DIDs and VCs. By building with privacy-by-design principles, you reduce onboarding friction, enhance user trust, and create a more portable identity layer. The key is to start with a clear use case, partner with a compliant credential issuer, and implement the verification logic that meets your specific regulatory obligations.

prerequisites
SETTING UP A COMPLIANCE-FRIENDALY KYC INTEGRATION USING DIDS

Prerequisites and Architecture Overview

This guide outlines the technical foundation for building a KYC system that leverages Decentralized Identifiers (DIDs) and Verifiable Credentials (VCs) to enhance user privacy and data portability while meeting regulatory requirements.

Before implementing a DID-based KYC system, you need a clear understanding of its core components. The architecture relies on three primary roles: the Issuer (a regulated entity like a KYC provider), the Holder (the end-user), and the Verifier (your application). The flow is governed by open W3C standards: Decentralized Identifiers (DIDs) for user-controlled identifiers and Verifiable Credentials (VCs) for cryptographically signed attestations. You'll need to choose a DID method (e.g., did:ethr, did:key, did:web) and a VC data model compatible with your chosen blockchain or decentralized network.

The technical stack requires specific libraries and services. For development, integrate SDKs like Veramo (TypeScript/JavaScript), SpruceID's Credible (Rust/WebAssembly), or MATTR's VII for enterprise solutions. You will need access to a DID resolver to fetch DID Documents and a VC verifier to check credential proofs. For on-chain attestations, consider smart contract libraries such as EAS (Ethereum Attestation Service) or Verax. Ensure your backend can handle JSON-LD or JWT formatted credentials and manage public/private key pairs for cryptographic operations.

Key prerequisites include establishing trust with a compliant KYC Issuer. This entity must undergo its own accreditation (e.g., SOC 2, ISO 27001) and be capable of issuing VCs. You must define the credential schema, specifying the exact claims (e.g., name, dateOfBirth, accreditationLevel) and their data types. This schema, often published to a registry like the Verifiable Credentials Schema Registry, ensures interoperability. Your application's smart contracts or backend logic must be designed to request and validate only the specific, minimal claims required for compliance (data minimization), rather than storing raw user data.

Architecturally, the system decouples identity verification from application logic. The user (Holder) obtains a KYC VC from the Issuer and stores it in a digital wallet (e.g., MetaMask, SpruceID's Kepler). When interacting with your dApp, the user presents a Verifiable Presentation—a package containing the relevant VC—upon request. Your Verifier service checks the credential's cryptographic signature, issuer DID, credential status (via a revocation registry), and expiry date. A successful verification grants access without you ever storing the user's personal information, shifting the data custody and consent model.

Consider the trade-offs between different architectural patterns. A off-chain model stores only the verification result (a boolean or a hash) on-chain, keeping VCs off-chain for maximum privacy. A hybrid model might store a zero-knowledge proof (ZKP) of the KYC credential on-chain, using protocols like zk-SNARKs via Circom or SnarkJS. This proves the user is verified without revealing any underlying data. Your choice impacts gas costs, privacy guarantees, and complexity. Start by mapping your specific compliance requirements (e.g., FATF Travel Rule, AML directives) to the data points needed in the VC schema.

key-concepts
KYC & IDENTITY

Core Components

Essential tools and standards for building decentralized identity verification and compliance into Web3 applications.

03

The Trust Triangle

The core architecture pattern for credential flows involving three roles:

  • Issuer: Trusted entity (e.g., KYC provider) that signs and issues VCs.
  • Holder: User who stores VCs in their digital wallet.
  • Verifier: Application (e.g., DeFi platform) that requests and cryptographically verifies VCs. This model removes the need for verifiers to directly query centralized databases.
05

Presentation & Verification Logic

How applications request and verify credentials. This involves:

  • Presentation Request: Defining required credentials (e.g., KYCLevel >= 2).
  • Selective Disclosure: User shares only the required VC, proving claims.
  • On-chain Verification: Using a verifier smart contract to check the VC's signature and revocation status. Libraries like veramo and ethr-did-resolver simplify this process.
06

Compliance & Privacy Standards

Regulatory frameworks that shape integration design:

  • Travel Rule (FATF): Requires VASPs to share sender/receiver info; DIDs can facilitate compliant data exchange.
  • GDPR/Right to be Forgotten: Off-chain VC storage with user-controlled revocation aids compliance.
  • AML/CFT: Risk-based approaches using zero-knowledge proofs to verify jurisdiction or accreditation without exposing underlying data.
step-1-did-creation
FOUNDATION

Step 1: User DID Creation and Management

Decentralized Identifiers (DIDs) form the core of a self-sovereign, verifiable identity system. This step establishes a user-owned cryptographic identity that can be linked to KYC credentials.

A Decentralized Identifier (DID) is a globally unique, persistent identifier that does not require a centralized registry. It is typically expressed as a URI, like did:ethr:0xabc123.... The user controls their DID via a private key, enabling them to prove ownership and create Verifiable Credentials (VCs). For KYC, a user's DID becomes the anchor point to which attested credentials (e.g., proof of identity from a regulated provider) are cryptographically bound, creating a portable and privacy-preserving compliance record.

To create a DID, you must first choose a DID method, which defines the specific blockchain or network and the operations for creating, updating, and deactivating the DID. For Ethereum-based applications, did:ethr (using the Ethereum Attestation Service or similar) and did:pkh (public key hash) are common. The creation process involves generating a cryptographic key pair. The public key is used to derive the DID, while the private key is securely stored by the user, often in a wallet. Libraries like ethr-did-registry or did-jwt handle this complexity.

Here is a basic example using the ethr-did library to create and manage a DID on Ethereum:

javascript
import { EthrDID } from 'ethr-did';
import { Wallet } from 'ethers';

// 1. Generate or use an existing Ethereum wallet
const wallet = Wallet.createRandom();
const privateKey = wallet.privateKey;

// 2. Instantiate the DID controller
const ethrDid = new EthrDID({
  identifier: wallet.address,
  privateKey,
  chainNameOrId: 'sepolia', // e.g., 'mainnet', 'sepolia'
  registry: '0xdca7ef03e98e0dc2b855be647c39abe984fcf21b' // EAS registry address
});

// 3. The DID is now ready for use
console.log('User DID:', ethrDid.did); // did:ethr:sepolia:0x...

This code creates a DID controller object that can sign credentials and interact with the on-chain registry.

Effective DID management is critical for security and user experience. The private key must be safeguarded, typically delegated to a user's non-custodial wallet (e.g., MetaMask). The application should never store this key. Instead, use DID resolvers to fetch the public DID Document from the blockchain. The DID Document contains the public keys and service endpoints necessary for verification. For KYC flows, after a user's identity is verified by a provider, a Verifiable Credential attesting to their KYC status will be issued and linked to this DID, forming the basis for compliant interactions across dApps.

step-2-kyc-attestation
SETTING UP A COMPLIANCE-FRIENDLY KYC INTEGRATION USING DIDS

Step 2: Integrating a Regulated KYC Attestation Provider

This guide explains how to integrate a regulated Know Your Customer (KYC) provider into your application using Decentralized Identifiers (DIDs) and Verifiable Credentials (VCs).

A regulated KYC attestation provider, such as Persona, Veriff, or Sumsub, performs the identity verification process and issues a Verifiable Credential (VC) as proof. This VC is a cryptographically signed attestation that a user has passed specific checks, like identity document validation and liveness detection. The credential is stored in the user's digital wallet, not on your servers, shifting the data custody and liability model. Your application's smart contract or backend only needs to verify the credential's signature and check its claims, such as the user's country of residence or verification level.

The technical integration involves two main flows. First, the issuance flow: you redirect the user to the KYC provider's hosted verification flow, often via an SDK or iFrame. Upon successful verification, the provider's service (acting as an issuer) creates a VC and pushes it to the user's wallet using protocols like SIOPv2 or OpenID4VP. Second, the verification flow: when a user wants to access your gated service, your application requests the VC. Your backend or a smart contract verifies the credential's cryptographic signature against the issuer's public DID (published on a Verifiable Data Registry like the ION network) and checks that the credential's claims (e.g., credentialSubject.KYCStatus: "Approved") meet your requirements.

For developers, a typical backend verification in Node.js using the Veramo SDK might look like this:

javascript
import { createAgent } from '@veramo/core';
import { CredentialPlugin } from '@veramo/credential-w3c';
// Agent setup with DID resolver and key management
const agent = createAgent({/* ...plugins */});
// Verify the presented Verifiable Credential
const verificationResult = await agent.verifyCredential({
  credential: userPresentedCredentialJWT,
});
if (verificationResult.verified && 
    verificationResult.credentialSubject.country === 'US') {
  // Grant access
}

This code checks the JWT signature and the embedded claims without handling raw user PII.

Using DIDs for KYC provides key advantages over traditional API-based checks. It enables user-centric data portability, allowing users to reuse their KYC credential across multiple dApps without re-verification. It also creates privacy-preserving verification; you can perform zero-knowledge proofs to confirm a user is from a permitted jurisdiction without learning their exact address. Furthermore, it reduces your compliance surface area, as you are verifying attestations from a licensed entity rather than processing PII directly. Always ensure your chosen provider's attestation format (like W3C Verifiable Credentials) and trust framework (like Travel Rule compliance) align with the regulations in your target markets.

Before going live, rigorously test the integration in the provider's sandbox environment. Key test scenarios include: verifying credential parsing for different user statuses (Approved, Denied, Pending), testing the revocation check by verifying a credential whose issuer has revoked it, and simulating network timeouts during the wallet presentation step. Document the specific claim types and schemas your application depends on, as these can vary between providers. This approach future-proofs your integration, allowing you to switch KYC providers or accept credentials from multiple issuers without major code changes, as long as they adhere to the same verifiable data standards.

step-3-vc-storage-verification
DID-BASED KYC INTEGRATION

Storing and Verifying Credentials

This guide explains how to implement a secure, user-centric system for storing and verifying KYC credentials using Decentralized Identifiers (DIDs) and Verifiable Credentials (VCs).

After a user completes a KYC check with a trusted provider, the verified data is issued as a Verifiable Credential. This is a cryptographically signed attestation, such as a proof of identity or residency, that is bound to the user's Decentralized Identifier (DID). The credential is not stored on a central server but is instead held by the user in their personal digital wallet, like a MetaMask Snap or a dedicated identity wallet. This shift to user-held data is the core of self-sovereign identity (SSI), giving individuals control over their personal information.

The technical foundation for verification relies on public key cryptography. When an issuer (e.g., a KYC provider) creates a VC, they sign it with their private key. The corresponding public key is published in their DID Document on a verifiable data registry, such as the Ethereum blockchain (for did:ethr) or the ION network on Bitcoin (for did:ion). To verify a credential, your application fetches the issuer's DID Document, retrieves the public key, and cryptographically validates the signature on the VC. This process proves the credential is authentic and unaltered without needing to query the issuer's database.

For developers, integrating this involves working with libraries like did-jwt-vc or veramo. A typical verification flow in code involves three steps: resolving the issuer's DID to get their public key, verifying the JWT signature of the credential, and then checking the credential's contents (like its expiration date or credential status). Here is a simplified Node.js example using hypothetical functions:

javascript
const verifiedCredential = await verifyCredentialJWT({
  jwt: userPresentedCredentialJWT,
  resolver: didResolver // Configured to resolve DIDs (e.g., did:ethr)
});
if (verifiedCredential.verified) {
  const kycData = verifiedCredential.payload.vc.credentialSubject;
  // Proceed with application logic using `kycData.country` or `kycData.isOver18`
}

A critical design choice is determining what data to request. For compliance with regulations like Travel Rule, you may need specific, attested claims (e.g., countryOfResidence, dateOfBirth). Using selective disclosure methods, such as BBS+ signatures for Zero-Knowledge Proofs (ZKPs), a user can prove they are over 18 from their credential without revealing their exact birth date. This minimizes data exposure. Your application's policy should define the exact set of required claims and the trusted issuers (their DIDs) from which it will accept credentials.

Finally, you must decide how to handle verification results within your application's state. A common pattern is to mint a non-transferable Soulbound Token (SBT) or set a status flag in a smart contract mapped to the user's wallet address upon successful KYC verification. This on-chain record allows other parts of your dApp to permission access based on this verified status without repeating the entire credential check. This completes a compliance-friendly flow that respects user privacy, leverages decentralized infrastructure, and integrates cleanly with on-chain logic.

step-4-audit-trail
KYC INTEGRATION

Step 4: Building an Immutable Audit Trail

Integrate Decentralized Identifiers (DIDs) to create a verifiable, tamper-proof record of user verification events, essential for regulatory compliance and user sovereignty.

An immutable audit trail is a cryptographically secured log of all KYC-related events, such as credential issuance, verification requests, and consent grants. Unlike traditional databases, this log is anchored on a blockchain or decentralized network, making it resistant to tampering or retroactive alteration. This provides regulators with a single source of truth and protects businesses from disputes over user verification status. The core technology enabling this is the W3C Decentralized Identifier (DID) standard, which gives users control over their verifiable credentials.

To set this up, you first need to establish a DID method for your system. Popular choices include did:ethr for Ethereum-compatible chains or did:key for a simple, self-contained approach. Your compliance service acts as an issuer, creating DIDs for verified users. When a user completes KYC, you issue a Verifiable Credential (VC)—a signed JSON object containing the attestation (e.g., "kycStatus": "approved")—and bind it to the user's DID. This VC is stored in the user's digital wallet, not your centralized database.

The audit trail is built from verifiable data registries. When a verification event occurs, your service publishes a minimal, privacy-preserving proof—such as the hash of the VC and a timestamp—to a public ledger like Ethereum or a permissioned chain like Hyperledger Besu. This creates an immutable anchor. You can use Smart Contracts to manage consent logs. For example, a contract could record when a user's DID authorizes a third-party to access their KYC status, with each transaction generating an on-chain event.

Here is a simplified code example for issuing a Verifiable Credential using the did:ethr method and veramo SDK:

javascript
import { createAgent } from '@veramo/core';
import { CredentialIssuer } from '@veramo/credential-w3c';
// Agent setup omitted for brevity
const issuedVC = await agent.createVerifiableCredential({
  credential: {
    issuer: { id: 'did:ethr:0x123...' }, // Your Issuer DID
    credentialSubject: {
      id: userDID, // The user's DID
      kycStatus: 'approved',
      level: 'tier2',
      issuanceDate: new Date().toISOString(),
    },
  },
  proofFormat: 'jwt', // Creates a JSON Web Token proof
});
// Store the JWT string (the VC) and its hash on-chain.

For regulators to verify the trail, you provide cryptographic proofs, not raw data. They can independently verify the signature on a VC and check its hash against the on-chain anchor. This selective disclosure model is key: users can prove specific claims (e.g., "I am over 18") without revealing their full credential. Frameworks like Ethereum Attestation Service (EAS) or OpenAttestation provide standardized schemas and tools for building such systems. The result is a compliance-friendly integration that enhances trust, reduces liability, and aligns with data privacy principles by design.

DECENTRALIZED IDENTITY PROVIDERS

KYC Attestation Provider Comparison

Comparison of major providers for issuing verifiable KYC credentials on-chain.

Feature / MetricVeriteSpruceIDPolygon ID

Attestation Standard

W3C Verifiable Credentials

W3C Verifiable Credentials

Iden3 / W3C VCs

On-Chain Verification

ZK-Proof Support

Issuance Cost Per User

$2-5

$1-3

$3-7

Verification Latency

< 2 sec

< 1 sec

< 3 sec

Supported Blockchains

Ethereum, Solana, Polygon

Ethereum, Celo, NEAR

Polygon, Ethereum

Regulatory Compliance (Travel Rule)

Open Source SDK

DEVELOPER FAQ

Frequently Asked Questions

Common technical questions and solutions for integrating Decentralized Identifiers (DIDs) into KYC workflows.

A Decentralized Identifier (DID) is a cryptographically verifiable identifier controlled by the user, not a centralized database. It is defined by the W3C standard. Unlike a traditional KYC record stored in a company's private server, a DID is anchored to a public blockchain or decentralized network (like Ethereum, Polygon, or ION on Bitcoin). The core components are:

  • DID Document: A JSON-LD file containing public keys, service endpoints, and verification methods.
  • Verifiable Credentials (VCs): Tamper-proof, cryptographically signed attestations (like a KYC approval) issued to a DID.

Key Difference: Traditional KYC creates a siloed record. A DID-based system allows users to present reusable, privacy-preserving proofs (Zero-Knowledge Proofs) of their KYC status without revealing the underlying document, enabling compliance across multiple dApps without repeated submissions.

conclusion-next-steps
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have now configured a KYC integration using Decentralized Identifiers (DIDs) and Verifiable Credentials (VCs). This approach shifts the paradigm from storing sensitive data to verifying claims.

This guide demonstrated a core pattern: a user obtains a Verifiable Credential from a trusted issuer (like an accredited KYC provider) and presents it to your dApp. Your smart contract or backend verifies the credential's cryptographic proof against the issuer's public Decentralized Identifier on-chain. This process validates the user's claim (e.g., "is KYC'd") without exposing their personal data. Key components you've worked with include the did:ethr method for on-chain DIDs, the VerifiableCredential data model, and the EIP-712 standard for structured signing.

For production, consider these next steps. First, audit your credential schema. Define precisely which claims are necessary (e.g., country of residence, accreditation status) and ensure your verification logic only checks for those. Second, implement selective disclosure. Using technologies like Zero-Knowledge Proofs (ZKPs) with BBS+ signatures allows users to prove they hold a valid credential without revealing all its contents. Frameworks like Hyperledger AnonCreds or Polygon ID offer libraries for this. Third, establish a credential revocation strategy, such as checking a status list or using a smart contract as a revocation registry.

Explore advanced integrations to enhance user flow. You can use Sign-In with Ethereum (SIWE) to bundle authentication and credential presentation in a single user action. For cross-chain compatibility, consider DID methods like did:key or did:jwk for portable identities. Monitor evolving standards from the W3C Verifiable Credentials group and the Decentralized Identity Foundation (DIF). The final architecture should balance user privacy, regulatory compliance, and seamless UX, moving beyond data collection to trusted verification.

How to Build a KYC System with Decentralized Identity (DIDs) | ChainScore Guides