Skip to main content
Version: v0.13

DID REST Services

The EDK provides REST APIs for DID lifecycle management compatible with the DIF Universal Registrar specification.

Overview

The EDK extends the IDK's DID capabilities with enterprise REST services:

ServiceSpecificationDescription
Universal RegistrarDIF Universal RegistrarCreate, update, deactivate DIDs
Universal ResolverDIF Universal ResolverResolve DIDs (via IDK)

Architecture

DID Universal API Architecture

Universal Registrar

The Universal Registrar provides a REST API for DID lifecycle operations.

Endpoints

MethodPathDescription
POST/1.0/createCreate a new DID
POST/1.0/updateUpdate an existing DID
POST/1.0/deactivateDeactivate a DID
GET/1.0/methodsList supported DID methods
GET/1.0/propertiesGet registrar capabilities

Create DID

POST /1.0/create HTTP/1.1
Content-Type: application/json

{
"method": "web",
"options": {
"domain": "example.com",
"path": ["users", "alice"]
},
"secret": {
"verificationMethod": [{
"type": "JsonWebKey2020",
"purpose": ["authentication", "assertionMethod"]
}]
}
}

Response:

{
"jobId": null,
"didState": {
"state": "finished",
"did": "did:web:example.com:users:alice",
"didDocument": {
"@context": ["https://www.w3.org/ns/did/v1"],
"id": "did:web:example.com:users:alice",
"verificationMethod": [{
"id": "did:web:example.com:users:alice#key-1",
"type": "JsonWebKey2020",
"controller": "did:web:example.com:users:alice",
"publicKeyJwk": {
"kty": "EC",
"crv": "P-256",
"x": "...",
"y": "..."
}
}],
"authentication": ["did:web:example.com:users:alice#key-1"],
"assertionMethod": ["did:web:example.com:users:alice#key-1"]
}
},
"didDocumentMetadata": {},
"didRegistrationMetadata": {}
}

Update DID

POST /1.0/update HTTP/1.1
Content-Type: application/json

{
"did": "did:web:example.com:users:alice",
"options": {},
"didDocumentOperation": ["addToDidDocument"],
"didDocument": [{
"service": [{
"id": "#hub",
"type": "LinkedDomains",
"serviceEndpoint": "https://hub.example.com"
}]
}]
}

Deactivate DID

POST /1.0/deactivate HTTP/1.1
Content-Type: application/json

{
"did": "did:web:example.com:users:alice",
"options": {
"reason": "Key rotation"
}
}

List Supported Methods

GET /1.0/methods HTTP/1.1

Response:

{
"methods": ["key", "web", "jwk"]
}

Get Properties

GET /1.0/properties HTTP/1.1

Response:

{
"properties": {
"supportedMethods": ["key", "web", "jwk"],
"supportsKeyGeneration": true,
"supportsUpdate": true,
"supportsDeactivate": true
}
}

Spring Boot Integration

Auto-Configuration

The registrar is automatically configured with Spring Boot:

dependencies {
implementation("com.sphereon.edk:lib-did-rest-registrar-server:0.13.0")
implementation("com.sphereon.edk:idk-spring-support:0.13.0")
}
# application.yml
sphereon:
did:
registrar:
enabled: true
base-path: /did/registrar

Custom DID Method Providers

Register custom DID method providers:

import com.sphereon.did.manager.DidProvider
import com.sphereon.did.manager.DidProviderRegistry
import org.springframework.context.annotation.Configuration
import jakarta.annotation.PostConstruct

@Configuration
class DidConfiguration(
private val providerRegistry: DidProviderRegistry
) {
@PostConstruct
fun registerProviders() {
// Providers are auto-registered via DI
// Custom providers can be added here
}
}

Programmatic Usage

Creating DIDs via REST Client

import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.http.*

val client = HttpClient()

val response = client.post("https://api.example.com/1.0/create") {
contentType(ContentType.Application.Json)
setBody("""
{
"method": "key",
"options": {},
"secret": {
"verificationMethod": [{
"type": "JsonWebKey2020",
"purpose": ["authentication"]
}]
}
}
""")
}

Using the HTTP Adapter Directly

import com.sphereon.did.rest.registrar.UniversalRegistrarHttpAdapter

class DidService(
private val registrarAdapter: UniversalRegistrarHttpAdapter
) {
// The adapter automatically handles routing for /1.0/* endpoints
// It delegates to injected command handlers:
// - CreateDidEndpointCommand
// - UpdateDidEndpointCommand
// - DeactivateDidEndpointCommand
// - GetRegistrarMethodsEndpointCommand
// - GetRegistrarPropertiesEndpointCommand
}

Integration with IDK DID Manager

The REST API delegates to the IDK's DID Manager for actual operations:

import com.sphereon.did.manager.dsl.didCreateOptions
import com.sphereon.crypto.core.generic.KeyTypeMapping
import com.sphereon.crypto.core.generic.Curve
import com.sphereon.did.models.VerificationPurpose

// The same DSL used in IDK works with EDK
val options = didCreateOptions {
method("web")
domain("example.com")
path("users", "alice")

autoGenerateKey {
keyType(KeyTypeMapping.EC)
curve(Curve.P_256)
}

service("hub") {
type("LinkedDomains")
endpoint("https://hub.example.com")
}
}

// Create via manager
val result = didManager.create(options.options, options.keyConfigs)

See the IDK DID Documentation for detailed DSL usage.

Filtering and Querying

Use the IDK's DidFilter for querying DIDs:

import com.sphereon.did.manager.DidFilter
import com.sphereon.did.manager.DidRole

// Filter by method
val webDids = didManager.list(DidFilter(method = "web"))

// Filter by role
val managedDids = didManager.list(DidFilter(role = DidRole.MANAGED))

// Combined filters
val activeWebDids = didManager.list(
DidFilter(
method = "web",
role = DidRole.MANAGED,
includeDeactivated = false
)
)

Dependencies

dependencies {
// Universal Registrar server
implementation("com.sphereon.edk:lib-did-rest-registrar-server:0.13.0")

// Universal Resolver server (from IDK)
implementation("com.sphereon.idk:lib-did-rest-resolver-server:0.13.0")

// DID methods (include what you need)
implementation("com.sphereon.idk:lib-did-methods-key:0.13.0")
implementation("com.sphereon.idk:lib-did-methods-jwk:0.13.0")
implementation("com.sphereon.idk:lib-did-methods-web:0.13.0")

// DID persistence (for storing managed DIDs)
implementation("com.sphereon.idk:lib-did-persistence-sqlite:0.13.0")
// or for enterprise
// implementation("com.sphereon.edk:lib-did-persistence-postgresql:0.13.0")
}

Security Considerations

  1. Authentication: Protect registrar endpoints with appropriate authentication (JWT, OAuth2)
  2. Authorization: Use AuthZEN policies to control who can create/update/deactivate DIDs
  3. Key Storage: Ensure KMS providers are properly secured
  4. Audit Logging: Enable event persistence for audit trails
# Example: Require authentication for registrar
sphereon:
did:
registrar:
require-authentication: true
security:
jwt:
issuer: https://auth.example.com
audience: did-registrar

Next Steps