Skip to main content
Version: v0.25.0 (Latest)

Roles and Topology

The EDK is consumable in two ways. Library customers depend on EDK modules from Sphereon's authenticated Maven repository in their own Kotlin application and assemble whatever process shape suits them; see Installation for the repository and dependency setup. Container customers run the pre-built enterprise service images Sphereon publishes and configure them through REST and YAML. This section is for the second group.

important

Sphereon publishes the enterprise container images and the edk-enterprise Helm chart. A customer deployment pulls these published images and installs the chart from the Enterprise Development Kit Deployment repository. Use the image tag and Helm chart version supplied during onboarding or by Sphereon support.

The shipped images are enterprise runtime assemblies. Customers consume them as published artifacts; they do not build them from source.

Sphereon publishes six enterprise service images to commercial customers:

  • nexus.sphereon.com/edk-docker/enterprise-platform: the internal platform service for first-run setup, platform administration, platform configuration, license/config distribution, and the platform-only authorization server.
  • nexus.sphereon.com/edk-docker/enterprise-tenant-kms: the cryptographic authority for tenant runtime services. Every other tenant service delegates key generation, signing, encryption, and public-key lookup to it. Internal-only by default.
  • nexus.sphereon.com/edk-docker/enterprise-did: a public DID resolver plus an internal admin and registrar surface for did:web, did:webvh, did:jwk, and did:key.
  • nexus.sphereon.com/edk-docker/enterprise-tenant-as: an OAuth 2.0 / OpenID authorization server scoped to the flows that EDK needs first-hand: the OID4VCI pre-authorized code grant, the OID4VCI authorization code grant via wallet federation, and client-credentials issuance for tenant service clients.
  • nexus.sphereon.com/edk-docker/enterprise-issuer: the OpenID4VCI credential issuer: protocol endpoints (/credential, /credential_deferred, /nonce, /notification), the attribute pipeline, the credential-design store, deferred and approved issuance, and the async-callback ingress.
  • nexus.sphereon.com/edk-docker/enterprise-verifier: the OpenID4VP verifier: request_uri, direct_post, DCQL query store with versioning, per-tenant trust frames, and presentation callbacks.
  • nexus.sphereon.com/edk-docker/admin-console: the operator admin UI, served at https://platform.<base-domain>/admin-console through the gateway.

These are exactly the container roles. There is no combined "everything" image, and there is no per-tenant fan-out at the EDK level. Each image is one process. Each runtime image is one logical entity (one issuer, one verifier, one tenant AS, and so on) that becomes multi-tenant by resolving the active tenant from each request.

Distribution

Sphereon distributes the service images and admin-console image through an authenticated Docker registry under nexus.sphereon.com/edk-docker. Registry credentials are issued under the commercial agreement during onboarding; customers pull with standard Docker authentication and pin the delivered version tag. The edk-enterprise Helm chart is published to Sphereon's authenticated Nexus repository, using the same onboarding credentials, and a baseline application.yaml per JVM service ships alongside the images.

Each published image carries a version tag and records its source revision in the OCI labels and /version output. Pin the exact tag supplied for the delivery rather than tracking :latest.

Each JVM service image is a Java 21 runtime (eclipse-temurin:21-jre) carrying a single service application and its static default configuration. It runs as a non-root user (uid 10001) and serves REST on port 8080. The admin console is a Next.js server on port 3000. All runtime behaviour is driven through the standard EDK configuration layering: environment variables, mounted YAML overlays, platform configuration, cloud config providers, and per-tenant configuration in the tenant workload database.

The platform and tenant-KMS images run the inbound gRPC command receiver. DID, tenant-AS, issuer, verifier, and tenant-KMS call the platform service over internal gRPC for platform configuration and platform-managed state. DID, tenant-AS, issuer, and verifier call tenant-KMS over internal gRPC for KMS operations. gRPC is east-west only and is never published through the public gateway.

EDK roles and topology

How the Roles Were Drawn

The split into platform, KMS, DID, AS, Issuer, Verifier, and admin console follows where attack surfaces and access patterns actually diverge, not microservice fashion.

The platform is the central control service. It owns first-run setup, license activation, operator login, platform administration, and platform configuration. Keeping it separate from the tenant AS prevents operator administration flows from being confused with customer tenant OAuth/OIDC flows.

The KMS sees raw key material and signing requests, so it has no business being on the public internet. It exposes a peer REST surface that the issuer, verifier, AS, and DID services call from the internal cluster network and an admin REST surface for provider registration and per-tenant key alias management. The deployment template binds it to an internal LB or a service-mesh-only endpoint.

The DID service is the inverse: its primary value is public resolution. Wallets, other issuers, other verifiers, and arbitrary internet clients need to be able to fetch did:web documents and Universal Resolver responses. Splitting DID out of the issuer and verifier images keeps the public surface they expose down to just their protocol endpoints, and lets DID scale horizontally for resolution traffic independently of the issuer's pipeline workload.

The AS, Issuer, and Verifier each own one OAuth or OpenID protocol family. They have both a public protocol surface (the wallet-facing endpoints) and an internal admin surface (the tenant administrator's CRUD over designs, queries, integrations, federation providers, public-endpoint bindings). The deployment template puts the protocol path behind the public ingress and the /api/v1/... admin path behind an internal ingress with bearer-JWT authentication.

Tenant Resolution Across The Runtime Images

The tenant runtime images embed the same EDK tenant resolution stack. The resolved tenant is the unit of routing and the unit of authorization. Tenants are recognised from the incoming request through a layered resolver chain:

  • JWT is the primary source for any authenticated call. The tenant_id claim in the bearer token is authoritative. The X-Tenant-Id header is informational only and is never trusted on its own.
  • Subdomain of the configured platform base host. acme.issuer.example.com resolves to the acme tenant.
  • Custom domain mapped to a tenant via the TenantDomain registry once the domain has been verified.
  • Path slug prefix. /{tenant-slug}/oid4vci/credential and the various .well-known URL forms route into the same tenant.

For the protocol metadata endpoints, the EDK supports both the spec-canonical form and the legacy slug-before-.well-known form, because clients in the field use both:

  • OID4VCI: /.well-known/openid-credential-issuer/{tenant-slug} (spec) and /{tenant-slug}/.well-known/openid-credential-issuer (legacy).
  • OAuth AS metadata: /.well-known/oauth-authorization-server/{tenant-slug} (spec) and the legacy variant.
  • OpenID Connect: /{tenant-slug}/.well-known/openid-configuration (the spec form expects slug-before).

The tenant administrator declares slugs and verified custom domains through the tenant admin REST. Runtime services consume from the registry; they never invent slugs or guess.

How the Enterprise Images Compose

A typical deployment looks like this:

  • One platform instance for setup, license activation, operator login, platform administration, platform configuration, and central platform-managed distribution.
  • One tenant KMS instance, sized for the deployment's signing rate. Backed by the tenant workload database for key-reference bookkeeping; actual key material lives in the configured provider backend (software keystore, AWS KMS, Azure Key Vault, Digidentity CSC, an HSM).
  • One DID resolver instance behind the public ingress, scaled horizontally if resolution traffic warrants it. A separate manager admin endpoint behind the internal ingress for did:web document publishing and did:webvh log management.
  • One tenant AS instance handling the wallet-facing OAuth surface and the per-tenant federation/discovery/JWKS endpoints.
  • One Issuer instance handling the wallet-facing OID4VCI protocol surface plus the credential design, attribute supplier, integration, and webhook admin surfaces.
  • One Verifier instance handling the wallet-facing OID4VP surface plus the DCQL versioned store, trust-frame admin, and webhook admin surfaces.
  • One admin-console instance routed at /admin-console on the platform host.
  • Two PostgreSQL database roles: a platform database owned by the platform service, and a tenant workload database shared by the tenant runtime images with one schema per tenant. Replicas of a runtime image share the same tenant workload database and route into the schema for the resolved tenant.

For a high-traffic deployment, each role scales horizontally. Cross-replica cache invalidation is handled through Postgres LISTEN/NOTIFY plus a TTL fallback, so tenant routing, public-endpoint binding, and per-tenant config mutations made on one replica become visible on the others without a restart and without rebooting the cluster.

What This Section Covers

  • Topology: the public/internal ingress split, network policies, service-to-service auth, the split platform and tenant workload databases, and how a customer typically lays out namespaces and ingress classes.
  • KMS Container: provider registration, per-tenant key aliases, the REST surface that the other images call.
  • DID Container: the public resolver, the manager admin, per-tenant method allowlists, the did:web and did:webvh publishing model.
  • AS Container: the tenant OAuth/OIDC surface that EDK currently supports, tenant federation, signing-key binding to KMS, the discovery URL forms.
  • Issuer Container: protocol endpoints, the attribute pipeline, the credential-design store, integration kinds for AS binding and attribute suppliers, webhooks.
  • Verifier Container: protocol endpoints, the DCQL versioned store, per-tenant trust-frame binding, presentation callbacks.
  • Configuration & Secrets: the application.yaml profile, environment variable mapping, per-tenant config storage, secret backends.
  • Operations: health, readiness, OpenTelemetry, audit, backup and restore.

What This Section Does Not Cover

Several capabilities that are sometimes associated with a broader production platform are deliberately out of scope for this EDK deployment section:

  • Multi-instance per tenant (N issuers, N verifiers, N AS instances per tenant for different credential programs or business units).
  • Building or publishing the enterprise images locally.
  • Tenant self-service onboarding flows beyond the REST endpoints.
  • License validation, billing, and metering.
  • Durable workflow execution (sagas, long-running schedulable commands).
  • Cross-tenant catalog projection.
  • MFA, account self-service, and a full IAM admin UI on the AS.

Treat those as separate platform capabilities, not as features of the EDK deployment kit.