Government & Digital Identity Scenario
This guide demonstrates how to build a government digital identity system using TrustWeave that enables citizen identity wallets, government-issued credentials, document verification, and cross-border identity verification.
What You’ll Build
By the end of this tutorial, you’ll have:
- ✅ Created DIDs for government agencies and citizens
- ✅ Issued government credentials (driver’s license, passport, tax credentials)
- ✅ Built citizen identity wallet
- ✅ Implemented document verification system
- ✅ Created service access control
- ✅ Enabled cross-border identity verification
- ✅ Anchored critical identity documents to blockchain
Big Picture & Significance
The Digital Government Transformation
Governments worldwide are digitizing citizen services, but face challenges with identity verification, document authenticity, and cross-border recognition. Digital identity systems built on DIDs and VCs provide a foundation for secure, privacy-preserving government services.
Industry Context:
- Market Size: Global digital identity solutions market projected to reach $49.5 billion by 2026
- Government Initiatives: Over 100 countries implementing national digital identity programs
- Regulatory Drivers: eIDAS in EU, NIST guidelines in US, Aadhaar in India
- Citizen Demand: 73% of citizens want digital government services
- Cost Savings: Digital identity can reduce government service costs by 30-50%
Why This Matters:
- Citizen Convenience: Access government services from anywhere
- Fraud Prevention: Cryptographic proof prevents document forgery
- Privacy: Citizens control what identity information is shared
- Interoperability: Works across different government agencies
- Cross-Border: Enables international identity verification
- Cost Reduction: Reduces administrative costs significantly
The Government Identity Challenge
Traditional government identity systems face critical issues:
- Document Forgery: Paper documents can be easily forged
- Siloed Systems: Different agencies can’t verify each other’s documents
- Privacy Concerns: Centralized databases create privacy risks
- Cross-Border Issues: International verification is complex
- Citizen Burden: Multiple identity documents for different services
- Cost: High costs for document issuance and verification
Value Proposition
Problems Solved
- Document Authenticity: Cryptographic proof prevents forgery
- Citizen Control: Citizens own and control their identity credentials
- Interoperability: Standard format works across all government agencies
- Privacy: Selective disclosure protects citizen privacy
- Cross-Border: Enables international identity verification
- Efficiency: Instant verification without manual checks
- Cost Reduction: Reduces document issuance and verification costs
- Fraud Prevention: Tamper-proof credentials prevent identity theft
Business Benefits
For Government Agencies:
- Cost Savings: 40-60% reduction in document issuance costs
- Fraud Reduction: 80% reduction in document forgery
- Efficiency: 10x faster identity verification
- Interoperability: Seamless data sharing across agencies
- Compliance: Meets eIDAS and other regulatory requirements
For Citizens:
- Convenience: Access services from any device
- Privacy: Control what information is shared
- Portability: Identity credentials work across agencies
- Security: Reduced risk of identity theft
- Speed: Faster service access
For Service Providers:
- Trust: Verifiable government-issued credentials
- Efficiency: Instant identity verification
- Compliance: Meets KYC/AML requirements
- Cost: Reduced verification costs
ROI Considerations
- Document Issuance: 50% cost reduction
- Verification: 90% faster verification process
- Fraud Prevention: Saves millions in prevented fraud
- Citizen Satisfaction: Improved service delivery
- Innovation: Enables new digital services
Understanding the Problem
Government identity management faces several critical challenges:
- Document Security: Paper documents can be forged or tampered with
- Siloed Systems: Different agencies maintain separate identity systems
- Privacy: Centralized databases create privacy and security risks
- Cross-Border: International identity verification is complex
- Citizen Burden: Multiple documents for different services
- Cost: High costs for document issuance and verification
- Fraud: Identity theft and document forgery
Real-World Pain Points
Example 1: Driver’s License Verification
- Current: Manual verification, paper documents, easy to forge
- Problem: Fraud, slow verification, no digital access
- Solution: Verifiable digital driver’s license with instant verification
Example 2: Passport Verification
- Current: Physical passport, manual border checks
- Problem: Slow border processing, document forgery
- Solution: Digital passport credential with instant verification
Example 3: Tax Credentials
- Current: Multiple documents for tax filing
- Problem: Complex, time-consuming, privacy concerns
- Solution: Verifiable tax credentials with selective disclosure
How It Works: Government Identity Flow
flowchart TD
A["Government Agency<br/>Creates Agency DID<br/>Issues Identity Credentials<br/>Manages Citizen Registry"] -->|issues credentials| B["Government Credentials<br/>Driver's License<br/>Passport<br/>Tax Credential<br/>Proof cryptographic"]
B -->|stored in citizen wallet| C["Citizen Identity Wallet<br/>Stores all government credentials<br/>Manages identity<br/>Creates presentations"]
C -->|presents for service access| D["Government Service<br/>Verifies credentials<br/>Grants access<br/>Logs access"]
style A fill:#1976d2,stroke:#0d47a1,stroke-width:2px,color:#fff
style B fill:#f57c00,stroke:#e65100,stroke-width:2px,color:#fff
style C fill:#388e3c,stroke:#1b5e20,stroke-width:2px,color:#fff
style D fill:#c2185b,stroke:#880e4f,stroke-width:2px,color:#fff
Key Concepts
Government Credential Types
- Driver’s License Credential: Driving privileges, vehicle classes, expiration
- Passport Credential: Citizenship, travel authorization, biometric data
- Tax Credential: Tax identification, filing status, authorization
- Voting Credential: Eligibility to vote, registration status
- Social Benefits Credential: Eligibility for government benefits
- Professional License Credential: Professional certifications and licenses
Citizen Identity Wallet
- Self-Sovereign: Citizen owns and controls identity
- Multi-Credential: Stores credentials from multiple agencies
- Selective Disclosure: Share only necessary information
- Privacy: Control what information is shared
- Portability: Works across all government services
Trust Anchors
- Government DIDs: Trusted government agency identities
- Verification: Cryptographic proof of government issuance
- Revocation: Government can revoke credentials
- Audit Trail: Immutable records of credential issuance
Prerequisites
- Java 21+
- Kotlin 2.2.0+
- Gradle 8.5+
- Basic understanding of Kotlin and coroutines
- Familiarity with government identity concepts (helpful but not required)
Step 1: Add Dependencies
Add TrustWeave dependencies to your build.gradle.kts. These modules provide DID creation, credential issuance, wallet management, and the in-memory services used in this government scenario.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dependencies {
// Core TrustWeave modules
implementation("com.trustweave:trustweave-core:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-json:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-kms:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-did:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-anchor:1.0.0-SNAPSHOT")
// Test kit for in-memory implementations
implementation("com.trustweave:trustweave-testkit:1.0.0-SNAPSHOT")
// Kotlinx Serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}
Result: After syncing, you can run the walkthrough without wiring additional adapters.
Step 2: Complete Example
Here’s the full government digital identity workflow. Run it once to see every step—from agency issuance to citizen presentation—before diving into the detailed breakdowns.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
import com.trustweave.credential.models.VerifiableCredential
import com.trustweave.credential.models.VerifiablePresentation
import com.trustweave.credential.CredentialIssuanceOptions
import com.trustweave.credential.CredentialVerificationOptions
import com.trustweave.credential.PresentationOptions
import com.trustweave.credential.issuer.CredentialIssuer
import com.trustweave.credential.verifier.CredentialVerifier
import com.trustweave.credential.proof.Ed25519ProofGenerator
import com.trustweave.credential.proof.ProofGeneratorRegistry
import com.trustweave.testkit.credential.InMemoryWallet
import com.trustweave.testkit.did.DidKeyMockMethod
import com.trustweave.testkit.kms.InMemoryKeyManagementService
import com.trustweave.testkit.anchor.InMemoryBlockchainAnchorClient
import com.trustweave.anchor.BlockchainAnchorRegistry
import com.trustweave.anchor.anchorTyped
import com.trustweave.did.DidMethodRegistry
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import kotlinx.serialization.json.Json
import java.time.Instant
import java.time.temporal.ChronoUnit
@Serializable
data class IdentityDocument(
val documentType: String,
val documentNumber: String,
val citizenDid: String,
val issuerDid: String,
val credentialDigest: String
)
fun main() = runBlocking {
println("=== Government & Digital Identity Scenario ===\n")
// Step 1: Setup services
println("Step 1: Setting up services...")
val dmvKms = InMemoryKeyManagementService() // Department of Motor Vehicles
val passportOfficeKms = InMemoryKeyManagementService()
val taxAuthorityKms = InMemoryKeyManagementService()
val citizenKms = InMemoryKeyManagementService()
val didMethod = DidKeyMockMethod(dmvKms)
val didRegistry = DidMethodRegistry().apply { register(didMethod) }
// Setup blockchain for anchoring
val anchorClient = InMemoryBlockchainAnchorClient("eip155:1", emptyMap())
val blockchainRegistry = BlockchainAnchorRegistry().apply {
register("eip155:1", anchorClient)
}
// Step 2: Create government agency DIDs
println("\nStep 2: Creating government agency DIDs...")
val dmvDid = didMethod.createDid()
println("DMV DID: ${dmvDid.id}")
val passportOfficeDid = didMethod.createDid()
println("Passport Office DID: ${passportOfficeDid.id}")
val taxAuthorityDid = didMethod.createDid()
println("Tax Authority DID: ${taxAuthorityDid.id}")
// Step 3: Create citizen DID
println("\nStep 3: Creating citizen DID...")
val citizenDid = didMethod.createDid()
println("Citizen DID: ${citizenDid.id}")
// Step 4: Create citizen identity wallet
println("\nStep 4: Creating citizen identity wallet...")
val citizenWallet = InMemoryWallet(
walletDid = citizenDid.id,
holderDid = citizenDid.id
)
println("Citizen wallet created: ${citizenWallet.walletId}")
// Step 5: Issue driver's license credential
println("\nStep 5: Issuing driver's license credential...")
val driversLicenseCredential = createDriversLicenseCredential(
citizenDid = citizenDid.id,
issuerDid = dmvDid.id,
licenseNumber = "DL123456789",
fullName = "John Doe",
dateOfBirth = "1985-06-15",
address = "123 Main St, City, State 12345",
vehicleClasses = listOf("Class C", "Class M"),
expirationDate = "2028-06-15"
)
val dmvKey = dmvKms.generateKey("Ed25519")
val dmvProofGenerator = Ed25519ProofGenerator(
signer = { data, keyId -> dmvKms.sign(keyId, data) },
getPublicKeyId = { keyId -> dmvKey.id }
)
val dmvProofRegistry = ProofGeneratorRegistry().apply { register(dmvProofGenerator) }
val dmvIssuer = CredentialIssuer(
proofGenerator = dmvProofGenerator,
resolveDid = { did -> didRegistry.resolve(did) != null },
proofRegistry = dmvProofRegistry
)
val issuedDriversLicense = dmvIssuer.issue(
credential = driversLicenseCredential,
issuerDid = dmvDid.id,
keyId = dmvKey.id,
options = CredentialIssuanceOptions(proofType = "Ed25519Signature2020")
)
println("Driver's license credential issued:")
println(" - License Number: DL123456789")
println(" - Name: John Doe")
println(" - Expiration: 2028-06-15")
// Step 6: Issue passport credential
println("\nStep 6: Issuing passport credential...")
val passportCredential = createPassportCredential(
citizenDid = citizenDid.id,
issuerDid = passportOfficeDid.id,
passportNumber = "P987654321",
fullName = "John Doe",
dateOfBirth = "1985-06-15",
nationality = "US",
placeOfBirth = "New York, USA",
issueDate = "2023-01-01",
expirationDate = "2033-01-01"
)
val passportKey = passportOfficeKms.generateKey("Ed25519")
val passportProofGenerator = Ed25519ProofGenerator(
signer = { data, keyId -> passportOfficeKms.sign(keyId, data) },
getPublicKeyId = { keyId -> passportKey.id }
)
val passportProofRegistry = ProofGeneratorRegistry().apply { register(passportProofGenerator) }
val passportIssuer = CredentialIssuer(
proofGenerator = passportProofGenerator,
resolveDid = { did -> didRegistry.resolve(did) != null },
proofRegistry = passportProofRegistry
)
val issuedPassport = passportIssuer.issue(
credential = passportCredential,
issuerDid = passportOfficeDid.id,
keyId = passportKey.id,
options = CredentialIssuanceOptions(proofType = "Ed25519Signature2020")
)
println("Passport credential issued")
// Step 7: Issue tax credential
println("\nStep 7: Issuing tax credential...")
val taxCredential = createTaxCredential(
citizenDid = citizenDid.id,
issuerDid = taxAuthorityDid.id,
taxId = "123-45-6789",
fullName = "John Doe",
filingStatus = "Single",
authorizationLevel = "Full"
)
val taxKey = taxAuthorityKms.generateKey("Ed25519")
val taxProofGenerator = Ed25519ProofGenerator(
signer = { data, keyId -> taxAuthorityKms.sign(keyId, data) },
getPublicKeyId = { keyId -> taxKey.id }
)
val taxProofRegistry = ProofGeneratorRegistry().apply { register(taxProofGenerator) }
val taxIssuer = CredentialIssuer(
proofGenerator = taxProofGenerator,
resolveDid = { did -> didRegistry.resolve(did) != null },
proofRegistry = taxProofRegistry
)
val issuedTaxCredential = taxIssuer.issue(
credential = taxCredential,
issuerDid = taxAuthorityDid.id,
keyId = taxKey.id,
options = CredentialIssuanceOptions(proofType = "Ed25519Signature2020")
)
println("Tax credential issued")
// Step 8: Store credentials in citizen wallet
println("\nStep 8: Storing credentials in citizen wallet...")
val driversLicenseId = citizenWallet.store(issuedDriversLicense)
val passportId = citizenWallet.store(issuedPassport)
val taxCredentialId = citizenWallet.store(issuedTaxCredential)
println("Stored ${citizenWallet.list().size} government credentials")
// Step 9: Organize credentials
println("\nStep 9: Organizing credentials...")
val identityCollection = citizenWallet.createCollection(
name = "Government Identity",
description = "Government-issued identity credentials"
)
citizenWallet.addToCollection(driversLicenseId, identityCollection)
citizenWallet.addToCollection(passportId, identityCollection)
citizenWallet.addToCollection(taxCredentialId, identityCollection)
citizenWallet.tagCredential(driversLicenseId, setOf("driving", "license", "dmv"))
citizenWallet.tagCredential(passportId, setOf("travel", "passport", "citizenship"))
citizenWallet.tagCredential(taxCredentialId, setOf("tax", "irs", "financial"))
println("Created identity collection")
// Step 10: Verify credentials
println("\nStep 10: Verifying government credentials...")
val verifier = CredentialVerifier(
didResolver = CredentialDidResolver { did ->
didRegistry.resolve(did).toCredentialDidResolution()
}
)
val licenseVerification = verifier.verify(
credential = issuedDriversLicense,
options = CredentialVerificationOptions(
checkRevocation = true,
checkExpiration = true,
validateSchema = true
)
)
if (licenseVerification.valid) {
println("✅ Driver's license credential is valid!")
println(" - Proof valid: ${licenseVerification.proofValid}")
println(" - Issuer valid: ${licenseVerification.issuerValid}")
println(" - Not expired: ${licenseVerification.notExpired}")
}
// Step 11: Create service access presentation
println("\nStep 11: Creating service access presentation...")
// Citizen needs to access government service, presents driver's license
val servicePresentation = citizenWallet.createPresentation(
credentialIds = listOf(driversLicenseId),
holderDid = citizenDid.id,
options = PresentationOptions(
holderDid = citizenDid.id,
proofType = "Ed25519Signature2020",
challenge = "government-service-${Instant.now().toEpochMilli()}"
)
)
println("Service access presentation created")
// Step 12: Anchor identity documents to blockchain
println("\nStep 12: Anchoring identity documents to blockchain...")
val licenseDigest = com.trustweave.json.DigestUtils.sha256DigestMultibase(
Json.encodeToJsonElement(
com.trustweave.credential.models.VerifiableCredential.serializer(),
issuedDriversLicense
)
)
val identityDoc = IdentityDocument(
documentType = "drivers-license",
documentNumber = "DL123456789",
citizenDid = citizenDid.id,
issuerDid = dmvDid.id,
credentialDigest = licenseDigest
)
val anchorResult = blockchainRegistry.anchorTyped(
value = identityDoc,
serializer = IdentityDocument.serializer(),
targetChainId = "eip155:1"
)
println("Identity document anchored:")
println(" - Transaction hash: ${anchorResult.ref.txHash}")
println(" - Provides immutable record")
// Step 13: Cross-border verification
println("\nStep 13: Cross-border identity verification...")
val canVerifyCrossBorder = verifyCrossBorderIdentity(
passportCredential = issuedPassport,
verifyingCountryDid = "did:example:border-control"
)
println("Cross-border verification: ${if (canVerifyCrossBorder) "Possible" else "Not possible"}")
println("\n=== Scenario Complete ===")
}
fun createDriversLicenseCredential(
citizenDid: String,
issuerDid: String,
licenseNumber: String,
fullName: String,
dateOfBirth: String,
address: String,
vehicleClasses: List<String>,
expirationDate: String
): VerifiableCredential {
return VerifiableCredential(
id = "https://dmv.example.com/licenses/$licenseNumber",
type = listOf("VerifiableCredential", "DriversLicenseCredential", "GovernmentCredential"),
issuer = issuerDid,
credentialSubject = buildJsonObject {
put("id", citizenDid)
put("driversLicense", buildJsonObject {
put("licenseNumber", licenseNumber)
put("fullName", fullName)
put("dateOfBirth", dateOfBirth)
put("address", address)
put("vehicleClasses", vehicleClasses)
put("issueDate", Instant.now().toString())
put("expirationDate", expirationDate)
})
},
issuanceDate = Instant.now().toString(),
expirationDate = expirationDate,
credentialSchema = com.trustweave.credential.models.CredentialSchema(
id = "https://example.com/schemas/drivers-license.json",
type = "JsonSchemaValidator2018",
schemaFormat = com.trustweave.spi.SchemaFormat.JSON_SCHEMA
)
)
}
fun createPassportCredential(
citizenDid: String,
issuerDid: String,
passportNumber: String,
fullName: String,
dateOfBirth: String,
nationality: String,
placeOfBirth: String,
issueDate: String,
expirationDate: String
): VerifiableCredential {
return VerifiableCredential(
id = "https://passport.example.com/passports/$passportNumber",
type = listOf("VerifiableCredential", "PassportCredential", "GovernmentCredential"),
issuer = issuerDid,
credentialSubject = buildJsonObject {
put("id", citizenDid)
put("passport", buildJsonObject {
put("passportNumber", passportNumber)
put("fullName", fullName)
put("dateOfBirth", dateOfBirth)
put("nationality", nationality)
put("placeOfBirth", placeOfBirth)
put("issueDate", issueDate)
put("expirationDate", expirationDate)
})
},
issuanceDate = issueDate,
expirationDate = expirationDate,
credentialSchema = com.trustweave.credential.models.CredentialSchema(
id = "https://example.com/schemas/passport.json",
type = "JsonSchemaValidator2018",
schemaFormat = com.trustweave.spi.SchemaFormat.JSON_SCHEMA
)
)
}
fun createTaxCredential(
citizenDid: String,
issuerDid: String,
taxId: String,
fullName: String,
filingStatus: String,
authorizationLevel: String
): VerifiableCredential {
return VerifiableCredential(
id = "https://tax.example.com/credentials/$taxId",
type = listOf("VerifiableCredential", "TaxCredential", "GovernmentCredential"),
issuer = issuerDid,
credentialSubject = buildJsonObject {
put("id", citizenDid)
put("taxCredential", buildJsonObject {
put("taxId", taxId)
put("fullName", fullName)
put("filingStatus", filingStatus)
put("authorizationLevel", authorizationLevel)
put("issueDate", Instant.now().toString())
})
},
issuanceDate = Instant.now().toString(),
expirationDate = null, // Tax credentials typically don't expire
credentialSchema = com.trustweave.credential.models.CredentialSchema(
id = "https://example.com/schemas/tax-credential.json",
type = "JsonSchemaValidator2018",
schemaFormat = com.trustweave.spi.SchemaFormat.JSON_SCHEMA
)
)
}
fun verifyCrossBorderIdentity(
passportCredential: VerifiableCredential,
verifyingCountryDid: String
): Boolean {
// Verify passport credential is valid
val verifier = CredentialVerifier(
didResolver = CredentialDidResolver { did ->
didRegistry.resolve(did).toCredentialDidResolution()
}
)
val verification = verifier.verify(
credential = passportCredential,
options = CredentialVerificationOptions(
checkRevocation = true,
checkExpiration = true
)
)
if (!verification.valid) return false
// Check if passport is from recognized issuing country
val issuerDid = passportCredential.issuer
// In production, check against list of trusted country DIDs
return true // Simplified for example
}
Extensive Step-by-Step Breakdown
Step 1: Setup and Initialization
Purpose: Initialize government identity system with proper key management for multiple agencies.
Detailed Explanation:
- Multiple Agency KMS: Separate key management for DMV, passport office, tax authority ensures proper separation
- Citizen KMS: Separate key management for citizen ensures citizen control
- DID Method Registration: Register DID method for creating identities
- Blockchain Setup: Initialize blockchain for anchoring critical identity documents
Why This Matters: Government identity requires the highest security standards. Multiple KMS instances ensure proper key isolation and security.
Step 2: Create Government Agency DIDs
Purpose: Establish verifiable identities for government agencies.
Detailed Explanation:
- DMV DID: Department of Motor Vehicles identity for issuing driver’s licenses
- Passport Office DID: Passport office identity for issuing passports
- Tax Authority DID: Tax authority identity for tax credentials
Key Considerations:
- Government DIDs serve as trust anchors
- Must be well-known and resolvable
- Cryptographic proof of government authority
- Can be verified by citizens and other agencies
Step 3: Create Citizen DID
Purpose: Establish citizen’s self-sovereign identity.
Detailed Explanation:
- Citizen DID provides persistent identity
- Not tied to any specific government system
- Works across all government services
- Citizen controls the DID
Benefits:
- Single identity across all services
- Not dependent on any single agency
- Portable across jurisdictions
- Privacy-preserving
Step 4: Create Citizen Identity Wallet
Purpose: Provide secure storage for citizen’s government credentials.
Detailed Explanation:
- Stores all government-issued credentials
- Provides organization capabilities
- Enables selective disclosure
- Citizen controls access
Privacy Benefits:
- Citizen owns their identity data
- Can control what information is shared
- Selective disclosure minimizes data exposure
- Audit trail of credential usage
Step 5: Issue Driver’s License Credential
Purpose: Create verifiable driver’s license credential.
Detailed Explanation:
- License Data: License number, name, DOB, address, vehicle classes
- Credential Structure: Follows W3C VC standard
- Proof Generation: Cryptographic signature from DMV
- Expiration: License expires on specified date
Security Features:
- Tamper-proof cryptographic proof
- Verifiable issuer (DMV)
- Expiration prevents misuse
- Can be revoked if license is suspended
Step 6: Issue Passport Credential
Purpose: Create verifiable passport credential.
Detailed Explanation:
- Passport Data: Passport number, name, DOB, nationality, place of birth
- Travel Authorization: Proves citizenship and travel eligibility
- Expiration: Passport expires on specified date
- Cross-Border: Can be verified internationally
Use Cases:
- Border control verification
- International travel
- Identity verification abroad
- Citizenship proof
Step 7: Issue Tax Credential
Purpose: Create verifiable tax credential.
Detailed Explanation:
- Tax Information: Tax ID, name, filing status
- Authorization Level: Level of tax authority access
- No Expiration: Tax credentials typically don’t expire
- Service Access: Enables tax service access
Use Cases:
- Tax filing
- Tax service access
- Financial service KYC
- Government benefit applications
Step 8: Store Credentials in Citizen Wallet
Purpose: Enable citizen to manage their identity credentials.
Detailed Explanation:
- Store all government credentials in one place
- Citizen has full control
- Can organize and query credentials
- Enables selective sharing
Citizen Benefits:
- Single source of truth for identity
- Easy access from any device
- Can share with any service provider
- Complete identity history
Step 9: Organize Credentials
Purpose: Enable efficient credential management.
Detailed Explanation:
- Collections: Group related credentials
- Tags: Add metadata for easy searching
- Organization Benefits: Quick access to specific credential types
Real-World Value:
- Quick access to driver’s license
- Find passport for travel
- Organize by service type
- Track credential expiration
Step 10: Verify Government Credentials
Purpose: Ensure government credentials are valid before use.
Detailed Explanation:
- Proof Verification: Verify cryptographic signature
- Issuer Verification: Verify government agency DID
- Expiration Check: Ensure credential hasn’t expired
- Revocation Check: Verify credential hasn’t been revoked
- Schema Validation: Validate credential structure
Security Importance:
- Prevents use of tampered credentials
- Ensures credentials from trusted agencies
- Prevents use of expired credentials
- Maintains data integrity
Step 11: Create Service Access Presentation
Purpose: Enable citizen to access government services.
Detailed Explanation:
- Credential Selection: Select appropriate credential for service
- Presentation Creation: Create verifiable presentation
- Service Access: Present to government service
- Verification: Service verifies credential
Use Cases:
- Access government portal
- Apply for benefits
- File taxes
- Renew licenses
Step 12: Anchor Identity Documents to Blockchain
Purpose: Create immutable record of identity document issuance.
Detailed Explanation:
- Document Record: Create structured record of identity document
- Blockchain Anchoring: Anchor to blockchain for immutability
- Audit Trail: Provides permanent record
- Non-Repudiation: Government cannot deny issuance
Benefits:
- Immutable record
- Timestamped issuance
- Cannot be tampered with
- Meets regulatory requirements
Step 13: Cross-Border Verification
Purpose: Enable international identity verification.
Detailed Explanation:
- Passport Verification: Verify passport credential
- Issuer Recognition: Check if issuing country is recognized
- Credential Validity: Verify credential is valid
- Cross-Border Access: Grant access based on verification
Use Cases:
- Border control
- International travel
- Cross-border services
- International identity verification
Advanced Features
Multi-Agency Credential Aggregation
Aggregate credentials from multiple agencies:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fun aggregateGovernmentCredentials(
citizenWallet: Wallet
): VerifiablePresentation {
val allCredentials = citizenWallet.list()
val governmentCredentials = allCredentials.filter {
it.type.contains("GovernmentCredential")
}
return citizenWallet.createPresentation(
credentialIds = governmentCredentials.mapNotNull { it.id },
holderDid = citizenWallet.holderDid!!,
options = PresentationOptions(
holderDid = citizenWallet.holderDid!!,
proofType = "Ed25519Signature2020"
)
)
}
Selective Identity Disclosure
Share only necessary identity information:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fun createSelectiveIdentityPresentation(
citizenWallet: Wallet,
serviceType: String
): VerifiablePresentation {
return when (serviceType) {
"age-verification" -> {
// Share only age, not full identity
citizenWallet.createSelectiveDisclosure(
credentialIds = listOf("drivers-license-id"),
disclosedFields = listOf("driversLicense.dateOfBirth"),
holderDid = citizenWallet.holderDid!!,
options = PresentationOptions(...)
)
}
"address-verification" -> {
// Share only address
citizenWallet.createSelectiveDisclosure(
credentialIds = listOf("drivers-license-id"),
disclosedFields = listOf("driversLicense.address"),
holderDid = citizenWallet.holderDid!!,
options = PresentationOptions(...)
)
}
else -> {
// Full identity presentation
citizenWallet.createPresentation(...)
}
}
}
Credential Renewal
Renew expired credentials:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fun renewDriversLicense(
oldCredential: VerifiableCredential,
newExpirationDate: String,
issuerDid: String,
issuer: CredentialIssuer
): VerifiableCredential {
// Create new credential based on old one
val renewalCredential = oldCredential.copy(
expirationDate = newExpirationDate,
issuanceDate = Instant.now().toString()
)
// Issue new credential
return issuer.issue(
credential = renewalCredential,
issuerDid = issuerDid,
keyId = "issuer-key",
options = CredentialIssuanceOptions(proofType = "Ed25519Signature2020")
)
}
Real-World Use Cases
1. Digital Driver’s License
Scenario: Citizen uses digital driver’s license for age verification at store.
Implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fun verifyAgeWithDriversLicense(
citizenWallet: Wallet,
minimumAge: Int
): Boolean {
val license = citizenWallet.query {
byType("DriversLicenseCredential")
valid()
}.firstOrNull() ?: return false
val dateOfBirth = license.credentialSubject.jsonObject["driversLicense"]?.jsonObject
?.get("dateOfBirth")?.jsonPrimitive?.content
?: return false
val age = java.time.Period.between(
java.time.LocalDate.parse(dateOfBirth),
java.time.LocalDate.now()
).years
return age >= minimumAge
}
2. Passport Verification at Border
Scenario: Border control verifies passport credential.
Implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
fun verifyPassportAtBorder(
passportCredential: VerifiableCredential,
borderControlDid: String
): BorderVerificationResult {
val verifier = CredentialVerifier(
didResolver = CredentialDidResolver { did ->
didRegistry.resolve(did).toCredentialDidResolution()
}
)
val verification = verifier.verify(
credential = passportCredential,
options = CredentialVerificationOptions(
checkRevocation = true,
checkExpiration = true,
validateSchema = true
)
)
if (!verification.valid) {
return BorderVerificationResult(
authorized = false,
reason = verification.errors.joinToString()
)
}
// Check if passport is from recognized country
val nationality = passportCredential.credentialSubject.jsonObject["passport"]?.jsonObject
?.get("nationality")?.jsonPrimitive?.content
return BorderVerificationResult(
authorized = true,
nationality = nationality,
expirationDate = passportCredential.expirationDate
)
}
data class BorderVerificationResult(
val authorized: Boolean,
val reason: String? = null,
val nationality: String? = null,
val expirationDate: String? = null
)
3. Tax Filing
Scenario: Citizen files taxes using tax credential.
Implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fun fileTaxesWithCredential(
citizenWallet: Wallet,
taxAuthorityDid: String,
taxData: TaxFilingData
): VerifiablePresentation {
val taxCredential = citizenWallet.query {
byType("TaxCredential")
valid()
}.firstOrNull() ?: throw IllegalArgumentException("No valid tax credential")
// Create presentation with tax credential
return citizenWallet.createPresentation(
credentialIds = listOfNotNull(taxCredential.id),
holderDid = citizenWallet.holderDid!!,
options = PresentationOptions(
holderDid = citizenWallet.holderDid!!,
proofType = "Ed25519Signature2020",
challenge = "tax-filing-${Instant.now().toEpochMilli()}"
)
)
}
data class TaxFilingData(
val income: Double,
val deductions: Double,
val taxYear: String
)
Benefits
- Document Authenticity: Cryptographic proof prevents forgery
- Citizen Control: Citizens own and control their identity
- Interoperability: Standard format works across all agencies
- Privacy: Selective disclosure protects citizen privacy
- Cross-Border: Enables international verification
- Efficiency: Instant verification without manual checks
- Cost Reduction: Reduces document issuance costs
- Fraud Prevention: Tamper-proof credentials prevent identity theft
- Convenience: Access services from any device
- Security: Reduced risk of identity theft
Best Practices
- Trust Anchors: Use well-known government DIDs as trust anchors
- Expiration Management: Set appropriate expiration dates
- Revocation: Enable credential revocation
- Selective Disclosure: Always use selective disclosure when possible
- Audit Logging: Log all credential usage
- Schema Validation: Validate credential structure
- Key Management: Use secure key storage
- Error Handling: Handle verification failures gracefully
- Citizen Education: Educate citizens on credential management
- Interoperability: Follow standard credential formats
Next Steps
- Learn about Wallet API Tutorial
- Explore Healthcare & Medical Records Scenario for related privacy-preserving credentials
- Check out Financial Services & KYC Scenario for identity verification
- Review Core Concepts: DIDs for identity management
- Study Core Concepts: Verifiable Credentials for credential details