Skip to content

DID Management

Decentralized Identifiers (DIDs) are the foundation of self-sovereign identity in KryptoOS. This guide covers everything you need to know about managing DIDs.

What are DIDs?

A Decentralized Identifier (DID) is a globally unique identifier that enables verifiable, decentralized digital identity. DIDs are:

  • Self-sovereign: You own and control them completely
  • Persistent: Independent of any centralized authority
  • Resolvable: Can be looked up to retrieve associated information
  • Cryptographically verifiable: Secured by public-key cryptography
  • W3C compliant: Following the W3C DID Core 1.0 specification

DID Format

KryptoOS uses the did:emp method:

did:emp:1234abcd5678efgh9012ijkl
│   │   └─────────────┬─────────────┘
│   │                 │
│   │                 └─ Unique identifier
│   └─ Method (emp = Empoorio)
└─ DID scheme

Creating a DID

Basic DID Creation

typescript
import { SSIClient } from '@empoorio/ssi-sdk';

const client = new SSIClient({
  nodeUrl: 'wss://ws.empooriochain.org'
});

// Create a new DID
const did = await client.did.register({
  method: 'Ed25519VerificationKey2020',
  controller: walletAddress
});

console.log('DID created:', did.id);
console.log('DID Document:', did.document);

Advanced DID Creation with Services

You can add service endpoints to your DID for communication and discovery:

typescript
const did = await client.did.register({
  method: 'Ed25519VerificationKey2020',
  controller: walletAddress,
  services: [
    {
      id: '#didcomm-1',
      type: 'DIDCommMessaging',
      serviceEndpoint: 'https://messaging.example.com'
    },
    {
      id: '#profile-1',
      type: 'ProfileService',
      serviceEndpoint: 'https://profile.example.com/user/123'
    }
  ]
});

DID Documents

A DID Document contains the public keys, authentication methods, and service endpoints associated with a DID.

Structure

json
{
  "id": "did:emp:1234abcd",
  "controller": ["did:emp:1234abcd"],
  "verificationMethod": [
    {
      "id": "did:emp:1234abcd#keys-1",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:emp:1234abcd",
      "publicKeyMultibase": "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
    }
  ],
  "authentication": ["did:emp:1234abcd#keys-1"],
  "assertionMethod": ["did:emp:1234abcd#keys-1"],
  "keyAgreement": ["did:emp:1234abcd#keys-1"],
  "capabilityInvocation": ["did:emp:1234abcd#keys-1"],
  "service": [
    {
      "id": "#didcomm-1",
      "type": "DIDCommMessaging",
      "serviceEndpoint": "https://messaging.emp"
    }
  ]
}

Verification Relationships

  • authentication: Keys used to authenticate as the DID subject
  • assertionMethod: Keys used to issue verifiable credentials
  • keyAgreement: Keys used for encryption (e.g., DIDComm)
  • capabilityInvocation: Keys used to invoke capabilities
  • capabilityDelegation: Keys used to delegate capabilities

Resolving DIDs

Retrieve a DID Document from the blockchain:

typescript
const didDocument = await client.did.resolve('did:emp:1234abcd');

console.log('Controller:', didDocument.controller);
console.log('Verification Methods:', didDocument.verificationMethod);
console.log('Services:', didDocument.service);

Updating DID Documents

Adding Verification Methods

Add new cryptographic keys to your DID:

typescript
await client.did.addVerificationMethod({
  did: 'did:emp:1234abcd',
  verificationMethod: {
    id: 'did:emp:1234abcd#keys-2',
    type: 'EcdsaSecp256k1VerificationKey2019',
    controller: 'did:emp:1234abcd',
    publicKeyMultibase: 'zQ3s...'
  },
  purposes: ['authentication', 'assertionMethod']
});

Adding Services

Add service endpoints for communication:

typescript
await client.did.addService({
  did: 'did:emp:1234abcd',
  service: {
    id: '#api-1',
    type: 'APIService',
    serviceEndpoint: 'https://api.example.com/v1'
  }
});

Updating the Entire Document

typescript
const updatedDoc = await client.did.update({
  did: 'did:emp:1234abcd',
  document: {
    // Updated DID Document
    verificationMethod: [...],
    service: [...],
    // ... other fields
  }
});

Key Rotation

Rotating cryptographic keys is essential for security. KryptoOS supports seamless key rotation:

Step 1: Add New Key

typescript
// Add new verification method
await client.did.addVerificationMethod({
  did: 'did:emp:1234abcd',
  verificationMethod: newKey,
  purposes: ['authentication', 'assertionMethod']
});

Step 2: Update Applications

Update all applications and services to use the new key.

Step 3: Remove Old Key

typescript
// Remove old verification method after grace period
await client.did.removeVerificationMethod({
  did: 'did:emp:1234abcd',
  verificationMethodId: 'did:emp:1234abcd#keys-1'
});

Best Practices

  • Grace Period: Keep old keys active for 30-90 days
  • Notifications: Notify relying parties about key rotation
  • Backup: Securely backup new keys before removing old ones
  • Regular Rotation: Rotate keys annually or after suspected compromise

Deactivating DIDs

Permanently deactivate a DID when it's no longer needed:

typescript
await client.did.deactivate('did:emp:1234abcd');

Important

Deactivation is permanent and irreversible. The DID cannot be reactivated or reused.

When to Deactivate

  • Account closure
  • Security compromise (after creating a new DID)
  • Organizational restructuring
  • End of service

DID Controllers

DIDs can have multiple controllers for shared management:

typescript
const did = await client.did.register({
  method: 'Ed25519VerificationKey2020',
  controller: [
    'did:emp:user-123',      // Primary controller
    'did:emp:backup-456',    // Backup controller
    'did:emp:guardian-789'   // Guardian for recovery
  ]
});

Use Cases for Multiple Controllers

  • Corporate accounts: Multiple executives control company DID
  • Recovery: Trusted guardians can help recover access
  • Delegation: Temporary delegation to service providers
  • Multi-sig: Require multiple signatures for critical operations

Pairwise DIDs

Create unique DIDs for each relationship to enhance privacy:

typescript
// Create pairwise DID for relationship with specific verifier
const pairwiseDid = await client.did.createPairwise({
  peerDid: 'did:emp:verifier-456',
  purpose: 'employment-verification'
});

// This DID is only used with this specific verifier
console.log('Pairwise DID:', pairwiseDid.id);

Benefits

  • Privacy: Prevents correlation across different services
  • Selective disclosure: Different identities for different contexts
  • Revocation: Revoke relationship without affecting others

DID Registry (On-Chain)

KryptoOS stores DID anchors on the EmpoorioChain blockchain:

What's Stored On-Chain

  • DID identifier
  • Hash of DID Document
  • Controller addresses
  • Verification method references
  • Service endpoint hashes
  • Version number
  • Creation and update timestamps

What's NOT Stored On-Chain

  • Private keys (always kept off-chain)
  • Personal identifiable information (PII)
  • Full service endpoint URLs (only hashes)
  • Credential data

Transaction Fees

DID operations require Dracma (DMS) tokens for transaction fees:

OperationApproximate Fee
Register DID0.1 Dracma (DMS)
Update DID Document0.05 Dracma (DMS)
Add Verification Method0.03 Dracma (DMS)
Add Service0.02 Dracma (DMS)
Deactivate DID0.05 Dracma (DMS)

Best Practices

Security

  1. Secure Key Storage: Use hardware wallets or HSMs for production
  2. Regular Rotation: Rotate keys at least annually
  3. Backup: Maintain secure, encrypted backups of keys
  4. Access Control: Limit who can update DID Documents

Privacy

  1. Pairwise DIDs: Use different DIDs for different relationships
  2. Minimal Disclosure: Only include necessary information in DID Documents
  3. Service Endpoints: Use privacy-preserving service endpoints

Operational

  1. Monitoring: Monitor DID resolution and update operations
  2. Documentation: Document all DID operations and key rotations
  3. Testing: Test DID operations in development before production
  4. Compliance: Ensure DID management complies with regulations

Troubleshooting

DID Resolution Fails

Problem: Cannot resolve a DID

Solutions:

  • Verify the DID format is correct
  • Check network connectivity
  • Ensure the DID is registered on-chain
  • Try a different resolver endpoint

Update Transaction Fails

Problem: DID update transaction rejected

Solutions:

  • Verify you control the DID (have the private key)
  • Check wallet has sufficient Dracma (DMS) for fees
  • Ensure you're using the correct controller address
  • Wait for network congestion to clear

Key Rotation Issues

Problem: Applications still using old keys

Solutions:

  • Implement grace period (30-90 days)
  • Notify all relying parties
  • Update all service configurations
  • Monitor for errors before removing old keys

Next Steps


Need help? Check our FAQ or join our Discord community.