Preview release.These docs are a work in progress. Pages are still being written, links may break, and structure may shift without notice. Treat everything here as a draft and report issues onGitHub.
An institution that runs a civil registry, a social-protection database, or a health registry already holds the records it needs. Registry Stack lets it answer questions about those records (is this person alive? is this household eligible?) and return a result another system can trust, while the records themselves are read where they already live, never written back, and not copied into a central exchange. This page explains what that means in practice: what stays inside the institution’s boundary, what crosses it, and (equally important) what the design does and does not guarantee.
A question goes in, an answer comes out
Section titled “A question goes in, an answer comes out”The Notary mental model is one sentence: a scoped question crosses into the institution, the record is read in place, and a computed answer crosses back out.
A Notary caller never sends the value it is asking about and never receives the underlying record as the answer. It sends the id of a claim (a single, pre-modelled question) and the inputs that claim needs to resolve the subject: a subject identifier, plus, where the claim’s matching policy requires them, target or requester attributes, further identifiers, or relationship attributes. It receives one of a few narrow shapes of answer: a yes/no, a single value, a machine-readable evaluation result, or a credential the subject can carry in a wallet. The source row that the answer was computed from stays behind.
The boundary
Section titled “The boundary”flowchart LR
subgraph inst["Institution: data stays here"]
src[("Source registry\nCSV · XLSX · Parquet · PostgreSQL")]
relay["Registry Relay\nprotected read API"]
notary["Registry Notary\nevaluate · disclose · issue"]
key>"Signing key\n(private half never leaves)"]
audit[("Audit log")]
src -- read in place --> relay
relay -- governed read --> notary
notary -. records .-> audit
key -. signs .-> notary
end
caller["Caller / verifier"]
holder(["Subject / wallet"])
caller == "request: claim id + subject inputs + scope" ==> notary
notary == "answer: yes/no · value · evaluation result" ==> caller
notary == "issued credential" ==> holder
caller == "scoped record read" ==> relay
relay == "authorized source records" ==> caller
classDef inside fill:#eef,stroke:#334,stroke-width:1px;
classDef outside fill:#f7f7f7,stroke:#777,stroke-dasharray:3 3;
class src,relay,notary,key,audit inside;
class caller,holder outside;
Two governed surfaces can cross the boundary. Registry Relay turns an existing file or database table into a read-only, access-controlled API without replacing the source. Its scoped record routes can return source records to authorized callers that hold the dataset’s row-read permission. Registry Notary evaluates one modelled question against that source and returns a shaped answer; it is the only component that evaluates claims, applies disclosure policy, and issues credentials. Notary is the strongest minimization surface. Relay record reads are scoped and audited, not open data.
What stays home
Section titled “What stays home”- Source data is read in place: Relay reads sources as batch snapshots or table scans;
there is no write-back to the source registry, and runtime services expose no
data-mutation routes. The source keeps running as it always has. “No write-back to the
source and no external handoff” is not the same as “no copy exists”: in snapshot mode
(the default), Relay materializes a projected copy into its local cache (
cache_dir), which carries its own retention and access considerations. - Storage internals stay private: The paths, table names, and backend credentials that point at the source live in the service’s runtime configuration, decided at startup. They are never part of the public API surface, and never part of a portable metadata file that gets distributed.
- The institution keeps custody: The design premise is distributed custody: each authority retains control of its own registry data, and the stack does not aggregate records into a central system. It provides the exchange surface, not a data lake.
- Private signing keys never leave the issuer: The institution publishes the public half of its signing key so anyone can verify a signed credential or signed result; the private half stays inside.
What crosses the boundary
Section titled “What crosses the boundary”What crosses depends on the surface. Registry Relay can return scoped source records to an authorized caller through a governed, audited read bounded by the caller’s per-dataset row scope and the dataset’s configured filters and limits. Registry Notary returns the answer a rule computes rather than the source row; keeping that answer narrow is a modelling discipline, because a well-modelled claim returns one decision or one extracted value. A Notary answer takes one of a few shapes:
- A yes/no: only the true/false satisfaction of the modelled rule.
- A single value: the evaluated value itself, when the claim’s disclosure mode is
value(this returns the full value). - A machine-readable evaluation result: a claim-result document carrying provenance metadata: which evaluation produced it, under which policy, across how many sources. This provenance lets a receiving system trace the result; it is not a cryptographic signature.
- An issued credential: an SD-JWT VC the subject can store in a wallet and present later. Unlike the plain result, the credential is cryptographically verifiable against the issuer’s published keys. Credential profiles are holder-bound by default, but an operator can explicitly configure an unbound profile.
Across a federation boundary (one institution’s Notary asking another’s), what crosses is a scoped, signed evaluation result, never a credential.
How much an answer reveals: the three disclosure modes
Section titled “How much an answer reveals: the three disclosure modes”Every claim carries a disclosure mode that fixes how much of the answer the caller receives. There are exactly three:
| Mode | Discloses | Withholds |
|---|---|---|
value | the evaluated value, less any object fields the policy redacts | nothing beyond policy-redacted object fields |
predicate | only the true/false satisfaction, for a claim whose rule yields a boolean | the underlying value |
redacted | neither: the result carries no value and no yes/no | the value and the outcome |
The mode is policy-bound: a claim defines an allowed set, a default, and a downgrade
policy.
A caller may request a mode.
Under the default deny downgrade, the service refuses a requested mode outside the
allowed set; a default or redacted downgrade substitutes that fallback mode when the
fallback is itself allowed.
The default mode applies when the caller requests none, and every result records which
mode was applied.
A privacy-sensitive claim is expected to default to the least-revealing mode that still
answers the question.
This is the mechanism behind “prove a fact without sharing the record”. To check whether a
person has a registered record, model the question as an existence rule and disclose it
as a predicate: a resolved record returns true, and the row never crosses the
boundary.
By default, a record that does not resolve collapses to a single not-available reason
rather than a false, which hides the reason matching failed. An authorized caller can
still distinguish a resolved record from a not-available response, so use this pattern for
minimization, not for hiding whether a requested subject matched.
To check eligibility without exposing an income figure, derive the decision with an
expression rule and disclose the eligibility boolean as a predicate; the income value
stays home.
Why the answer is not the record
Section titled “Why the answer is not the record”A credential is not a copy of the record. It is an SD-JWT VC: the signed body carries a
SHA-256 digest of each selectively disclosable field rather than the field value, so a
field the holder does not present stays hidden.
Holder binding is set by the credential profile.
By default, a profile with no holder_binding block uses did:jwk holder binding.
A holder-bound profile ties the credential to the holder’s key so it is not presentable
without the matching private key; an operator that intentionally needs a bearer-style
credential can set holder_binding.mode: none.
Each selectively disclosable field is a whole claim output, so an object-valued output is
revealed as a unit unless an explicit projection splits it into separately disclosable
fields.
Anyone can verify the credential against the issuer’s published public keys, served
without authentication so a verifier needs no credential of its own.
The issued credential carries no full record payload.
How the boundary is enforced
Section titled “How the boundary is enforced”The “stays home” property rests on a few enforced rules, covered in depth in the Trust & Security material:
- Scope-before-source, deny-by-default: A service checks the caller’s scope before it reads any source or evaluates any claim, and does not widen a caller’s reach at request time beyond what its configuration grants. Anything that touches a record or a claim requires authentication. Routes reachable without it return no record or claim result on their own: liveness and readiness probes, public verification keys, public metadata, and, where OID4VCI issuance or credential status is enabled, the protocol surfaces that run their own flow checks.
- A permit, or a closed door: On a governed read, the policy decision point must return a permit before data is returned; a denial fails closed with a stable reason rather than falling back to an ungoverned read.
- Every person-level request is audited: An audit record captures at least the caller, the scopes exercised, a request id, and the declared purpose where one was supplied. A deployment can run audit fail-closed, so a request whose audit record cannot be written does not return success.
What this guarantees, and what it does not
Section titled “What this guarantees, and what it does not”“Records stay home” is a precise, narrow promise.
- It is not “data never moves” and not “air-gapped”: The promise is read-in-place, no write-back, retained custody. Authorized, minimized answers do leave the boundary by design: that is the point of the system.
- Minimization is modelled, not automatic:
valuemode discloses the evaluated value, less any object fields the policy marks for redaction; it is not constrained to a scalar, so a claim modelled to return an object or extracted record returns one. A claim reveals only what its author configured it to reveal; least disclosure is a design choice the claim makes, not a property the stack imposes on every answer. - Correctness depends on the source: Notary reports what the configured source says; it does not independently vouch for whether the source is correct or current.
- A plain result is provenance-tagged, not signed: The everyday evaluation response carries provenance metadata, not a cryptographic signature. Cryptographic verifiability comes from the SD-JWT VC credential and the signed federation result: a receiving system that must verify an answer cryptographically uses the credential, not the default response.
- Matching is only as strict as it is configured: Notary resolves a subject through its configured matching policy and does not independently verify identity beyond that. By default a matching failure collapses to a single public reason, but an authorized caller can still tell a resolved record from a not-available response.
- This is not zero-knowledge: A
predicateanswer is a policy-enforced boolean computed inside the service; SD-JWT selective disclosure is digest omission. Neither is a zero-knowledge proof.
This page’s promise also sits inside the wider set of stack-wide limits: revocation and erasure gaps, which guarantees are left to the operator to provide, and the draft status of the underlying specifications. Weigh those alongside the limits in this section; see the known limitations hub for the full inventory.
Related
Section titled “Related”- The security model and protocol contracts: RS-SEC-G, RS-PR-RELAY, RS-PR-NOTARY, RS-DM-CLAIM
- Evidence issuance, end to end
- Disclosure modes and computed answers
- Threat model