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
registry-backed claim from compiler-pinned Relay outputs, verifies the exact stored Relay execution
provenance and its per-claim execution binding, applies the disclosure policy,
and signs an SD-JWT VC. The unkeyed binding detects partial stored-record
mutation; store access controls remain the authenticity boundary. Permitted self-attestation
without Relay remains evaluation-only.
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 a Relay-backed claim, verifies its exact execution provenance, 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 registry-backed stored evaluations with exact Relay execution provenance 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 registry-backed credential profiles.
Private Relay execution ids are retained only for selected roots that share one
of those validated 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
            redeems an issuer-initiated pre-authorized offer, then presents a
            transaction-bound holder proof 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 token and
   credential endpoints and supported configurations. The citizen opens
   `/oid4vci/offer/start` in a browser and authenticates at the configured
   identity provider. Notary consumes that internal authorization code, derives
   the subject binding, creates the registry transaction, executes the
   compiler-pinned Relay consultation, and only then renders an
   issuer-initiated pre-authorized offer. The wallet redeems that offer, receives
   a transaction-bound proof nonce from the token response, signs an EdDSA proof
   with its `did:jwk` key, and posts the Notary access token plus proof to
   `POST /oid4vci/credential`. The wallet-facing grant is pre-authorized code
   only. Source-free and delegated evaluations cannot enter the credential
   path. Transaction code is required by default; an explicit no-PIN wallet
   profile has a maximum 300-second bearer-offer window.
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.

## 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`).
- Live status outside selective disclosure. When a credential contains a
  `status.status_list` claim, that top-level claim is always visible. A verifier
  retrieves the signed status token only from its exact configured HTTPS trusted
  origin and fails closed when status is unavailable, invalid, suspended,
  revoked, or expired.

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/)