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

Verifier Container

nexus.sphereon.com/edk-docker/enterprise-verifier is the OpenID4VP verifier. It accepts presentation requests from relying-party-side callers, hosts the protocol endpoints the wallet interacts with, validates incoming presentations using the trust modules included in the image, and fires callbacks to tenant-configured webhooks when a presentation completes.

Like the issuer, the verifier inherits the protocol layer from the IDK and adds the EDK layers around it: the DCQL versioned store with multi-binding per verifier, presentation session admin, and the same webhook infrastructure the issuer uses.

Verifier container layout

Public Protocol Surface​

The wallet-facing endpoints are the OID4VP set plus the universal-verifier integration:

  • Oid4vpVerifierHttpAdapter: request_uri, direct_post, ready. Standard OID4VP protocol mechanics.
  • UniversalOid4vpHttpAdapter: the EDK universal-verifier surface for create-auth-request, returning the request URI for the wallet to fetch, and the response surface.
  • TenantAwareOid4vpVerifierHttpAdapter: the tenant-aware adapter contributed by lib-openid-oid4vp-verifier-rest-tenant. Mounts the verifier under /{tenant-slug}/oid4vp/... and consults the public-endpoint binding for outbound URLs.

The IDK verifier descriptor provider publishes a TenantPathPolicy.LeadingSlug(maxDepth = 1), which is what makes the /{tenant-slug}/oid4vp/... path form route into the verifier through catalog dispatch.

The integration with the OID4VP authorization-server bridge (Oid4vpAuthHttpAdapter) lets a tenant use OID4VP as the authentication step for an OAuth flow. This is the same wallet-as-authenticator pattern the EDK auth bridge implements, but exposed at the verifier rather than as a separate service.

Internal Admin Surface​

The verifier admin REST under /api/v1/... covers:

  • Per-tenant verifier configuration. /api/v1/verifier/oid4vp is the typed CRUD for the verifier's per-tenant settings: display metadata, response_uri base, signing key alias for request objects, supported credential types.
  • DCQL versioned store. Two admin surfaces. DcqlQueryAdminHttpAdapter (from the IDK) handles the latest-version-only CRUD for development convenience. DcqlQueryVersionHttpAdapter (the EDK versioned overlay) handles versioned authoring: a header is stable, each save produces a new version, previous versions stay resolvable. A single verifier can have multiple DCQL queries bound concurrently and route between them by query id.
  • Webhook configuration. Same webhook subsystem the issuer uses, configured for verifier event types (presentation status, callback success, callback failure).
  • Presentation session admin. List, inspect, and cancel presentation sessions for debugging. Adapts the existing generic session persistence at lib-data-store-session/persistence-postgresql rather than creating a new session table family.
  • Tenant admin. Shared TenantAdminHttpAdapter for tenant CRUD, domain registration, public-endpoint bindings.

For the protocol-level reference and the DCQL authoring guide, see the OpenID4VP section: overview, integration, DCQL store, DCQL REST API, DCQL authoring, verifier bindings.

Tenant-Aware URL Generation​

The lib-openid-oid4vp-verifier-rest-tenant overlay replaces the IDK default Universal OID4VP create-auth-request command with an EDK implementation that consults tenant_public_endpoint. The effect:

  • request_uri_base in a returned authorization request points at the tenant's public OID4VP base.
  • For signed request objects using direct_post, the response_uri is the tenant's public OID4VP response endpoint.
  • status_uri in the returned status is rooted at the tenant's public OID4VP backend base.

The fail-closed default applies: if no tenant_public_endpoint binding for OID4VP_VERIFIER is configured for the resolved tenant, the verifier refuses to generate URLs against the request host. Tenant administrators set the binding through the tenant admin REST before enabling the verifier for live wallet traffic.

Trust Configuration​

The enterprise verifier image currently includes the IDK core and X.509 trust modules. It does not expose a per-tenant trust-source CRUD endpoint, and the platform trust-domain anchor model does not accept a trust-list URL or configure scheduled retrieval.

The IDK has a separate ETSI trust-list module that can retrieve and validate a statically configured List of Trusted Lists URL. An application that includes that module can configure it with trust.anchors.etsi.enabled, trust.anchors.etsi.lotl-url, trust.anchors.etsi.verify-signatures, and trust.anchors.etsi.territories. The library-level configuration is documented on the IDK page guides/trust/etsi-trust-lists. The standard enterprise verifier image does not currently include or expose this facility.

Consuming a tenant-supplied ETSI trust-list URL, retaining its JAdES validation policy, and periodically refetching it therefore requires an enterprise product capability that is not present in this image. Do not use /api/v1/verifier/oid4vp/integrations/trust; that route is not implemented.

VICAL and mdoc PKI​

VICAL is the ISO 18013-5 Annex C binary CBOR/COSE_Sign1 trust artifact used in some mdoc ecosystems. It is distinct from ETSI TS 119 602 JSON/JAdES trust-list material. The standard enterprise verifier image exposes no VICAL consume, generate, proxy, or refresh endpoint. Do not infer VICAL support from an x5c value or from ETSI trust-list material; those are different kinds of public certificate or trust metadata.

This is a statement about the verifier image, not about the product. A VICAL source is configured on the trust domain that the verifier consumes, through the trust-domain service, and the verifier then resolves mdoc issuer authorities from the admitted anchors of that domain. See Trust domains for the VICAL configuration surface.

DCQL Versioning​

DCQL queries are the verifier's declaration of what it wants the wallet to present. Each query has a stable header (an identifier and a label) and a sequence of versions (each carrying the query body itself). When a verifier evolves its DCQL query, it produces a new version against the same header; previous versions stay resolvable so in-flight presentations against the previous version still validate.

The header lives in dcql_query_header. Versions live in dcql_query_version. The DcqlQueryVersionHttpAdapter allows clients to fetch the current version, fetch by version id, list versions, and create a new version against an existing header. The Postgres impl ships in lib-openid-oid4vp-dcql-store-versioned-persistence-postgresql.

A verifier can also bind multiple distinct DCQL queries simultaneously, addressed by the query header id. Different presentation flows can each reference the appropriate query.

Signing Keys​

The verifier's request-object signing key alias defaults to (tenant, verifier, request-object-signing) on the KMS. Used when the verifier signs the authorization request object for request_uri flows.

The webhook signing key alias defaults to (tenant, verifier, webhook-signing). Used to HMAC outbound webhook calls so consumers can verify authenticity.

Both aliases are per-tenant; the tenant admin can override either through the signing-key admin REST.

Persistence​

The verifier overlay adds the following tables to the tenant workload database in each tenant schema:

  • The DCQL versioned store tables (dcql_query_header, dcql_query_version).
  • The integration registry tables (shared with the issuer).
  • The webhook configuration and dispatch queue tables (shared with the issuer).
  • The OID4VP-as-OAuth session store (PostgreSqlOid4vpAuthSessionRepository), backed through DatabaseOid4vpAuthSessionStore.
  • The presentation session admin uses the existing generic session persistence at lib-data-store-session/persistence-postgresql.

Image and Runtime​

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

The entry point starts EnterpriseOid4vpVerifierKtorServer, which installs the tenant resolution plugin first and then mounts the universal HTTP adapters. The Metro graph for the enterprise verifier pulls in lib-openid-oid4vp-verifier-rest-tenant, services-tenant-rest, lib-tenant-resolution-impl, lib-tenant-persistence-postgresql, the DCQL versioned store with its Postgres impl, the remote KMS/client transport modules, the IDK trust engine modules (lib-trust-core-impl, lib-trust-x509), and the core events implementation that the session emitter uses to dispatch callbacks.

A production deployment overrides the shipped application.yaml to require admin-scoped bearer JWTs on /api/v1/..., points at the tenant workload database with schema-per-tenant routing, registers the KMS endpoint, and binds tenant public endpoints through the tenant admin REST.

Operational Notes​

  • Presentation session retention. Successful presentation sessions are retained for the audit window (configurable per tenant), then archived. The presentation-session.list admin endpoint reads from the live table; archived sessions are accessible through the audit pipeline.
  • Multi-DCQL routing. When a verifier is bound to multiple DCQL queries, the create-auth-request call carries the query header id. The dispatch logic looks up the current version of that header and embeds the query body in the authorization request.
  • Webhook reliability. Same dispatcher as the issuer. The verifier emits presentation-completed and presentation-failed event types; tenants subscribe through the webhook admin REST.