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

KMS Container

nexus.sphereon.com/edk-docker/enterprise-tenant-kms is the cryptographic authority for tenant runtime services. Every key the issuer signs credentials with, every signing key on an OID4VP request object, every key alias a tenant AS uses to sign access tokens, and every audit-checkpoint signing key lives on this container. The other runtime containers do not generate or hold key material; they reference keys by alias and route KMS commands to tenant-KMS over the internal gRPC network.

That centralisation is deliberate. It lets a deployment use a single provider backend (an HSM, AWS KMS, Azure Key Vault) across all of its issuer, verifier, AS, and DID activity, with one place to coordinate key references and one audit trail for crypto operations. It also keeps the issuer, verifier, and AS images free of provider SDKs they would otherwise need to ship. A registered external resource remains owned by its provider, so the container must not treat every reference as permission to delete provider material.

KMS container internal architecture

Why the KMS Is Protected​

For generated or imported keys, the KMS handles the key material as it writes to the provider backend and sees plaintext payloads on their way in to be signed. Registering an existing provider key or certificate does not send private or symmetric key material through the KMS. There is no scenario in which a wallet or relying party should call it directly. Runtime signing traffic comes from the EDK's own issuer, verifier, AS, and DID containers on the east-west network.

Customer-facing administration goes through the tenant gateway route https://<tenant>.<base-domain>/api/kms/v1 with a tenant-scoped bearer token. The KMS container hostname, service DNS name, health routes, metrics, and gRPC receiver are not customer endpoints.

If a deployment needs extra controls around KMS administration, add policy at the gateway or service mesh. Do not expose the KMS container itself.

Providers​

A provider is the actual backend that holds the key material and performs the operations. The EDK ships first-party providers for:

  • Software keystore. Keys generated and held in process. Useful for development and for non-critical signing duties.
  • AWS KMS. Keys live in AWS KMS; the EDK provider issues Sign, Verify, and GetPublicKey calls. Provider configuration carries the AWS region and an optional endpoint.
  • Azure Key Vault. Keys live in Azure Key Vault or Managed HSM under the configured vault URI. The provider authenticates as a Microsoft Entra application with a client secret.
  • Digidentity CSC. Keys held in a Digidentity Cloud Signature Consortium account, suitable for eIDAS qualified signing.
  • HTTP provider facade. A KMS provider that itself fronts another KMS through a REST-compatible EDK KMS facade. Useful when a tenant needs to route to a remote KMS instance behind that facade.

Tenant onboarding creates the software provider default for every tenant. Cloud providers come from one of two places: the operator declares a managed provider in the deployment configuration, or an administrator creates one through the Admin Console or the Platform Config API. Cloud KMS providers explains both and when to use which. Either way the provider is typed configuration, and its provider id is a permanent identifier that applications send with every key and signing request.

A tenant can have several providers at once. One is the tenant default and receives new keys when a request omits providerId; issuers, verifiers, status lists and authorization servers name their provider id and key alias explicitly. A provider must be configured, active, and available to the tenant before the tenant can generate, import or register a key or certificate against it.

Key Aliases​

A key alias is a logical name a runtime service uses to refer to a key. The alias structure is (tenant, service, purpose):

  • tenant: the tenant slug the key belongs to.
  • service: which service uses it: issuer, verifier, as, did, audit.
  • purpose: what the key signs: credential-signing, request-object-signing, access-token-signing, audit-checkpoint, did-update.

The first time a runtime service needs a key for a given alias, it either resolves to a system-provisioned default (the deployment template generates one per tenant on first activity), to an operator-supplied alias, or to a reference for a key that already exists in an authorized provider. Either way, the service never sees the raw key. It only sees the alias and the provider routing.

Key rotation is per-alias and per-tenant. The KMS holds the key history; the runtime service queries the current public key when it needs to publish JWKS or to verify a counterparty signature.

What the REST Surface Provides​

The protected REST surface exposes several HTTP adapter families for tenant and operator administration. The same command families back service-to-service KMS operations, but runtime issuer, verifier, tenant AS, and DID traffic reaches tenant-KMS over internal gRPC rather than through the public gateway:

  • KeysHttpAdapter: global key generation, key import, key registration, key listing, key deletion, and key metadata read. Tenant context is JWT-bound.
  • ProvidersHttpAdapter: provider registration, provider configuration, provider listing. Platform-admin scoped.
  • CapabilitiesHttpAdapter: provider capability listing and provider matching via /capabilities, /providers/{providerId}/capabilities, /providers/query, and /providers/query/best.
  • ResolversHttpAdapter: public-key resolution by alias or key id. Runtime services use the corresponding command family when they publish JWKS or verify a counterparty signature.
  • SignaturesHttpAdapter: raw signature creation and verification. These commands back issuer credential signing, AS access-token signing, OID4VP request-object signing, and audit-checkpoint signing.
  • EncryptionHttpAdapter: content encryption/decryption, key wrap/unwrap, and key agreement.
  • CertificatesHttpAdapter: CSR generation, certificate issuing, trusted certificate storage, certificate-chain storage, and external certificate-reference registration. Deployment availability still depends on the immutable image and migrations running in the target environment.

For keys, generation is the normal POST /keys and POST /providers/{providerId}/keys flow. Externally supplied key material is imported through /keys/import or /providers/{providerId}/keys/import. POST /keys/register is reserved for registering an existing provider-side key reference. Registration resolves an existing alias and, when supplied, verifies the immutable kid; it creates no key, imports no key material, and creates no certificate-management record.

Multi-tenant isolation is enforced on every call: a tenant can only operate on its own references, and no call can reach another tenant's key or certificate material. Registration inspection runs through a typed, permit-bound provider lease after the tenant authorization check. It does not use an unscoped provider directory or provider-wide enumeration.

Persistence​

The KMS stores tenant-scoped reference bookkeeping in the tenant workload database. The key_reference table maps (tenant, alias) to (provider_id, kid, metadata) inside the resolved tenant schema. Certificate references store the provider id, logical alias, source, lifecycle mode, linked key reference, fingerprints, and public DER chain when STORED_PUBLIC_MATERIAL is used. The actual private or symmetric key material remains in the provider backend. Public certificate bytes may be stored for a stored-material reference.

Persistent list operations return only references owned by the authenticated tenant. They do not enumerate every key or certificate present in a shared cloud provider. Existing rows migrate as PLATFORM_MANAGED because migration cannot infer whether an old row was externally provisioned. A later explicit registration establishes EXTERNALLY_MANAGED ownership.

External registration and lifecycle​

External registration records a tenant-local reference. It does not transfer lifecycle ownership from the provider. An EXTERNALLY_MANAGED key DELETE removes only the local EDK reference and leaves the provider resource untouched. A repeated delete must resolve the persisted deleted reference and must remain local-only, including after a restart.

Platform-managed keys generated or imported through EDK may use a tenant-prefixed provider backing alias. Externally managed keys and provider-native certificates keep the exact alias or id assigned in AWS or Azure. When one platform-owned provider connection is shared by multiple tenants, an externally managed AWS KMS key or Azure Key Vault key or certificate must carry the cloud-native tag sphereon-tenant-id=<tenantId>. The assignment is checked before registration and immediately before later use. Tenant-scoped reference indexes determine list results; the service does not enumerate the provider inventory. A tenant-owned provider does not require the shared-provider assignment tag.

The existing platform-managed behavior is preserved. A PLATFORM_MANAGED key or certificate DELETE retains its provider deletion behavior, with the local reference updated only after the provider operation succeeds. The control mode, not the route name alone, determines whether provider deletion is allowed.

The additive certificate registration contract uses POST /api/kms/v1/certificates/register. It supports PROVIDER_NATIVE reads where a provider exposes a non-destructive certificate read capability, and STORED_PUBLIC_MATERIAL for public DER chains. Both modes bind the leaf public key to a tenant-authorized provider key. The current source includes the REST adapter route. A deployment supports it only when its immutable enterprise image build contains this contract and the matching database migrations.

Azure Key Vault provides provider-native leaf reads only. The KMS does not follow AIA URLs, export a PFX, or synthesize a chain. AWS KMS has no certificate object API. AWS Certificate Manager and AWS Private CA are separate services, so an AWS KMS-linked certificate chain uses stored public DER unless a separate certificate-capable provider is configured.

Provider-supplied x5c, x5t, and x5t#S256 remain public key and JWKS metadata. They do not create certificate-management records. A DID verification-method JWK omits the backend kid while retaining these public certificate members.

The persistence module is lib-crypto-key-persistence-postgresql. It also has a MySQL counterpart (lib-crypto-key-persistence-mysql) for deployments that standardise on MySQL.

Image and Runtime​

The image is nexus.sphereon.com/edk-docker/enterprise-tenant-kms:<enterprise-version>, or the equivalent mirror supplied through your distribution channel. It runs as a non-root appuser (uid 10001) on port 8080.

The Helm chart keeps the KMS service private and routes selected REST paths through the tenant gateway. Operators use https://<tenant>.<base-domain>/api/kms/v1 with a tenant-scoped token; service-to-service KMS commands remain on the internal gRPC network.

The minimal application.yaml shipped in the image is intentionally permissive for local testing:

server:
rest:
port: 8080
auth:
enabled: false
anonymous:
allowed: true

A production deployment overrides this through the standard EDK config layering (environment variables, mounted YAML overlays, cloud config providers) to require bearer-JWT auth on every call and to disable anonymous access. Per-tenant configuration, including provider routing and key alias overrides, lives in the tenant workload database under tenant_config_property in the resolved tenant schema.

Operational Notes​

  • Capacity. The KMS is rarely the bottleneck for low-to-medium throughput. When it is, the bottleneck is usually the provider backend (AWS KMS rate limits, HSM throughput) rather than the container.
  • Failure modes. If the KMS is unreachable, signing-dependent paths fail immediately on the calling service. There is no fallback to a local key, by design. The deployment template's readiness probes consider the KMS dependency healthy before marking issuer/verifier/AS ready.
  • Provider failover. A tenant can have several providers and switch which provider id a service uses. The KMS itself does not sequence cross-provider failover automatically.
  • Auditing. Every signing operation emits an audit event with the tenant, alias, provider id, kid, and timestamp. Lifecycle audit data distinguishes provider-resource deletion from local-reference removal. The audit signing key alias is a KMS key in its own right ((tenant, audit, audit-checkpoint)).