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.
- 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, ororganization, 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, arelationType, and per-end cardinality: for example,residentialAddresslinks a Person (source) to an Address entity (target, rolehome, 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 thecountryattribute of the Address entity via theresidentialAddressrelationship 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-jwtormso_mdoc), a credential-type identity (vctfor SD-JWT ordoctypefor mdoc), shared branding, and aclaimMappingstable 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 singlecredentialConfigurationIdand carries the offer configuration; it has nosetRefof its own.
Modeling Your World goes deeper into the world model and each layer.
Channel Modes
A channel exists in one of two modes:
| Mode | Claim source | Where it lives | License gate |
|---|---|---|---|
| Free-form | hand-written claim list | IDK (open source) | ungated |
| Set-bound / semantic | derived from a set-bound VC channel | EDK / 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.
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,
vctordoctype) come from the VC channel'sclaimMappingstable, 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.
| Step | Layer / surface | REST entry point | Page |
|---|---|---|---|
| L1: create the catalog shell | Catalog | POST /api/attributes/v1/catalogs | Catalog |
| L1: add 5 entities | Catalog entities | POST /api/attributes/v1/catalogs/{id}/entities (x5) | Catalog |
| L1: add 2 relationships | Catalog relationships | POST /api/attributes/v1/catalogs/{id}/relationships (x2) | Catalog |
| L1: publish and resolve | Catalog lifecycle | PUT /api/attributes/v1/catalogs/{id}/status then GET .../resolved | Catalog |
| L2: create, publish, resolve the profile | Profile | POST /api/attributes/v1/profiles (+ .../status, .../resolved) | Attribute Profile |
| Branding: create and publish | Presentation overlay | POST /api/attributes/v1/branding (+ .../status) | Channels |
| L3: create, publish, resolve the set | Attribute set | POST /api/attributes/v1/sets (+ .../status, .../resolved) | Attribute Set |
| L4: two set-bound VC channels | VC channels | POST /api/attributes/v1/channels/credentials (x2) | Channels |
| L4: OID4VCI issuance channel | OID4VCI channel | POST /api/attributes/v1/channels/oid4vci | Channels |
| Render both issuer designs from channels | Issuer design | POST /api/v1/designs/credentials/fromchannel (x2) | Issuing |
| Create one offer per credential | Issuer offer | POST /oid4vci/backend/credential/offers (x2) | Issuing |
| Preview then author a multi-credential DCQL | Verifier DCQL | POST /api/v1/oid4vp/dcql/preview then .../authored | Verifying |
| Create the OID4VP auth request | Verifier presentation | POST /oid4vp/backend/auth/requests | Verifying |
| Poll verifier status, read verified data | Verifier presentation | GET /oid4vp/backend/auth/requests/{id} | Verifying |
| Audit usage lineage | Provenance | (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
- Modeling Your World: the world model, the four layers, usage lineage, and the license gate
- Catalog (L1): seed the catalog with entities and relationships, then continue through profile, set, and channels
- Issuing: render issuer designs from the VC channels and create the offer
- Verifying: author a multi-credential DCQL, request a presentation, read verified data
- Provenance & Operations: usage lineage, governance flow-through, versioning, and operational boundaries
- Related guides: OpenID4VCI, OpenID4VP, Credential Design, OCA Bundles