Registry stack documentation: machine-readable Markdown.
Index of all pages: https://docs.registrystack.org/llms.txt
Full corpus: https://docs.registrystack.org/llms-full.txt

# Evidence issuance, end to end

> Explains how Registry Notary turns typed request inputs and a configured claim into a signed evaluation or SD-JWT VC credential, including direct, wallet, federated, and receipt-only paths.

This page describes how Registry Notary turns typed request inputs and a configured claim into a
signed evaluation or verifiable credential. It is an explanation, not a how-to: there are no
commands here.
For commands, see the [Registry Notary documentation](../../products/registry-notary/) and the
[Registry Stack project authoring guide](../../tutorials/author-registry-project/).

## Why issue credentials at all

Programs and services need to know whether a person qualifies for something. The classic way to
answer that question is to demand records: birth certificates, land titles, tax statements. The
records carry far more information than the answer requires, the records live in registries the
program does not own, and the records cross trust boundaries every time a copy moves. A
credential lets a registry answer one question (does this subject satisfy this rule) without
shipping the records that justify the answer. Registry Notary is the component that produces
those credentials.

In the three-party credential model, Registry Notary is the issuer: it evaluates a configured
claim from compiler-pinned Relay outputs or permitted self-attestation, applies the disclosure
policy, and signs an SD-JWT VC.
A wallet is the holder: it stores the credential, presents fields selectively, and proves key
possession. A verifier is the relying party: it checks the issuer signature, reads the presented
fields, and applies its own program policy. What Notary produces is evidence, a signed receipt
that a claim was evaluated; the decision (whether the subject qualifies for a benefit) belongs
to the program, not to Notary.

{/* SVG diagram. Essential labels are restated in the paragraph above. */}
<figure>
  <img src="../../images/registry-notary-three-parties.svg"
       alt="Registry Notary as issuer in the three-party credential model. Registry Notary
            evaluates Relay-backed or self-attested claims, applies disclosure policy, and signs an
            SD-JWT VC. A wallet, the holder, stores the credential, presents selectively,
            and proves key possession. A verifier, the relying party, checks the issuer
            signature, reads presented fields, and applies program policy. Notary produces
            evidence, a signed receipt that a claim was evaluated; the program produces the
            decision, whether the subject qualifies for a benefit." />
</figure>

## The claim model in one diagram

A single claim evaluation moves through five stages.

{/* SVG diagram. Essential labels and option lists are restated in the prose that follows. */}
<figure>
  <img src="../../images/registry-claim-model.svg"
       alt="Claim model: five configured stages in order. (1) Typed request inputs from the
            caller. (2) A compiler-pinned Relay consultation, or permitted self-attestation.
            (3) Rule evaluation from closed inputs. (4) Disclosure mode:
            value, predicate, or redacted. (5) Evaluation render format: claim-result
            JSON or CCCEV JSON-LD.
            Eligible stored evaluations can later be materialized as SD-JWT VC credentials." />
</figure>

Registry Stack project authoring makes each stage concrete. An evidence service declares typed
request inputs, compiler-pinned consultations, claims over the closed consultation or
self-attestation inputs, disclosure modes, and optional credential profiles. Product and source
version labels record interoperability evidence. They do not select a Relay capability or script
runtime.

## Four ways to consume an evaluation

There is one claim model and four transports a caller can use to land a credential, delegated
evaluation, or receipt.

{/* SVG diagram. Essential labels are restated in the numbered list that follows. */}
<figure>
  <img src="../../images/registry-evidence-transports.svg"
       alt="Four transports for a claim evaluation, sharing one claim model. (1) Direct API:
            a backend calls /v1/evaluations; pair with /v1/credentials to mint an SD-JWT
            VC. (2) OID4VCI offer: a wallet caller discovers the issuer via /.well-known and
            completes a nonce-bound flow at /oid4vci/credential. (3) Receipt only: a backend
            calls /v1/evaluations and stores the audit-stamped result; no credential is
            issued. (4) Federated: a peer Notary posts a signed JWT to
            /federation/v1/evaluations and receives a signed JWT response." />
</figure>

1. Direct API. The caller calls `POST /v1/evaluations` to evaluate the claim, then
   `POST /v1/credentials` to materialize an SD-JWT VC from the stored evaluation. The caller
   is a backend (a program registry, a benefits portal) that holds a Registry Notary API key or
   an OIDC token. The credential ends up wherever the calling backend chooses to send it.
2. OID4VCI offer flow. The caller is a wallet, not a backend. Registry Notary publishes
   `/.well-known/openid-credential-issuer` so the wallet learns the credential endpoint, the
   nonce endpoint, and the supported credential configurations. The wallet (or a portal acting on
   the wallet's behalf) fetches a `CredentialOffer` from `GET /oid4vci/credential-offer`, the
   user authenticates at the configured authorization server, the wallet calls
   `POST /oid4vci/nonce` to get a `c_nonce`, signs a proof-of-possession JWT with its `did:jwk`
   key, and posts the bearer access token plus the proof to `POST /oid4vci/credential`. The
   choreography is implemented in the Notary server's API module at
   [`crates/registry-notary-server/src/api.rs`](https://github.com/registrystack/registry-stack/blob/v0.8.1/crates/registry-notary-server/src/api.rs).
   The offer can carry an authorization-code grant (the user authenticates at the authorization
   server, as in the authorization-code grant) or a pre-authorized-code grant; the hosted lab uses pre-authorized-code with
   eSignet (an open-source identity and e-signature platform) as the authorization server.
3. Verifiable receipt only. The caller does not need a credential at all. It calls
   `POST /v1/evaluations`, accepts the disclosure mode the claim allows (often `predicate` or
   `redacted`), and stores the audit-stamped result. Every evaluation, credential or not, is
   recorded in the JSONL audit log alongside `verification_id` and `claim_hash` for redacted
   results.
4. Federated delegated evaluation. The caller is another configured Registry Notary. It posts a
   compact signed JWT to `POST /federation/v1/evaluations`; the serving Notary verifies peer
   policy, replay state, purpose, profile, and audience before claim evaluation, then returns a
   compact signed JWT response. Federation profiles are source-free in this version and cannot
   select a `registry_backed` claim. This path returns a scoped evaluation result, not a credential.

The [credential tour](../../start/credential-tour/) citizen self-attestation scenario uses path 2:
eSignet provides the access token, Notary evaluates the permitted authenticated context without a
registry source, and a wallet completes the OID4VCI flow.

## Selective disclosure properties

Selective disclosure is the property that distinguishes an SD-JWT VC from a plain JWT.
The credential format is the IETF SD-JWT VC draft's `application/dc+sd-jwt` media type, with
`dc+sd-jwt` as the JWT `typ` header; the implementation tracks the draft family's current media
type rather than pinning a numbered draft revision, and the
[standards register](../../reference/standards/) records the claim as a profiled subset.
Three mechanics make selective disclosure work.

- Per-field disclosures. Registry Notary wraps each claim field in its own SD-JWT disclosure
  blob. The signed credential body carries the SHA-256 digest of every disclosure, not the
  disclosure value. The holder chooses which disclosures to present to which verifier; the
  unselected fields stay hidden.
- SHA-256 digests. The digest list is what the credential's signature covers. A verifier checks
  the signature, recomputes the digest of every presented disclosure, and confirms each digest
  appears in the signed list. There is no way for a holder to mint a disclosure that was not in
  the original credential.
- Holder binding via `did:jwk`. The credential's `cnf` claim names the holder's public key as a
  `did:jwk`. To present the credential, the holder must produce a fresh signed proof from that
  key, audience-bound to the verifier. A stolen credential without the matching private key is
  not presentable. Holder binding is the default: a credential profile that omits `holder_binding`
  binds with `did:jwk`, and issuing an unbound, bearer-style credential requires an explicit
  `holder_binding.mode: none`. This has been the default since v0.8.4, and `registry-notary doctor`
  warns on a profile that opts out (`notary.credential_profile.unbound_holder_binding`).

Evidence: the [v0.8.4 Notary changelog](https://github.com/registrystack/registry-stack/blob/v0.8.4/products/notary/CHANGELOG.md#084---2026-07-04) records the default, and the [configuration loader](https://github.com/registrystack/registry-stack/blob/v0.8.4/crates/registry-notary-core/src/config.rs) applies it.

The [doctor diagnostic](https://github.com/registrystack/registry-stack/blob/v0.8.4/crates/registry-notary/src/main.rs) is covered by the [doctor CLI test](https://github.com/registrystack/registry-stack/blob/v0.8.4/crates/registry-notary/tests/doctor_cli.rs).

## Where this fits with Relay

Registry Notary is an independently deployable HTTP service. A Notary-only deployment supports
source-free and self-attested claims. Registry-backed claims require Registry Relay, and a
combined deployment calls Relay through the compiler-pinned consultation contract.

Registry Relay surfaces evidence-offering metadata under `/metadata/evidence-offerings/{id}`.
The metadata document points at a Registry Notary instance, names the claim ids the offering
covers, and describes the supported disclosure modes and formats. A consumer that finds an
offering on Relay learns where to call Notary. Relay owns registry source access and typed
consultation outputs; Notary owns claim semantics, disclosure, and credential issuance.

For delegated evaluation, Registry Manifest can also publish `federation` and
`evaluation_profiles` metadata. That metadata helps a partner configure a static peer relationship.
Runtime access still comes from the serving Notary `federation.peers` policy, signed request
verification, and replay checks.

## Boundaries

A few things Registry Notary is not.

- Not an eligibility decision. The verification receipt is an evidence artifact. The issuing
  program, not Registry Notary, converts a verified claim into an entitlement, a payment, or a
  benefit.
- Not a wallet. Registry Notary issues credentials. The wallet that stores, presents, and
  unlocks them is a separate component, owned by the holder.
- Not a credential authority. The DID, the verification key, the credential profile config, and
  the relationship to the relying party belong to the deployment, not to Registry Notary as a
  product. Registry Notary ships an engine and a wire shape; the trust comes from the
  deployment.
- Not open federation. The MVP accepts only statically configured peers and delegated evaluation.
  Federated credential issuance and dynamic trust-chain discovery are not implemented.

## Next

- [Registry Notary overview](../../products/registry-notary/)
- [Glossary](../../reference/glossary/)