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

Semantics Walkthrough

This walkthrough builds one concrete use case end to end: an organization (Acme Corp) issues employee credentials and later verifies a subset of them. Acme issues two credentials to its people, an Employee credential as an SD-JWT VC and a Business Card as an mdoc, and stands up a standalone verifier that asks a wallet to present claims from both in a single request.

What makes this an enterprise walkthrough is not the protocols. The OpenID4VCI issuance and OpenID4VP verification flows are the same ones documented in the OpenID4VCI and OpenID4VP guides. What changes is that none of the wire forms are typed by hand. The issuer's credential design and the verifier's DCQL query are both derived from a shared semantic model, so the issued credential and the requested credential agree on attribute identity by construction.

The pages that follow take you from modeling your world to the REST calls that drive the flow. They focus on the public EDK REST API and the JSON it exchanges. You author every layer over these REST APIs; in VDX the same layers are also presented through a guided UI, so an operator can build and govern the model without writing requests by hand.

The Mental Model

The naive way to stand up an issuer and a verifier is to hand-author both wire forms:

  • The issuer POSTs a credential design with a literal claims[] array. Each claim carries its own path, selective-disclosure policy, label, and ordering, all typed by hand.
  • The verifier POSTs a DCQL query with a literal credentials[] array, its claim paths typed by hand, independently of the issuer.

That works for a single credential, but it does not scale across an organization. There is no shared definition of what given_name is, so the issuer's given_name and the verifier's given_name can drift apart with nothing to catch it. Selective-disclosure policy, data classification, legal basis, and retention are retyped on every design. And nothing records which attributes a given design or query actually consumed, so no one can later answer "where do we issue or request this personal attribute?".

The enterprise semantic model inverts this. A canonical, organization-owned model is authored once, and the issuer design and verifier DCQL are renderings derived from it. The model is the source of truth; the wire forms are outputs.

The Layered Model

The model is a layered authoring stack. Each layer is authoritative for the layer above it, narrowing what downstream layers admit and never widening it.

The four-layer semantic authoring stack: L1 Semantic Catalog defines PREDEFINED party-type entities (Person, Address, Organization) and SPECIALIZATION entities (Employee, Employer) plus first-class relationships (residentialAddress, employment). L2 Attribute Profile binds catalog entities via use-case roles (employee, employer) with optional specializes narrowing, and selects which relationships the use case includes. L3 Attribute Set is a role-scoped traversal subselection of one profile, where each selected entry is a roleRef plus an array path that may traverse a relationship. L4 channels are set-bound artifacts that map set traversal paths to wire claim paths; both the issuer design and the verifier DCQL derive from the same VC channel, and usage lineage rows carry role_ref, source_entity, traversal_path, role (ISSUE or REQUEST), and artifact_kind.
  • L1 Semantic Catalog is the canonical layer. It describes the world for the organization: the party-type entities, their attributes, their relationships, and their governance. A catalog is owned (by a Party) and versioned. Entities are either PREDEFINED party types (for example, natural_person, address, or organization, each with its own attribute list) or SPECIALIZATIONS that subtype a predefined entity and add attributes (for example, Employee specializes Person, Employer specializes Organization). Relationships between entities are first-class objects with named ends, a relationType, and per-end cardinality: for example, residentialAddress links a Person (source) to an Address entity (target, role home, cardinality 1..1). A catalog is created as a shell, entities and relationships are appended, then it is published.
  • L2 Attribute Profile is the use-case layer. The "Acme Employee" profile pins the catalog version it draws from, declares use-case roles (each bound to a catalog entity and optionally narrowed to a specialization via specializes), selects which catalog relationships the use case includes, and may narrow a small allow-list of per-attribute fields such as conformance. It never widens the catalog.
  • L3 Attribute Set is a role-scoped traversal subselection of exactly one profile. Each selected entry is a { roleRef, path: [...] } pair where the path is an array that may traverse a relationship: for example, { roleRef: "employee", path: ["residentialAddress", "country"] } reaches the country attribute of the Address entity via the residentialAddress relationship from the employee role. The set resolves to a flat list of typed, governed attribute entries that downstream channels consume.
  • L4 is the channel-rendering layer. The same resolved attribute set can drive many outputs, not just credentials: a data-capture form, a portal page, a generated PDF document, an API payload, or a verifiable credential, each authored at /api/attributes/v1/channels/{channel}. Because this is an issuer and verifier walkthrough, it uses the channel. A set-bound VC channel binds exactly one attribute set, a credential format (dc+sd-jwt or mso_mdoc), a credential-type identity (vct for SD-JWT or doctype for mdoc), shared branding, and a claimMappings table that maps each set traversal path to its wire claim path. This is the artifact the issuer design and the verifier DCQL both derive from. An OID4VCI issuance channel then composes one or more VC channels under a single credentialConfigurationId and carries the offer configuration; it has no setRef of its own.

Modeling Your World goes deeper into the world model and each layer.

Channel Modes

A channel exists in one of two modes:

ModeClaim sourceWhere it livesLicense gate
Free-formhand-written claim listIDK (open source)ungated
Set-bound / semanticderived from a set-bound VC channelEDK / VDX (enterprise)gated on semantic-attribute-binding

The free-form mode is a hand-written claim list with no semantic provenance. It is the simple, open-source path and is not license-gated. Use it when you just want a credential and have no model behind it.

The set-bound / semantic mode derives the claim list, selective-disclosure policy, and credential-type identity from a set-bound VC channel. The governance flows down from the catalog, usage lineage is recorded per consumed traversal path, and the verifier's DCQL is derived from the same VC channel the issuer used. This is the enterprise, license-gated mode, and it is the mode this walkthrough uses.

tip

Every enterprise write (catalog, profile, set, and branding authoring; VC channel create; design-from-channel render; and the DCQL authored call) is gated behind a single license feature, semantic-attribute-binding. Reads, resolves, and the DCQL preview derivation are never gated. The free-form path is entirely ungated. The gate is fail-open by design: a deployment with no license features set (the unbounded default) applies no gating at all. HTTP-exposed VDX semantic-binding operations also carry per-operation x-license-protection metadata in OpenAPI and matching ServiceCommandContract.licenseProtection descriptors. See Modeling Your World.

What the Model Drives

The model is not a passive input. From the catalog, profile, set, and VC channels, the platform derives, transparently:

  • The wire form of the issued credential. The claim list and the credential-type identity (format, vct or doctype) come from the VC channel's claimMappings table, not from a hand-typed design field.
  • Selective-disclosure and governance policy. Selective-disclosure policy, data classification, legal basis, and retention flow down from the catalog attribute, through the profile and set, to the issued wire form.
  • The verifier DCQL. The verifier's credential queries are derived from the same VC channels the issuer used, so issuer and verifier agree on attribute identity by construction.
  • Usage lineage. Every derivation records which traversal paths a given artifact (a credential design or a DCQL query) consumed, in which role (ISSUE or REQUEST), so an operator can audit where each attribute is issued or requested.

What We Will Build

The walkthrough authors the whole model through the layered authoring API under /api/attributes/v1: one explicit REST call per layer, which is exactly how a real authoring UI drives it.

StepLayer / surfaceREST entry pointPage
L1: create the catalog shellCatalogPOST /api/attributes/v1/catalogsCatalog
L1: add 5 entitiesCatalog entitiesPOST /api/attributes/v1/catalogs/{id}/entities (x5)Catalog
L1: add 2 relationshipsCatalog relationshipsPOST /api/attributes/v1/catalogs/{id}/relationships (x2)Catalog
L1: publish and resolveCatalog lifecyclePUT /api/attributes/v1/catalogs/{id}/status then GET .../resolvedCatalog
L2: create, publish, resolve the profileProfilePOST /api/attributes/v1/profiles (+ .../status, .../resolved)Attribute Profile
Branding: create and publishPresentation overlayPOST /api/attributes/v1/branding (+ .../status)Channels
L3: create, publish, resolve the setAttribute setPOST /api/attributes/v1/sets (+ .../status, .../resolved)Attribute Set
L4: two set-bound VC channelsVC channelsPOST /api/attributes/v1/channels/credentials (x2)Channels
L4: OID4VCI issuance channelOID4VCI channelPOST /api/attributes/v1/channels/oid4vciChannels
Render both issuer designs from channelsIssuer designPOST /api/v1/designs/credentials/fromchannel (x2)Issuing
Create one offer per credentialIssuer offerPOST /oid4vci/backend/credential/offers (x2)Issuing
Preview then author a multi-credential DCQLVerifier DCQLPOST /api/v1/oid4vp/dcql/preview then .../authoredVerifying
Create the OID4VP auth requestVerifier presentationPOST /oid4vp/backend/auth/requestsVerifying
Poll verifier status, read verified dataVerifier presentationGET /oid4vp/backend/auth/requests/{id}Verifying
Audit usage lineageProvenance(lineage rows)Provenance & Operations

The two set-bound VC channels are what turn the layered semantic model into something issuable and verifiable: the issuer's design and the verifier's DCQL are both derived from those same channels.

All authoring and backend calls authenticate with an OIDC bearer token issued by the tenant's Authorization Server; the tenant is resolved from the token's tenant_id claim, never from a client-supplied header. The wallet-facing protocol endpoints (/oid4vci/credential, /oid4vp/request-uri/...) are driven by a wallet and need no operator token.

Next Steps