โ† all docs

Credential Delivery Mechanisms

Architectural decision, 2026-06-09. Defines the full space of credential
delivery mechanisms so the National ID and Discovery work is designed against
the right model rather than as isolated features.

"Issuance" is not one thing. It is a family of delivery mechanisms with very
different security and UX properties. This document maps that space, classifies
what verifiably-go already does, and identifies the gaps that should shape the
near-term roadmap.

The two axes that matter

Every delivery mechanism is defined by two questions. Everything else (channel,
format, timing) is secondary.

  1. Who initiates? โ€” Issuer-initiated (push) vs Holder-initiated (pull).
  2. Is it bound to an authenticated identity? โ€” Anonymous (pre-auth code,
    channel-possession trust) vs Identity-bound (auth code + verified claims).
                 ANONYMOUS               IDENTITY-BOUND
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  ISSUER      โ”‚  โ‘  QR / link    โ”‚  โ‘ฅ Push to wallet     โ”‚
  INITIATES   โ”‚  โ‘ฃ PDF          โ”‚  โ‘ง DIDComm proactive  โ”‚
              โ”‚  โ‘ค Bulk         โ”‚                       โ”‚
              โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
  HOLDER      โ”‚       โ€”         โ”‚  โ‘ก Auth code flow     โ”‚
  INITIATES   โ”‚  (no meaning:   โ”‚  โ‘ข Self-service from  โ”‚
              โ”‚   nothing to    โ”‚     catalog           โ”‚
              โ”‚   bind to)      โ”‚                       โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The lower-left cell is intentionally empty: a holder-initiated request with no
authenticated identity has nothing to bind the credential to.

Mechanisms, mapped to the code

# Mechanism Initiator Binding Status in repo
1 OID4VCI pre-auth + QR/link Operator Anonymous โœ… Adapter.IssueToWallet โ€” current default
2 OID4VCI auth code flow Holder authenticates Identity-bound โณ National ID Nivel 2
3 Self-service from catalog Holder browses Identity-bound โณ Credential Discovery
4 PDF / printed with verifiable QR Operator Anonymous โœ… Adapter.IssueAsPDF
5 Bulk โ†’ link by email/notification Operator Anonymous โœ… Adapter.IssueBulk + async job queue
6 Push to holder's wallet Issuer pushes Identity-bound โŒ requires holder notification channel
7 Deferred issuance (approval needed) Operator, holder waits Either โŒ not implemented
8 DIDComm proactive delivery Issuer pushes Identity-bound โš ๏ธ CREDEBL supports it natively (Aries); not exposed

The structural gap

The three mechanisms in production today (1, 4, 5) all sit in the
anonymous + operator-initiated quadrant. That is correct for a guided demo,
but it has two ceilings:

  • No guarantee of who received it. A pre-auth offer does not know who
    redeems it. If the link leaks, anyone can claim the credential.
  • The operator is the bottleneck. It does not scale to "millions of citizens
    self-issue their own credential."

National ID (Nivel 2) and Credential Discovery are not loose features โ€” together
they are the move from the anonymous/operator quadrant to the
identity-bound + holder-initiated quadrant. That is why they belong together
and in this order.

Mechanisms not yet on the roadmap

Three mechanisms are worth recording now, even if not built immediately, because
they constrain whether the National ID / Discovery design is extensible.

Deferred issuance (#7)

OID4VCI formally defines it: the holder requests a credential and the issuer
responds "not ready yet, come back with this transaction_id." This is critical
for credentials that need human approval or back-office verification (e.g. a
licence a civil servant must review). Without it, every issuance must be
instantaneous โ€” unrealistic for high-value government credentials. The moment
self-service issuance is real, deferred issuance is required alongside it.

Holder notification channel (#6) โ€” unify with push revocation

This is the mirror of the already-tracked "push revocation to holder." The same
channel that pushes a revocation serves to push an issuance / renewal
(e.g. a licence expires and the State pushes the renewed one with no holder
action). The two should be designed as one holder notification channel, not
two parallel webhooks. See [ARCH] Push revocation notification to holder in
TODO.md and the Discovery [FEAT] Push notification to wallet item.

DIDComm proactive delivery (#8)

CREDEBL is Aries underneath and already performs proactive delivery over
DIDComm; verifiably-go does not expose it. For federation with entities that
already speak Aries, this may be nearly free architecturally. Worth a spike to
confirm before committing to it.

Recommended sequencing

Do not think of "National ID" and "Discovery" as features. Think of it as
completing the identity-bound quadrant, which has a natural order:

  1. Auth code flow + claim binding (National ID Nivel 2) โ€” the foundation;
    it lets any mechanism become identity-bound.
  2. Self-service catalog (Discovery) โ€” the first holder-initiated mechanism;
    depends on (1) for the subject data and eligibility evaluation.
  3. Deferred issuance โ€” needed as soon as self-service is real, because not
    every credential issues instantly.
  4. Holder notification channel (push) โ€” unifies push-issuance and
    push-revocation.

National ID first is the lowest-friction, highest-impact path: a citizen
authenticates with their national IdP โ†’ their data is already in the issuance
form โ†’ their credentials are bound to their identity โ†’ Discovery then has real
data to work with.

Source: docs/credential-delivery.md