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 on GitHub.
Registry Lab overview
Use this when you want to see the registry stack actually run end-to-end on your laptop in one command.
Registry Lab is a Docker Compose demo for the registry stack. It wires three Registry Relay instances, four Registry Notary instances, live Postgres and Zitadel services, a private OpenFn sidecar path, a static metadata publisher, and narrated demo clients into a single topology you can run on a laptop, with no production credentials and no remote services.
The goal is to let a developer, reviewer, or integrator observe every layer of the stack interacting end-to-end on local data before writing any integration code. Use Lab when you want to see the full stack interact locally; for production deployment guidance, look at each project’s own docs.
Stack commitments: interoperability, safeguards, reviewability (all three, with the distributed-custody premise visible in the federated topology).
Quickstart
Section titled “Quickstart”git clone --recurse-submodules https://github.com/jeremi/registry-labcd registry-labscripts/release-check.sh# Open output/ to inspect the demo artifactsrelease-check.sh runs fixture generation, credential generation, static metadata publication,
compose build, compose up, core smoke checks, demo client, live-service checks,
OpenFn smoke checks, live-story walkthroughs, and compose down in one pass.
The submodules use GitHub SSH URLs; configure SSH access or a Git URL rewrite before cloning
with --recurse-submodules.
Compose topology
Section titled “Compose topology”The topology runs three Relay instances, four Notary instances, live Postgres and Zitadel services, a private OpenFn sidecar, a static metadata publisher, and a narrated demo client. For service names, host ports, image sources, and network layout, see the Registry Lab reference.
Fixtures and generated credentials
Section titled “Fixtures and generated credentials”Synthetic fixtures
Section titled “Synthetic fixtures”scripts/generate-fixtures.py
is a Python PEP 723 inline-dependency script (run with uv run).
It produces three fixture files under data/:
data/civil/civil_registry.csv: children, caregivers, living adults, and deceased adults across five districts.data/social-protection/social_protection_registry.xlsx: households, household members, and enrollments with active, inactive, suspended, and review-required cases.data/health/health_registry.parquet: active, suspended, pending-renewal, and partially-serviceable facilities.
Timestamps are deterministic (2026-01-01).
The fixture generator validates that every demo scenario has representative data before writing.
The data/ directory is gitignored; only the .gitignore marker is committed.
Generated local credentials
Section titled “Generated local credentials”scripts/generate-demo-secrets.py
is a direct-executable Python script (not wrapped by uv run).
It writes a .env file (gitignored) with local demo credentials.
No raw token is committed to the repository.
The .env.example file in the repository root contains inert placeholder values only.
Generated credentials now include OpenFn sidecar caller tokens and the private
mock registry target token used by the OpenFn smoke path.
Static metadata publisher
Section titled “Static metadata publisher”scripts/publish-static-metadata.sh
reads the portable manifest at config/static-metadata/metadata.yaml and
invokes the Registry Manifest CLI to publish a static bundle into static-metadata/metadata/.
The static-metadata/ directory is gitignored except for its .gitignore.
The static-metadata-publisher service then serves that bundle at 127.0.0.1:4331.
No authentication is required for the static publisher endpoints.
The static bundle is generated from the portable metadata config, not scraped from a running Relay.
It includes the Core Public Service Vocabulary Application Profile (CPSV-AP) service catalogue
used by Registry Atlas for service-first discovery.
The catalogue preserves grouped Core Criterion and Core Evidence Vocabulary (CCCEV) evidence
options: one option can require separate civil, household, and health evidence records, while
another can require a single combined support record.
Smoke checks
Section titled “Smoke checks”scripts/smoke.sh
runs more than 30 checks against the live compose topology.
The checks cover health and readiness on all three Relay instances,
discovery endpoints on all three core Notary instances with bearer-token and x-api-key credentials,
OpenAPI endpoints on every service,
authorization scope denial responses (403 with auth.scope_denied),
positive row-read and aggregate-read responses on the social protection Relay,
claim evaluation (POST /claims/evaluate) on civil, social protection, and shared eligibility notaries,
a cross-authority result with source_count >= 2 on the shared eligibility notary,
credential-bound evaluation returning application/dc+sd-jwt,
and service-log assertions that generated raw secrets are not emitted.
Additional focused checks exercise live and adaptor-backed paths:
scripts/smoke-openfn.shverifies the OpenFn-backed Notary path through host port 4324.scripts/check-relay-postgres.shruns Relay’s ignored live Postgres tests.scripts/check-relay-zitadel.shruns Relay’s ignored Zitadel OIDC tests.scripts/smoke-oidc-relay.shstarts a temporary OIDC-protected Relay against the local Zitadel IdP.scripts/demo-live-stories.shruns narrated live-service stories for Postgres, Zitadel/OIDC, and OpenFn.
The smoke suite also checks the Registry Atlas service graph path when the sibling
registry-atlas checkout is available.
That check verifies the published CPSV-AP catalogue has at least one public service, one
requirement, multiple evidence option groups, a form, providers, and data-service routes.
All smoke requests carry the correlation ID decentralized-demo-correlation-001 by default,
overridable via the DEMO_CORRELATION_ID environment variable.
Narrated demo client
Section titled “Narrated demo client”scripts/demo-flow.py
runs three end-to-end scenarios in sequence.
Scenario 1: Birth registration to child support. Civil claim evaluation with predicate disclosure.
Scenario 2: Household benefit review. Protected row read and aggregate consultation with scope binding.
Scenario 3: Cross-authority conditional support. Multi-authority claim with source_count >= 2.
For the full narrated walkthrough, see demo flow.
All client requests are sent with the same correlation ID and saved as JSON artifacts
to the output/ directory (default DEMO_OUTPUT_DIR).
The client uses a custom Ed25519 holder key for credential binding and requires openssl
on the PATH for holder proof signing.
The demo client is started with a profile flag so it does not start alongside the background services:
docker compose -f compose.yaml --profile client run --rm demo-clientLive-service stories
Section titled “Live-service stories”scripts/demo-live-stories.sh
runs four additional narrated checks against the live-service topology:
- A live Postgres source cutover that shows new database rows becoming visible without a Relay restart.
- A Zitadel-issued JWT flow against a temporary OIDC-protected Relay.
- An OpenFn sidecar lookup behind Registry Notary, with the sidecar and mock registry kept off host ports.
- A service-first discovery story that asks Atlas to read the static CPSV-AP catalogue and select a satisfiable grouped evidence option without reading protected person-level data.
The script writes artifacts to output/live-stories/.
v0 status and caveats
Section titled “v0 status and caveats”Registry Lab is at v0.
Fixture data covers only five districts and a maximum of approximately 100 rows per dataset;
it is not representative of production scale.
Core Notary services have no healthcheck in compose; Relay services use the CLI-help healthcheck,
and the OpenFn sidecar uses an HTTP readiness healthcheck.
Static metadata is not auto-regenerated on manifest changes; you must re-run
scripts/publish-static-metadata.sh after modifying config/static-metadata/metadata.yaml.
The demo client’s output/ directory is wiped on each run.
- First run with Registry Lab: start the topology from scratch on a clean checkout.
- Demo flow walkthrough: step through the three narrated scenarios once the topology is running.
- Registry Lab reference: compose service inventory, fixture layout, smoke-check scripts, and credential types.