From 0aa67c9a337fb28d9c4598afd340330095130ebc Mon Sep 17 00:00:00 2001
From: Derek Scruggs
Date: Mon, 8 Jun 2026 11:46:02 -0500
Subject: [PATCH 1/4] Correct coordinator role on all build pages.
The issuer and verifier build pages described a coordinator as running
@bedrock/vc-delivery and hand-coding the raw VCALM exchange loop. That
conflates two distinct roles. A coordinator is a client of a workflow
service, not the service itself.
Rewrite all six build pages (government, education, supply-chain;
issuer and verifier) around the actual coordinator API surface:
- Create an exchange: POST /exchanges with ttl + variables,
receiving 204 plus a Location header (the exchange URL).
- Host and share the interaction URL pointing the wallet at the exchange.
- Poll GET /exchanges/ until state is complete and read
results under exchange.variables.results.
The workflow service (which runs @bedrock/vc-delivery) handles protocol
negotiation, signing, verification, and multi-wallet interop. Request
and response shapes verified against the bedrock-vc-delivery source.
Co-Authored-By: Claude Opus 4.8
---
src/verticals/education/build/issuer.njk | 164 ++++++++-------
src/verticals/education/build/verifier.njk | 185 +++++++++--------
src/verticals/government/build/issuer.njk | 167 +++++++++-------
src/verticals/government/build/verifier.njk | 189 ++++++++++--------
src/verticals/supply-chain/build/issuer.njk | 166 ++++++++-------
src/verticals/supply-chain/build/verifier.njk | 185 +++++++++--------
6 files changed, 614 insertions(+), 442 deletions(-)
diff --git a/src/verticals/education/build/issuer.njk b/src/verticals/education/build/issuer.njk
index d6e0c0e..6546c4b 100644
--- a/src/verticals/education/build/issuer.njk
+++ b/src/verticals/education/build/issuer.njk
@@ -1,128 +1,158 @@
---
title: "Build an issuer — academic credentials"
-description: "Issue diplomas over VCALM in 3 steps: start an exchange, deliver a signed VC, confirm. Server-side HTTP quick start."
+description: "Issue diplomas as a VCALM coordinator: create an exchange, share an interaction URL, poll for the result. A workflow service does the protocol work."
permalink: /education/build/issuer/
---
-{# Layer 4 — issuer coordinator quick start. The recommended path is the
- @bedrock/vc-delivery server; the raw HTTP loop below shows what it runs. #}
+{# Layer 4 — issuer coordinator. A coordinator is a CLIENT of a workflow
+ service; it does not run @bedrock/vc-delivery itself. It only creates
+ exchanges, hosts/shares interaction URLs, and polls for results. #}
Build an issuer
- You run the university side: start an exchange and deliver a signed diploma
- credential into the graduate's wallet — over the same VCALM exchange loop
- the wallet speaks.
+ You run the university side. To issue a diploma you don't speak VCALM on the
+ wire yourself — you drive a workflow service that does. As a
+ coordinator, your whole job is three calls: create an
+ exchange, share an interaction URL that points the graduate's wallet at it,
+ then poll the exchange until the diploma has been issued.
-
Under the hood: the raw VCALM exchange
-
- Want to build your own coordinator, or just see exactly what the server does
- on the wire? It's a short HTTP loop — three things:
-
+
What the coordinator does
-
Expose an interaction URL (in a QR code or link) that advertises
- vcapi.
-
When the wallet POSTs to your exchange URL, respond with the
- diploma in a verifiablePresentation.
-
Optionally ask the wallet to authenticate first (DID Auth), then
- deliver; finish the exchange.
+
Create an exchange by POSTing the workflow's variables
+ to its exchanges endpoint.
+
Host and share an interaction URL that points the
+ graduate's wallet at that exchange.
+
Poll the exchange until it completes, then read the
+ result.
+
+ The workflow service does everything in between — protocol negotiation,
+ DID authentication, signing, talking to whatever wallet shows up — and hands
+ you back just the result.
+
-
1. Advertise the exchange
+
1. Create the exchange
- The wallet dereferences your interaction URL (iuv=1) and you
- return the protocols you support. Offer vcapi for VCALM:
+ POST to your workflow's exchanges endpoint. The body carries a
+ ttl and the variables the workflow expects — here,
+ who the diploma is for:
+ This call is authenticated (your service uses a capability or OAuth2 token).
+ On success the service returns 204 No Content with a
+ Location header — that's your exchange URL:
+
- The wallet POSTs an empty body to start. You respond with the signed diploma
- wrapped in a verifiablePresentation:
+ The exchange URL is the vcapi interaction endpoint.
+ Hosting and sharing it is the coordinator's responsibility — put it in a QR
+ code or a link, typically wrapped in a presentation request the wallet
+ understands:
- The exchange is complete when you return no
- verifiablePresentationRequest.
+ The graduate's wallet POSTs to that endpoint and runs the exchange with the
+ workflow service directly. DID authentication and credential delivery happen
+ there — you are not in that loop.
-
3. (Optional) Authenticate the holder first
+
3. Poll for the result
- To bind the diploma to a holder, respond to the wallet's first POST with a
- verifiablePresentationRequest for DID Authentication, then
- deliver on the next turn:
+ While the wallet works, GET the exchange URL (authenticated) until its
+ state is complete:
+ Verified per-step results land under
+ exchange.variables.results, keyed by the workflow's step names.
+ A complete state means the diploma was issued into the
+ graduate's wallet.
+
That's it
- A conformant education issuer is this exchange: advertise, deliver, confirm.
- The signing of the credential itself is your issuer instance's job — the
- coordinator just runs the exchange.
+ An education issuer, as a coordinator, is these three calls: create
+ an exchange, host and share the interaction URL, poll for the result.
+ Signing the diploma and speaking every wallet's protocol is the workflow
+ service's job — you just create exchanges and read what comes back.
On the wallet end, a standalone client-side VCALM library is still planned;
- until it ships, the raw HTTP flow is the supported path there. For the
- issuer/coordinator side shown here, use
+ until it ships, wallets run the exchange over the raw HTTP flow. The
+ coordinator side shown here works today against any VCALM workflow service,
+ such as one running
@bedrock/vc-delivery.
diff --git a/src/verticals/education/build/verifier.njk b/src/verticals/education/build/verifier.njk
index 3553b53..650860e 100644
--- a/src/verticals/education/build/verifier.njk
+++ b/src/verticals/education/build/verifier.njk
@@ -1,135 +1,160 @@
---
title: "Build a verifier — academic credentials"
-description: "Verify diplomas over VCALM in 3 steps: request a presentation, receive it, verify the proof. Server-side HTTP quick start."
+description: "Verify diplomas as a VCALM coordinator: create an exchange, share an interaction URL, poll for the verified result. A workflow service does the protocol work."
permalink: /education/build/verifier/
---
-{# Layer 4 — verifier coordinator quick start. The recommended path is the
- @bedrock/vc-delivery server; the raw HTTP loop below shows what it runs. #}
+{# Layer 4 — verifier coordinator. A coordinator is a CLIENT of a workflow
+ service; it does not run @bedrock/vc-delivery itself. It creates exchanges,
+ hosts/shares interaction URLs, and polls for verified results. #}
Build a verifier
- You run the admissions side: ask the applicant's wallet to present their
- diploma, then verify the proof — over the same VCALM exchange loop the
- wallet speaks.
+ You run the admissions side. You don't speak VCALM on the wire yourself; a
+ workflow service does that and verifies the diploma for you. As a
+ coordinator, your job is three calls: create an exchange,
+ share an interaction URL that points the applicant's wallet at it, then poll
+ until the verified result comes back.
-
Under the hood: the raw VCALM exchange
-
- Want to build your own coordinator, or just see exactly what the server does
- on the wire? It's a short HTTP loop — three things:
-
+
What the coordinator does
-
Expose an interaction URL that advertises vcapi.
-
When the wallet POSTs to start, respond with a
- verifiablePresentationRequest describing the diploma you
- need.
-
Receive the verifiablePresentation and verify its proof,
- challenge, and domain.
+
Create an exchange against a workflow that requests the
+ diploma and names the institutions you trust.
+
Host and share an interaction URL that points the
+ applicant's wallet at that exchange.
+
Poll the exchange until it completes, then read the
+ verified result.
+
+ The workflow service does the rest — it sends the presentation request,
+ receives the wallet's response, and verifies the proof, challenge, domain,
+ trusted issuer, and status before it ever returns a result to you.
+
-
1. Request the diploma
+
1. Create the exchange
- When the wallet POSTs an empty body to your exchange URL, respond with a
- QueryByExample asking for the credential type you need:
+ POST to your workflow's exchanges endpoint. The workflow already
+ encodes request a university degree and trust this
+ institution; you pass just the per-exchange variables:
- The challenge and domain are what you'll verify in
- the returned proof — they stop a captured presentation from being replayed.
- Use trustedIssuer to require a degree from a specific
- institution.
+ This call is authenticated. On success the service returns
+ 204 No Content with a Location header — your
+ exchange URL:
+
+ The workflow's challenge and domain stop a captured
+ presentation from being replayed; its trustedIssuer setting
+ requires a degree from a specific institution.
-
2. Receive the presentation
+
2. Host and share the interaction URL
- The wallet POSTs the signed presentation back to the same exchange URL:
+ The exchange URL is the vcapi interaction endpoint.
+ Hosting and sharing it is the coordinator's responsibility — put it in a QR
+ code or a link, typically wrapped in a presentation request:
+ A complete state means the workflow service already verified the
+ presentation for you — proof, challenge, domain, trusted issuer, and
+ revocation/expiry status. The verified result lands under
+ exchange.variables.results, keyed by the workflow's step names.
+
That's it
- A conformant education verifier is this exchange: request, receive, verify.
- The cryptographic verification itself is your verifier instance's job — the
- coordinator just runs the exchange.
+ An education verifier, as a coordinator, is these three calls: create
+ an exchange, host and share the interaction URL, poll for the verified
+ result. The cryptographic verification and protocol interop are the
+ workflow service's job — you create exchanges and read what comes back.
On the wallet end, a standalone client-side VCALM library is still planned;
- until it ships, the raw HTTP flow is the supported path there. For the
- verifier/coordinator side shown here, use
+ until it ships, wallets run the exchange over the raw HTTP flow. The
+ coordinator side shown here works today against any VCALM workflow service,
+ such as one running
@bedrock/vc-delivery.
diff --git a/src/verticals/government/build/issuer.njk b/src/verticals/government/build/issuer.njk
index b159028..2bb6f4e 100644
--- a/src/verticals/government/build/issuer.njk
+++ b/src/verticals/government/build/issuer.njk
@@ -1,125 +1,158 @@
---
title: "Build an issuer (DMV) — mobile driver's license"
-description: "Issue a mobile driver's license over VCALM in 3 steps: start an exchange, deliver a signed VC, confirm. Server-side HTTP quick start."
+description: "Issue a mobile driver's license as a VCALM coordinator: create an exchange, share an interaction URL, poll for the result. A workflow service does the protocol work."
permalink: /government/build/issuer/
---
-{# Layer 4 — issuer coordinator. The recommended path is the
- @bedrock/vc-delivery server; the raw HTTP loop below shows what it runs. #}
+{# Layer 4 — issuer coordinator. A coordinator is a CLIENT of a workflow
+ service; it does not run @bedrock/vc-delivery itself. It only creates
+ exchanges, hosts/shares interaction URLs, and polls for results. #}
Build an issuer
- You run the DMV side: start an exchange and deliver a signed mobile license
- into the resident's wallet — over the same VCALM exchange loop the wallet
- speaks.
+ You run the DMV side. To issue a mobile license you don't speak VCALM on the
+ wire yourself — you drive a workflow service that does. As a
+ coordinator, your whole job is three calls: create an
+ exchange, share an interaction URL that points the resident's wallet at it,
+ then poll the exchange until the wallet has been issued the license.
-
Under the hood: the raw VCALM exchange
-
- Want to build your own coordinator, or just see exactly what the server does
- on the wire? It's a short HTTP loop — three things:
-
+
What the coordinator does
-
Expose an interaction URL (in a QR code or link) that advertises
- vcapi.
-
Authenticate the resident, then deliver the license in a
- verifiablePresentation.
-
Finish the exchange.
+
Create an exchange by POSTing the workflow's variables
+ to its exchanges endpoint.
+
Host and share an interaction URL that points the
+ resident's wallet at that exchange.
+
Poll the exchange until it completes, then read the
+ result.
+
+ The workflow service does everything in between — protocol negotiation,
+ DID authentication, signing, talking to whatever wallet shows up — and hands
+ you back just the result.
+
-
1. Advertise the exchange
+
1. Create the exchange
- The wallet dereferences your interaction URL (iuv=1) and you
- return the protocols you support. Offer vcapi for VCALM:
+ POST to your workflow's exchanges endpoint. The body carries a
+ ttl and the variables the workflow expects — here,
+ who the license is for:
+ This call is authenticated (your service uses a capability or OAuth2 token).
+ On success the service returns 204 No Content with a
+ Location header — that's your exchange URL:
+
- Identity credentials should be bound to the holder. Respond to the wallet's
- first POST with a DID Authentication request:
+ The exchange URL is the vcapi interaction endpoint.
+ Hosting and sharing it is the coordinator's responsibility — put it in a QR
+ code or a link, typically wrapped in a presentation request the wallet
+ understands:
On the next turn, deliver the signed mobile license:
+
+ The resident's wallet POSTs to that endpoint and runs the exchange with the
+ workflow service directly. DID authentication and credential delivery happen
+ there — you are not in that loop.
+
+
+
3. Poll for the result
+
+ While the wallet works, GET the exchange URL (authenticated) until its
+ state is complete:
+
- The exchange is complete when you return no
- verifiablePresentationRequest.
+ Verified per-step results land under
+ exchange.variables.results, keyed by the workflow's step names.
+ A complete state means the mobile license was issued into the
+ resident's wallet.
That's it
- A conformant DMV issuer is this exchange: advertise, authenticate, deliver,
- confirm. Signing the credential is your issuer instance's job — the
- coordinator just runs the exchange.
+ A DMV issuer, as a coordinator, is these three calls: create an
+ exchange, host and share the interaction URL, poll for the result.
+ Signing the license and speaking every wallet's protocol is the workflow
+ service's job — you just create exchanges and read what comes back.
On the wallet end, a standalone client-side VCALM library is still planned;
- until it ships, the raw HTTP flow is the supported path there. For the
- issuer/coordinator side shown here, use
+ until it ships, wallets run the exchange over the raw HTTP flow. The
+ coordinator side shown here works today against any VCALM workflow service,
+ such as one running
@bedrock/vc-delivery.
diff --git a/src/verticals/government/build/verifier.njk b/src/verticals/government/build/verifier.njk
index 6778162..2881362 100644
--- a/src/verticals/government/build/verifier.njk
+++ b/src/verticals/government/build/verifier.njk
@@ -1,132 +1,163 @@
---
title: "Build a verifier (relying party) — mobile driver's license"
-description: "Verify a mobile driver's license over VCALM in 3 steps: request, receive, verify. Selective disclosure — prove age without revealing identity. HTTP quick start."
+description: "Verify a mobile driver's license as a VCALM coordinator: create an exchange, share an interaction URL, poll for the verified result. Selective disclosure — prove age without revealing identity."
permalink: /government/build/verifier/
---
-{# Layer 4 — verifier coordinator. The recommended path is the
- @bedrock/vc-delivery server; the raw HTTP loop below shows what it runs.
- Highlights selective disclosure (prove "over 21" without birthdate). #}
+{# Layer 4 — verifier coordinator. A coordinator is a CLIENT of a workflow
+ service; it does not run @bedrock/vc-delivery itself. It creates exchanges,
+ hosts/shares interaction URLs, and polls for verified results. The workflow
+ here requests only "over 21" — selective disclosure. #}
Build a verifier
- You run the relying-party side — a bar, an airport, a website. You ask the
- resident's wallet to present just what you need, then verify the proof, over
- the same VCALM exchange loop the wallet speaks.
+ You run the relying-party side — a bar, an airport, a website. You don't
+ speak VCALM on the wire yourself; a workflow service does that and
+ verifies the proof for you. As a coordinator, your job is
+ three calls: create an exchange, share an interaction URL that points the
+ resident's wallet at it, then poll until the verified result comes back.
-
Under the hood: the raw VCALM exchange
-
- Want to build your own coordinator, or just see exactly what the server does
- on the wire? It's a short HTTP loop — three things:
-
+
What the coordinator does
-
Expose an interaction URL that advertises vcapi.
-
When the wallet POSTs to start, respond with a
- verifiablePresentationRequest for only the fields you need.
-
Receive the verifiablePresentation and verify its proof,
- challenge, and domain.
+
Create an exchange against a workflow that requests only
+ what you need — here, proof of age.
+
Host and share an interaction URL that points the
+ resident's wallet at that exchange.
+
Poll the exchange until it completes, then read the
+ verified result.
+
+ The workflow service does the rest — it sends the presentation request,
+ receives the wallet's response, and verifies the proof, challenge, domain,
+ issuer, and status before it ever returns a result to you.
+
-
1. Request only what you need
+
1. Create the exchange
- Don't ask for the whole license. Request a single attribute — here, proof of
- age — so the resident reveals nothing more:
+ POST to your workflow's exchanges endpoint. The workflow already
+ encodes request only "over 21" and trust the DMV; you pass
+ just the per-exchange variables:
- With selective disclosure, a well-built wallet returns a derived proof of
- "over 21" — not the birthdate itself. The challenge and
- domain stop a captured presentation from being replayed.
+ This call is authenticated. On success the service returns
+ 204 No Content with a Location header — your
+ exchange URL:
+
+ Because the workflow asks for a single derived attribute, a well-built wallet
+ returns proof of "over 21" — not the birthdate. The workflow's
+ challenge and domain stop a captured presentation
+ from being replayed.
-
2. Receive the presentation
-
The wallet POSTs the signed presentation back to the same exchange URL:
+
2. Host and share the interaction URL
+
+ The exchange URL is the vcapi interaction endpoint.
+ Hosting and sharing it is the coordinator's responsibility — put it in a QR
+ code or a link, typically wrapped in a presentation request:
+
+ A complete state means the workflow service already verified the
+ presentation for you — proof, challenge, domain, trusted issuer, and
+ revocation/expiry status. The verified result lands under
+ exchange.variables.results, keyed by the workflow's step names.
+
That's it
- A conformant relying-party verifier is this exchange: request, receive,
- verify. The cryptographic verification is your verifier instance's job — the
- coordinator just runs the exchange.
+ A relying-party verifier, as a coordinator, is these three calls:
+ create an exchange, host and share the interaction URL, poll for the
+ verified result. The cryptographic verification and protocol interop
+ are the workflow service's job — you create exchanges and read what comes
+ back.
On the wallet end, a standalone client-side VCALM library is still planned;
- until it ships, the raw HTTP flow is the supported path there. For the
- verifier/coordinator side shown here, use
+ until it ships, wallets run the exchange over the raw HTTP flow. The
+ coordinator side shown here works today against any VCALM workflow service,
+ such as one running
@bedrock/vc-delivery.
diff --git a/src/verticals/supply-chain/build/issuer.njk b/src/verticals/supply-chain/build/issuer.njk
index 787c3e2..e457707 100644
--- a/src/verticals/supply-chain/build/issuer.njk
+++ b/src/verticals/supply-chain/build/issuer.njk
@@ -1,130 +1,158 @@
---
title: "Build an issuer (brand) — product provenance"
-description: "Issue authenticity credentials over VCALM in 3 steps: start an exchange, deliver a signed VC, confirm. Server-side HTTP quick start."
+description: "Issue authenticity credentials as a VCALM coordinator: create an exchange, share an interaction URL, poll for the result. A workflow service does the protocol work."
permalink: /supply-chain/build/issuer/
---
-{# Layer 4 — issuer coordinator. The recommended path is the
- @bedrock/vc-delivery server; the raw HTTP loop below shows what it runs. #}
+{# Layer 4 — issuer coordinator. A coordinator is a CLIENT of a workflow
+ service; it does not run @bedrock/vc-delivery itself. It only creates
+ exchanges, hosts/shares interaction URLs, and polls for results. #}
Build an issuer
- You run the brand side: start an exchange and deliver a signed authenticity
- credential into the product's wallet — over the same VCALM exchange loop
- the wallet speaks.
+ You run the brand side. To issue an authenticity credential you don't speak
+ VCALM on the wire yourself — you drive a workflow service that does.
+ As a coordinator, your whole job is three calls: create an
+ exchange, share an interaction URL that points the product's wallet at it,
+ then poll the exchange until the credential has been issued.
-
Under the hood: the raw VCALM exchange
-
- Want to build your own coordinator, or just see exactly what the server does
- on the wire? It's a short HTTP loop — three things:
-
+
What the coordinator does
-
Expose an interaction URL (on a tag, QR, or link) that advertises
- vcapi.
-
When the wallet POSTs to your exchange URL, respond with the
- authenticity credential in a verifiablePresentation.
-
Optionally bind the credential to the current owner first, then deliver;
- finish the exchange.
+
Create an exchange by POSTing the workflow's variables
+ to its exchanges endpoint.
+
Host and share an interaction URL that points the
+ product's wallet at that exchange.
+
Poll the exchange until it completes, then read the
+ result.
+
+ The workflow service does everything in between — protocol negotiation,
+ optional owner binding, signing, talking to whatever wallet shows up — and
+ hands you back just the result.
+
-
1. Advertise the exchange
+
1. Create the exchange
- The wallet dereferences your interaction URL (iuv=1) and you
- return the protocols you support. Offer vcapi for VCALM:
+ POST to your workflow's exchanges endpoint. The body carries a
+ ttl and the variables the workflow expects — here,
+ which product the credential is for:
+ This call is authenticated (your service uses a capability or OAuth2 token).
+ On success the service returns 204 No Content with a
+ Location header — that's your exchange URL:
+
- The wallet POSTs an empty body to start. You respond with the signed
- authenticity credential wrapped in a verifiablePresentation:
+ The exchange URL is the vcapi interaction endpoint.
+ Hosting and sharing it is the coordinator's responsibility — put it on a tag,
+ QR code, or link, typically wrapped in a presentation request the wallet
+ understands:
- The exchange is complete when you return no
- verifiablePresentationRequest.
+ The product's wallet POSTs to that endpoint and runs the exchange with the
+ workflow service directly. Owner binding and credential delivery happen
+ there — you are not in that loop.
-
3. (Optional) Bind to the current owner first
+
3. Poll for the result
- To tie the credential to whoever holds the product, respond to the wallet's
- first POST with a verifiablePresentationRequest for DID
- Authentication, then deliver on the next turn:
+ While the wallet works, GET the exchange URL (authenticated) until its
+ state is complete:
+ Verified per-step results land under
+ exchange.variables.results, keyed by the workflow's step names.
+ A complete state means the authenticity credential was issued
+ into the product's wallet.
+
That's it
- A conformant provenance issuer is this exchange: advertise, deliver, confirm.
- Signing the credential is your issuer instance's job — the coordinator just
- runs the exchange.
+ A provenance issuer, as a coordinator, is these three calls: create
+ an exchange, host and share the interaction URL, poll for the result.
+ Signing the credential and speaking every wallet's protocol is the workflow
+ service's job — you just create exchanges and read what comes back.
On the wallet end, a standalone client-side VCALM library is still planned;
- until it ships, the raw HTTP flow is the supported path there. For the
- issuer/coordinator side shown here, use
+ until it ships, wallets run the exchange over the raw HTTP flow. The
+ coordinator side shown here works today against any VCALM workflow service,
+ such as one running
@bedrock/vc-delivery.
diff --git a/src/verticals/supply-chain/build/verifier.njk b/src/verticals/supply-chain/build/verifier.njk
index 7df405d..af1fe29 100644
--- a/src/verticals/supply-chain/build/verifier.njk
+++ b/src/verticals/supply-chain/build/verifier.njk
@@ -1,135 +1,160 @@
---
title: "Build a verifier (buyer/retailer) — product provenance"
-description: "Verify product authenticity over VCALM in 3 steps: request a presentation, receive it, verify the proof. Server-side HTTP quick start."
+description: "Verify product authenticity as a VCALM coordinator: create an exchange, share an interaction URL, poll for the verified result. A workflow service does the protocol work."
permalink: /supply-chain/build/verifier/
---
-{# Layer 4 — verifier coordinator. The recommended path is the
- @bedrock/vc-delivery server; the raw HTTP loop below shows what it runs. #}
+{# Layer 4 — verifier coordinator. A coordinator is a CLIENT of a workflow
+ service; it does not run @bedrock/vc-delivery itself. It creates exchanges,
+ hosts/shares interaction URLs, and polls for verified results. #}
Build a verifier
- You run the buyer or retailer side: ask the product's wallet to present its
- authenticity credential, then verify the proof — over the same VCALM
- exchange loop the wallet speaks.
+ You run the buyer or retailer side. You don't speak VCALM on the wire
+ yourself; a workflow service does that and verifies the credential
+ for you. As a coordinator, your job is three calls: create
+ an exchange, share an interaction URL that points the product's wallet at it,
+ then poll until the verified result comes back.
-
Under the hood: the raw VCALM exchange
-
- Want to build your own coordinator, or just see exactly what the server does
- on the wire? It's a short HTTP loop — three things:
-
+
What the coordinator does
-
Expose an interaction URL that advertises vcapi.
-
When the wallet POSTs to start, respond with a
- verifiablePresentationRequest describing the credential you
- need.
-
Receive the verifiablePresentation and verify its proof,
- challenge, and domain.
+
Create an exchange against a workflow that requests the
+ authenticity credential and names the brands you trust.
+
Host and share an interaction URL that points the
+ product's wallet at that exchange.
+
Poll the exchange until it completes, then read the
+ verified result.
+
+ The workflow service does the rest — it sends the presentation request,
+ receives the wallet's response, and verifies the proof, challenge, domain,
+ trusted issuer, and status before it ever returns a result to you.
+
-
1. Request the credential
+
1. Create the exchange
- When the wallet POSTs an empty body to your exchange URL, respond with a
- QueryByExample asking for the credential type you need:
+ POST to your workflow's exchanges endpoint. The workflow already
+ encodes request a product passport and trust the real
+ brand; you pass just the per-exchange variables:
- The challenge and domain are what you'll verify in
- the returned proof — they stop a captured presentation from being replayed.
- Use trustedIssuer to require the credential come from the real
- brand.
+ This call is authenticated. On success the service returns
+ 204 No Content with a Location header — your
+ exchange URL:
+
+ The workflow's challenge and domain stop a captured
+ presentation from being replayed; its trustedIssuer setting
+ requires the credential come from the real brand.
-
2. Receive the presentation
+
2. Host and share the interaction URL
- The wallet POSTs the signed presentation back to the same exchange URL:
+ The exchange URL is the vcapi interaction endpoint.
+ Hosting and sharing it is the coordinator's responsibility — put it on a tag,
+ QR code, or link, typically wrapped in a presentation request:
+ A complete state means the workflow service already verified the
+ presentation for you — proof, challenge, domain, trusted issuer, and
+ revocation/expiry status. The verified result lands under
+ exchange.variables.results, keyed by the workflow's step names.
+
That's it
- A conformant provenance verifier is this exchange: request, receive, verify.
- The cryptographic verification is your verifier instance's job — the
- coordinator just runs the exchange.
+ A provenance verifier, as a coordinator, is these three calls: create
+ an exchange, host and share the interaction URL, poll for the verified
+ result. The cryptographic verification and protocol interop are the
+ workflow service's job — you create exchanges and read what comes back.
On the wallet end, a standalone client-side VCALM library is still planned;
- until it ships, the raw HTTP flow is the supported path there. For the
- verifier/coordinator side shown here, use
+ until it ships, wallets run the exchange over the raw HTTP flow. The
+ coordinator side shown here works today against any VCALM workflow service,
+ such as one running
@bedrock/vc-delivery.
From 6869e340d4e825e9d1a7f408a57a10d7e19a2ddc Mon Sep 17 00:00:00 2001
From: Derek Scruggs
Date: Mon, 8 Jun 2026 12:46:40 -0500
Subject: [PATCH 2/4] Replace government vertical with student-ID vertical.
Drop the DMV / mobile-driver's-license framing and repurpose the slot as
a digital student ID vertical: a school issues, a student holds in the
wallet of their choice, and a campus service or partner verifies.
Student IDs are identity and entitlement credentials, kept distinct from
the existing education (diploma/transcript) vertical. The selective-
disclosure anchor becomes "currently enrolled" in place of "over 21".
Verticals are collection-driven, so renaming the directory, the tag, and
the permalinks updates the nav, footer, home grid, sitemap, and llms.txt
automatically. The issuer and verifier pages keep the corrected
coordinator model (create exchange, host/share interaction URL, poll for
results) and are only re-themed.
- Rename src/verticals/government -> src/verticals/student-id and its
data file; change the collection tag to student-id.
- Rewrite index.njk, build/index.njk, and build/wallet.njk around the
student-ID story; re-theme build/issuer.njk and build/verifier.njk.
- Rename flowIcons gov* keys to studentId* and update embedded labels.
- Rename the unused government-flow.svg diagram to student-id-flow.svg.
Co-Authored-By: Claude Opus 4.8
---
src/_data/flowIcons.js | 12 +-
...overnment-flow.svg => student-id-flow.svg} | 0
src/verticals/government/index.njk | 191 -----------------
.../build/index.njk | 22 +-
.../build/issuer.njk | 46 ++--
.../build/verifier.njk | 58 +++---
.../build/wallet.njk | 26 +--
src/verticals/student-id/index.njk | 196 ++++++++++++++++++
.../student-id.json} | 2 +-
9 files changed, 279 insertions(+), 274 deletions(-)
rename src/assets/diagrams/{government-flow.svg => student-id-flow.svg} (100%)
delete mode 100644 src/verticals/government/index.njk
rename src/verticals/{government => student-id}/build/index.njk (58%)
rename src/verticals/{government => student-id}/build/issuer.njk (77%)
rename src/verticals/{government => student-id}/build/verifier.njk (69%)
rename src/verticals/{government => student-id}/build/wallet.njk (70%)
create mode 100644 src/verticals/student-id/index.njk
rename src/verticals/{government/government.json => student-id/student-id.json} (61%)
diff --git a/src/_data/flowIcons.js b/src/_data/flowIcons.js
index 0338249..2a669ab 100644
--- a/src/_data/flowIcons.js
+++ b/src/_data/flowIcons.js
@@ -88,7 +88,7 @@ export default {
`,
- govIssue: `
- The resident's wallet POSTs to that endpoint and runs the exchange with the
+ The student's wallet POSTs to that endpoint and runs the exchange with the
workflow service directly. DID authentication and credential delivery happen
there — you are not in that loop.
Verified per-step results land under
exchange.variables.results, keyed by the workflow's step names.
- A complete state means the mobile license was issued into the
- resident's wallet.
+ A complete state means the student ID was issued into the
+ student's wallet.
That's it
- A DMV issuer, as a coordinator, is these three calls: create an
+ A school issuer, as a coordinator, is these three calls: create an
exchange, host and share the interaction URL, poll for the result.
- Signing the license and speaking every wallet's protocol is the workflow
+ Signing the student ID and speaking every wallet's protocol is the workflow
service's job — you just create exchanges and read what comes back.
@@ -158,5 +158,5 @@ GET https://workflows.example/workflows/mdl-issuance/exchanges/z19xQ...
diff --git a/src/verticals/government/build/verifier.njk b/src/verticals/student-id/build/verifier.njk
similarity index 69%
rename from src/verticals/government/build/verifier.njk
rename to src/verticals/student-id/build/verifier.njk
index 2881362..691f17f 100644
--- a/src/verticals/government/build/verifier.njk
+++ b/src/verticals/student-id/build/verifier.njk
@@ -1,20 +1,20 @@
---
-title: "Build a verifier (relying party) — mobile driver's license"
-description: "Verify a mobile driver's license as a VCALM coordinator: create an exchange, share an interaction URL, poll for the verified result. Selective disclosure — prove age without revealing identity."
-permalink: /government/build/verifier/
+title: "Build a verifier (campus or partner) — digital student ID"
+description: "Verify a digital student ID as a VCALM coordinator: create an exchange, share an interaction URL, poll for the verified result. Selective disclosure — prove enrollment without revealing identity."
+permalink: /student-id/build/verifier/
---
{# Layer 4 — verifier coordinator. A coordinator is a CLIENT of a workflow
service; it does not run @bedrock/vc-delivery itself. It creates exchanges,
hosts/shares interaction URLs, and polls for verified results. The workflow
- here requests only "over 21" — selective disclosure. #}
+ here requests only "currently enrolled" — selective disclosure. #}
Build a verifier
- You run the relying-party side — a bar, an airport, a website. You don't
- speak VCALM on the wire yourself; a workflow service does that and
- verifies the proof for you. As a coordinator, your job is
- three calls: create an exchange, share an interaction URL that points the
- resident's wallet at it, then poll until the verified result comes back.
+ You run the relying-party side — a library, a lab door, a partner venue. You
+ don't speak VCALM on the wire yourself; a workflow service does that
+ and verifies the proof for you. As a coordinator, your job
+ is three calls: create an exchange, share an interaction URL that points the
+ student's wallet at it, then poll until the verified result comes back.
POST to your workflow's exchanges endpoint. The workflow already
- encodes request only "over 21" and trust the DMV; you pass
- just the per-exchange variables:
+ encodes request only "currently enrolled" and trust the
+ school; you pass just the per-exchange variables:
{% highlight "bash" %}
-POST https://workflows.example/workflows/age-check/exchanges
+POST https://workflows.example/workflows/enrollment-check/exchanges
{% endhighlight %}
{% highlight "json" %}
{
"ttl": 900,
"variables": {
- "reason": "Please prove you are over 21 to continue."
+ "reason": "Please prove you are currently enrolled to continue."
}
}
{% endhighlight %}
@@ -75,13 +75,13 @@ POST https://workflows.example/workflows/age-check/exchanges
{% highlight "http" %}
HTTP/1.1 204 No Content
-Location: https://workflows.example/workflows/age-check/exchanges/z19xQ...
+Location: https://workflows.example/workflows/enrollment-check/exchanges/z19xQ...
{% endhighlight %}
Because the workflow asks for a single derived attribute, a well-built wallet
- returns proof of "over 21" — not the birthdate. The workflow's
- challenge and domain stop a captured presentation
- from being replayed.
+ returns proof of "currently enrolled" — not the name, photo, or student
+ number. The workflow's challenge and domain stop a
+ captured presentation from being replayed.
- The resident's wallet POSTs to that endpoint and runs the exchange with the
+ The student's wallet POSTs to that endpoint and runs the exchange with the
workflow service directly. You are not in that loop.
diff --git a/src/verticals/government/build/wallet.njk b/src/verticals/student-id/build/wallet.njk
similarity index 70%
rename from src/verticals/government/build/wallet.njk
rename to src/verticals/student-id/build/wallet.njk
index 03bb735..1100e92 100644
--- a/src/verticals/government/build/wallet.njk
+++ b/src/verticals/student-id/build/wallet.njk
@@ -1,12 +1,12 @@
---
-title: "VCALM tutorial: build a wallet — mobile driver's license"
-description: "Make your wallet speak VCALM in 3 steps: dereference, POST to start, loop. HTTP example for mobile driver's licenses and digital ID."
-permalink: /government/build/wallet/
+title: "VCALM tutorial: build a wallet — digital student ID"
+description: "Make your wallet speak VCALM in 3 steps: dereference, POST to start, loop. HTTP example for digital student IDs."
+permalink: /student-id/build/wallet/
---
-{# Layer 4 — exchange client. Same VCALM loop, mDL credential. #}
+{# Layer 4 — exchange client. Same VCALM loop, student-ID credential. #}
Build a wallet
-
Make your wallet speak VCALM: pick up and present a mobile license over an exchange.
+
Make your wallet speak VCALM: pick up and present a student ID over an exchange.
When the server returns a verifiablePresentationRequest, find
- the matching license, build a signed Verifiable Presentation — disclosing
+ the matching student ID, build a signed Verifiable Presentation — disclosing
only the requested fields — and POST it back to the same exchange
URL. When the server returns a verifiablePresentation,
store the delivered credential. The exchange is done when the server stops
@@ -53,7 +53,7 @@ Content-Type: application/json
That's it
-
A conformant mobile-license wallet is this loop. Nothing more.
+
A conformant student-ID wallet is this loop. Nothing more.
Prefer a library to raw HTTP?
@@ -69,5 +69,5 @@ Content-Type: application/json
diff --git a/src/verticals/student-id/index.njk b/src/verticals/student-id/index.njk
new file mode 100644
index 0000000..421b067
--- /dev/null
+++ b/src/verticals/student-id/index.njk
@@ -0,0 +1,196 @@
+---
+title: "Student IDs & campus credentials with VCALM"
+shortName: "Student IDs"
+cardTitle: "Student IDs & campus credentials"
+summary: "Issue student IDs students control — verifiable across campus and beyond, with any wallet."
+description: "Issue digital student IDs with W3C Verifiable Credentials over VCALM — student-controlled, any wallet, no allow-lists, privacy by design. Prove enrollment without revealing identity."
+order: 3
+permalink: /student-id/
+---
+{# Single-page student-ID vertical. Anchor: digital campus/student ID.
+ Distinct from the education (diploma) vertical — this is identity and
+ entitlement, not transcripts. Lean on wallet-choice / no-allow-list /
+ privacy — the student-liberty angle. #}
+
+
+
{{ title }}
+
+ Issue student IDs that students truly control — verifiable across campus and
+ with partners, in person or online, with the wallet of their choice, and
+ without locking students to a school-approved app.
+
+
+ To issue a digital student ID, a school signs it as a
+ W3C Verifiable Credential and delivers it to the student's
+ wallet of choice over VCALM (the VC API). A campus service
+ or partner verifies it cryptographically — in person or online — and with
+ selective disclosure the student can prove one fact, like "currently
+ enrolled," without revealing their name, photo, or student number.
+
+
+
+
+ {% set flowSteps = [
+ {icon: flowIcons.studentIdIssue, label: "School issues a student ID", caption: "Student picks their own wallet -- no school-mandated app"},
+ {icon: flowIcons.studentIdHold, label: "Student holds and controls it", caption: "Nothing shared without one-tap, explicit consent"},
+ {icon: flowIcons.studentIdDisclose, label: "Proves one fact", caption: "Currently enrolled -- no name, photo, or student number revealed"}
+ ] %}
+ {% set flowFooter = "Any conformant wallet -- no school-mandated app -- selective disclosure by design" %}
+ {% include "partials/flow-diagram.njk" %}
+
+
+
+
What it feels like to use
+
+ The technology is invisible by design. Here's what each person actually
+ does — and what they no longer have to.
+
+
+
+
+
The school issues a student ID
+
+ A student requests their digital ID from the registrar portal or campus
+ app. They authenticate once, pick the wallet they already use, and the
+ ID lands in it — alongside their physical card.
+
+
No school-mandated app. Their wallet, their choice.
+
+
+
The student holds and controls it
+
+ The student ID lives on their phone, under their control. Nothing is
+ shared automatically — every presentation needs an explicit, one-time
+ approval the student sees and consents to.
+
+
The school can't watch where it's used.
+
+
+
They prove just one thing, when needed
+
+ At the library or a lab door, the student taps to prove "currently
+ enrolled" — and reveals nothing else. No name, no photo, no student
+ number. At a partner venue offering a student discount, they share
+ exactly the field asked for, and no more.
+
+
Selective disclosure: minimum data, every time.
+
+
+
+
+
+
{{ flowIcons.person | safe }}What the student experiences
+
+
Their choice of wallet. Not a single school-approved app.
+
Prove a fact, not your identity. "Currently enrolled" without your student number.
+
One-tap consent. Nothing leaves the phone without approval.
+
No tracking. The school doesn't see each place it's used.
+
+
+
+
{{ flowIcons.institution | safe }}What the school experiences
+
+
Privacy by design. Data minimization is built into every request.
+
Instant, tamper-evident checks. No call-backs to the registrar.
+
No vendor or wallet lock-in. Works with every conformant wallet.
+
Standards-based. Built on open W3C Verifiable Credentials.
A student ID is signed JSON the student holds and controls.
+
+ Delivery (school → student) and
+ presentation (student → verifier) are the same simple
+ exchange loop: POST, read what the server wants, POST back.
+
+
+ With selective disclosure, the student can prove a single fact —
+ "currently enrolled," "valid student" — without revealing name, photo, or
+ student number.
+
+
+
+
+
+
A good fit if…
+
+
You issue identity or entitlement credentials to students.
+
You want students to choose their own wallet, not an approved list.
+
You need selective disclosure — prove a fact without revealing everything.
Can a student ID prove enrollment without revealing identity?
+
+ Yes. With selective disclosure, a student proves a single fact —
+ "currently enrolled," "valid student" — without revealing name, photo, or
+ student number.
+
+
+
Does a digital student ID lock students to a school app?
+
+ Not with VCALM — the student ID works with any conformant wallet. The
+ OpenID/mdoc approach often pairs with attestation and allow-lists that let
+ the school decide which apps are accepted.
+
+
+
Is a VCALM student ID private?
+
+ Yes. Data minimization is built into every request, nothing is shared
+ without one-tap consent, and the school can't see where it's used.
+
+
+
Why VCALM vs. OID4?
+
+ The OID4VCI / OID4VP, mdoc-centric approach often pairs with wallet
+ "attestation" and allow-lists — which means the school has to certify, and
+ build and maintain an integration for, every wallet it wants to support.
+ With VCALM, you issue once to an open standard and any conformant wallet
+ works, so there's no per-wallet integration to own. See
+ the full comparison.
+
+
+
diff --git a/src/verticals/government/government.json b/src/verticals/student-id/student-id.json
similarity index 61%
rename from src/verticals/government/government.json
rename to src/verticals/student-id/student-id.json
index f141cce..d8c3cab 100644
--- a/src/verticals/government/government.json
+++ b/src/verticals/student-id/student-id.json
@@ -1,4 +1,4 @@
{
"layout": "layouts/base.njk",
- "tags": "government"
+ "tags": "student-id"
}
From e4c11423006d2ff12c13d6349b355218f5863356 Mon Sep 17 00:00:00 2001
From: Derek Scruggs
Date: Mon, 8 Jun 2026 12:49:07 -0500
Subject: [PATCH 3/4] Clarify that coordinators speak VCALM, not VCALM
delivery.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The build pages said a coordinator does not "speak VCALM on the wire."
That implies the coordinator is outside VCALM entirely. It is not — the
create-exchange / host-interaction-URL / poll API is itself the
coordinator side of VCALM.
Reword the six issuer/verifier intros: a coordinator speaks VCALM, just
not VCALM delivery — the on-the-wire exchange loop with the wallet, which
the workflow service handles. Also scope "the protocol mess" to "VCALM
delivery" rather than VCALM as a whole.
Co-Authored-By: Claude Opus 4.8
---
src/verticals/education/build/issuer.njk | 9 +++++----
src/verticals/education/build/verifier.njk | 10 ++++++----
src/verticals/student-id/build/issuer.njk | 9 +++++----
src/verticals/student-id/build/verifier.njk | 10 ++++++----
src/verticals/supply-chain/build/issuer.njk | 9 +++++----
src/verticals/supply-chain/build/verifier.njk | 10 ++++++----
6 files changed, 33 insertions(+), 24 deletions(-)
diff --git a/src/verticals/education/build/issuer.njk b/src/verticals/education/build/issuer.njk
index 6546c4b..3d540d8 100644
--- a/src/verticals/education/build/issuer.njk
+++ b/src/verticals/education/build/issuer.njk
@@ -9,9 +9,10 @@ permalink: /education/build/issuer/
Build an issuer
- You run the university side. To issue a diploma you don't speak VCALM on the
- wire yourself — you drive a workflow service that does. As a
- coordinator, your whole job is three calls: create an
+ You run the university side. As a coordinator you speak
+ VCALM — just the coordinator side of it. You don't run VCALM
+ delivery, the on-the-wire exchange with the graduate's wallet; a
+ workflow service does that. Your whole job is three calls: create an
exchange, share an interaction URL that points the graduate's wallet at it,
then poll the exchange until the diploma has been issued.
Drive a workflow service — don't build the protocol
- The protocol mess — VCALM, OID4VCI, OID4VP, and interoperating with
+ The protocol mess — VCALM delivery, OID4VCI, OID4VP, and interoperating with
whatever wallet a graduate brings — is handled by a workflow
service. Digital Bazaar's
@bedrock/vc-delivery
diff --git a/src/verticals/education/build/verifier.njk b/src/verticals/education/build/verifier.njk
index 650860e..4ac9f81 100644
--- a/src/verticals/education/build/verifier.njk
+++ b/src/verticals/education/build/verifier.njk
@@ -9,9 +9,11 @@ permalink: /education/build/verifier/
Build a verifier
- You run the admissions side. You don't speak VCALM on the wire yourself; a
- workflow service does that and verifies the diploma for you. As a
- coordinator, your job is three calls: create an exchange,
+ You run the admissions side. As a coordinator you speak
+ VCALM — just the coordinator side of it. You don't run VCALM
+ delivery, the on-the-wire exchange with the applicant's wallet; a
+ workflow service does that and verifies the diploma for you. Your
+ job is three calls: create an exchange,
share an interaction URL that points the applicant's wallet at it, then poll
until the verified result comes back.
Drive a workflow service — don't build the protocol
- The protocol mess — VCALM, OID4VP, replay protection, and interoperating
+ The protocol mess — VCALM delivery, OID4VP, replay protection, and interoperating
with whatever wallet an applicant brings — is handled by a workflow
service. Digital Bazaar's
@bedrock/vc-delivery
diff --git a/src/verticals/student-id/build/issuer.njk b/src/verticals/student-id/build/issuer.njk
index a352c36..8933ec1 100644
--- a/src/verticals/student-id/build/issuer.njk
+++ b/src/verticals/student-id/build/issuer.njk
@@ -9,9 +9,10 @@ permalink: /student-id/build/issuer/
Build an issuer
- You run the school side. To issue a student ID you don't speak VCALM on the
- wire yourself — you drive a workflow service that does. As a
- coordinator, your whole job is three calls: create an
+ You run the school side. As a coordinator you speak VCALM —
+ just the coordinator side of it. You don't run VCALM delivery, the
+ on-the-wire exchange with the student's wallet; a workflow service
+ does that. Your whole job is three calls: create an
exchange, share an interaction URL that points the student's wallet at it,
then poll the exchange until the wallet has been issued the student ID.
Drive a workflow service — don't build the protocol
- The protocol mess — VCALM, OID4VCI, OID4VP, and interoperating with
+ The protocol mess — VCALM delivery, OID4VCI, OID4VP, and interoperating with
whatever wallet a student brings — is handled by a workflow
service. Digital Bazaar's
@bedrock/vc-delivery
diff --git a/src/verticals/student-id/build/verifier.njk b/src/verticals/student-id/build/verifier.njk
index 691f17f..5885733 100644
--- a/src/verticals/student-id/build/verifier.njk
+++ b/src/verticals/student-id/build/verifier.njk
@@ -10,9 +10,11 @@ permalink: /student-id/build/verifier/
Build a verifier
- You run the relying-party side — a library, a lab door, a partner venue. You
- don't speak VCALM on the wire yourself; a workflow service does that
- and verifies the proof for you. As a coordinator, your job
+ You run the relying-party side — a library, a lab door, a partner venue. As
+ a coordinator you speak VCALM — just the coordinator side of
+ it. You don't run VCALM delivery, the on-the-wire exchange with the
+ student's wallet; a workflow service does that and verifies the
+ proof for you. Your job
is three calls: create an exchange, share an interaction URL that points the
student's wallet at it, then poll until the verified result comes back.
Drive a workflow service — don't build the protocol
- The protocol mess — VCALM, OID4VP, replay protection, and interoperating
+ The protocol mess — VCALM delivery, OID4VP, replay protection, and interoperating
with whatever wallet a student brings — is handled by a workflow
service. Digital Bazaar's
@bedrock/vc-delivery
diff --git a/src/verticals/supply-chain/build/issuer.njk b/src/verticals/supply-chain/build/issuer.njk
index e457707..e9e4b0d 100644
--- a/src/verticals/supply-chain/build/issuer.njk
+++ b/src/verticals/supply-chain/build/issuer.njk
@@ -9,9 +9,10 @@ permalink: /supply-chain/build/issuer/
Build an issuer
- You run the brand side. To issue an authenticity credential you don't speak
- VCALM on the wire yourself — you drive a workflow service that does.
- As a coordinator, your whole job is three calls: create an
+ You run the brand side. As a coordinator you speak VCALM —
+ just the coordinator side of it. You don't run VCALM delivery, the
+ on-the-wire exchange with the product's wallet; a workflow service
+ does that. Your whole job is three calls: create an
exchange, share an interaction URL that points the product's wallet at it,
then poll the exchange until the credential has been issued.
Drive a workflow service — don't build the protocol
- The protocol mess — VCALM, OID4VCI, OID4VP, and interoperating with
+ The protocol mess — VCALM delivery, OID4VCI, OID4VP, and interoperating with
whatever wallet a product or owner brings — is handled by a workflow
service. Digital Bazaar's
@bedrock/vc-delivery
diff --git a/src/verticals/supply-chain/build/verifier.njk b/src/verticals/supply-chain/build/verifier.njk
index af1fe29..b80d486 100644
--- a/src/verticals/supply-chain/build/verifier.njk
+++ b/src/verticals/supply-chain/build/verifier.njk
@@ -9,9 +9,11 @@ permalink: /supply-chain/build/verifier/
Build a verifier
- You run the buyer or retailer side. You don't speak VCALM on the wire
- yourself; a workflow service does that and verifies the credential
- for you. As a coordinator, your job is three calls: create
+ You run the buyer or retailer side. As a coordinator you
+ speak VCALM — just the coordinator side of it. You don't run VCALM
+ delivery, the on-the-wire exchange with the product's wallet; a
+ workflow service does that and verifies the credential
+ for you. Your job is three calls: create
an exchange, share an interaction URL that points the product's wallet at it,
then poll until the verified result comes back.
Drive a workflow service — don't build the protocol
- The protocol mess — VCALM, OID4VP, replay protection, and interoperating
+ The protocol mess — VCALM delivery, OID4VP, replay protection, and interoperating
with whatever wallet a product or owner brings — is handled by a
workflow service. Digital Bazaar's
@bedrock/vc-delivery
From 22a11211c0b0bcbb437fa283f4e0e72c81781089 Mon Sep 17 00:00:00 2001
From: Derek Scruggs
Date: Mon, 8 Jun 2026 12:55:15 -0500
Subject: [PATCH 4/4] Reword "buy off the shelf" to "use off the shelf".
Co-Authored-By: Claude Opus 4.8
---
src/verticals/education/build/issuer.njk | 2 +-
src/verticals/education/build/verifier.njk | 2 +-
src/verticals/student-id/build/issuer.njk | 2 +-
src/verticals/student-id/build/verifier.njk | 2 +-
src/verticals/supply-chain/build/issuer.njk | 2 +-
src/verticals/supply-chain/build/verifier.njk | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/verticals/education/build/issuer.njk b/src/verticals/education/build/issuer.njk
index 3d540d8..841c132 100644
--- a/src/verticals/education/build/issuer.njk
+++ b/src/verticals/education/build/issuer.njk
@@ -28,7 +28,7 @@ permalink: /education/build/issuer/
is one. The workflow service runs that library; you don't.
- A goal of VCALM is to let you buy a workflow service off the shelf. An
+ A goal of VCALM is to let you use a workflow service off the shelf. An
administrator loads the workflows you need (a reusable issuance
config — what to issue, what to ask for). From then on, whenever a graduate
action requires a credential exchange, you create an exchange against that
diff --git a/src/verticals/education/build/verifier.njk b/src/verticals/education/build/verifier.njk
index 4ac9f81..3bdf61c 100644
--- a/src/verticals/education/build/verifier.njk
+++ b/src/verticals/education/build/verifier.njk
@@ -29,7 +29,7 @@ permalink: /education/build/verifier/
is one. The workflow service runs that library; you don't.
- A goal of VCALM is to let you buy a workflow service off the shelf. An
+ A goal of VCALM is to let you use a workflow service off the shelf. An
administrator loads a workflow (a reusable verification config —
what to request, which institutions to trust, what counts as valid). From
then on, whenever an applicant action needs a check, you create an exchange
diff --git a/src/verticals/student-id/build/issuer.njk b/src/verticals/student-id/build/issuer.njk
index 8933ec1..095abdc 100644
--- a/src/verticals/student-id/build/issuer.njk
+++ b/src/verticals/student-id/build/issuer.njk
@@ -28,7 +28,7 @@ permalink: /student-id/build/issuer/
is one. The workflow service runs that library; you don't.
- A goal of VCALM is to let you buy a workflow service off the shelf. An
+ A goal of VCALM is to let you use a workflow service off the shelf. An
administrator loads the workflows you need (a reusable issuance
config — what to issue, what to ask for). From then on, whenever a student
action requires a credential exchange, you just create an exchange against
diff --git a/src/verticals/student-id/build/verifier.njk b/src/verticals/student-id/build/verifier.njk
index 5885733..4041a62 100644
--- a/src/verticals/student-id/build/verifier.njk
+++ b/src/verticals/student-id/build/verifier.njk
@@ -30,7 +30,7 @@ permalink: /student-id/build/verifier/
is one. The workflow service runs that library; you don't.
- A goal of VCALM is to let you buy a workflow service off the shelf. An
+ A goal of VCALM is to let you use a workflow service off the shelf. An
administrator loads a workflow (a reusable verification config —
what to request, which schools to trust, what counts as valid). From then
on, whenever a student action needs a check, you create an exchange and
diff --git a/src/verticals/supply-chain/build/issuer.njk b/src/verticals/supply-chain/build/issuer.njk
index e9e4b0d..92c64b8 100644
--- a/src/verticals/supply-chain/build/issuer.njk
+++ b/src/verticals/supply-chain/build/issuer.njk
@@ -28,7 +28,7 @@ permalink: /supply-chain/build/issuer/
is one. The workflow service runs that library; you don't.
- A goal of VCALM is to let you buy a workflow service off the shelf. An
+ A goal of VCALM is to let you use a workflow service off the shelf. An
administrator loads the workflows you need (a reusable issuance
config — what to issue, what to ask for). From then on, whenever a product
action requires a credential exchange, you create an exchange against that
diff --git a/src/verticals/supply-chain/build/verifier.njk b/src/verticals/supply-chain/build/verifier.njk
index b80d486..5f96fb3 100644
--- a/src/verticals/supply-chain/build/verifier.njk
+++ b/src/verticals/supply-chain/build/verifier.njk
@@ -29,7 +29,7 @@ permalink: /supply-chain/build/verifier/
is one. The workflow service runs that library; you don't.
- A goal of VCALM is to let you buy a workflow service off the shelf. An
+ A goal of VCALM is to let you use a workflow service off the shelf. An
administrator loads a workflow (a reusable verification config —
what to request, which brands to trust, what counts as valid). From then
on, whenever a sale or check needs it, you create an exchange and read back