Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ __pycache__/
dist/
.cache/
projects/*/.registry-stack/
demos/opencrvs-v2/project/.registry-stack/
demos/opencrvs-v2/.runtime/
*.log
config/postgres/ssl/*
!config/postgres/ssl/.gitkeep
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ The first wave covers three journeys:
- `portal/` contains the citizen portal and BFF.
- `scenarios/`, `requests/`, and `perf/` carry guided scenarios, API examples,
and k6 smoke coverage.
- `demos/opencrvs-v2/` contains an optional, isolated OpenCRVS interoperability
demo. Its released live path is blocked; paired candidate use is
development-only. It is not part of the six-authority topology.
- `scripts/` contains root quality gates and orchestration helpers.

## Development Commands
Expand Down Expand Up @@ -95,11 +98,31 @@ just registry-projects-review # complete redacted acquisition and disclosure rep
just registry-projects-capabilities # value-free installed/used/missing capability inventory
just registry-projects-editor # version-matched VS Code and Zed schemas for all projects
just contract-generation-proof # release-only live SRO blue/mixed/successor proof
just opencrvs-demo-test # optional OpenCRVS fixture and compiler proof
just opencrvs-demo-candidate-build <worktree> # build matched pre-release compiler and Relay
just opencrvs-demo-compose # validate the isolated demo topology
just opencrvs-demo-up # start with compatible release or paired dev artifacts
just opencrvs-demo-proof # live proof with compatible release or paired dev artifacts
just opencrvs-demo-down # remove its containers, volumes, and runtime closure
just release-pins <registry-stack-tag> # compare committed versions.env pins against a candidate or release tag
just review # normal security and release-readiness checks
just review-release <registry-stack-tag> # candidate review with published pin validation
```

The OpenCRVS demo's offline compiler, fixture, Compose, and paired pre-release
live checks pass. Its released live path remains blocked. Relay v0.15.2 has the
strict no-expiry OAuth decoder, yet its durable state plane rejects this
no-cache script plan before source dispatch. Registryctl v0.15.2 also cannot
author the profile. One exact pending Registry Stack commit enables offline
compiler development only. Pre-release live development requires Registryctl
and a labeled Relay image built from one later exact candidate commit
containing the authoring, state-plane, and active script-budget fixes. Do not
deploy the demo until a Registry Stack release contains those fixes and all
coordinated pins in `versions.env` have passed release review. The safe paired
override, exact native endpoints, cleanup sequence, privacy boundary, and
direct machine issuance limits are documented in
[`demos/opencrvs-v2/README.md`](demos/opencrvs-v2/README.md).

Normal startup pulls the immutable canonical Relay image pinned in
`versions.env`; it does not clone or compile Registry Stack. Governed attribute
release is part of the canonical Registry Stack v0.15.2 Relay build. The
Expand Down
329 changes: 329 additions & 0 deletions demos/opencrvs-v2/README.md

Large diffs are not rendered by default.

108 changes: 108 additions & 0 deletions demos/opencrvs-v2/build-candidate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ "$#" -ne 1 ]]; then
printf 'usage: %s <registry-stack-worktree>\n' "$0" >&2
exit 2
fi

stack_dir="$(cd -- "$1" && pwd -P)"
commit="$(git -C "${stack_dir}" rev-parse HEAD)"
if [[ ! "${commit}" =~ ^[0-9a-f]{40}$ ]]; then
printf 'Registry Stack HEAD must resolve to a lowercase 40-character commit SHA\n' >&2
exit 1
fi
if [[ -n "$(git -C "${stack_dir}" status --porcelain)" ]]; then
printf 'Registry Stack candidate worktree must be clean\n' >&2
exit 1
fi

builder_image='rust:1.95-trixie@sha256:f49565f188ee00bc2a18dd418183f2c5f23ef7d6e691890517ed341a598f67c3'
relay_features="$(<"${stack_dir}/crates/registry-relay/canonical-release-features.txt")"
engine_arch="$(docker version --format '{{.Server.Arch}}')"
case "${engine_arch}" in
amd64 | x86_64)
relay_arch='amd64'
;;
arm64 | aarch64)
relay_arch='arm64'
;;
*)
printf 'unsupported Docker server architecture: %s\n' "${engine_arch}" >&2
exit 1
;;
esac
relay_platform="linux/${relay_arch}"
image="registry-relay-opencrvs:${commit}-${relay_arch}"
image_version="0.15.2-opencrvs.${commit:0:12}"
linux_target="/workspace/target/opencrvs-linux-${relay_arch}"

cargo build --locked --manifest-path "${stack_dir}/Cargo.toml" \
-p registryctl --bin registryctl

docker run --rm \
--platform "${relay_platform}" \
--user "$(id -u):$(id -g)" \
--volume "${stack_dir}:/workspace" \
--workdir /workspace \
--env CARGO_HOME=/workspace/.cargo-home \
--env CARGO_INCREMENTAL=0 \
--env CARGO_TARGET_DIR="${linux_target}" \
--env HOME=/workspace \
--env REGISTRY_RELAY_FEATURES="${relay_features}" \
"${builder_image}" \
bash -c 'set -euo pipefail
cargo build --release --locked \
-p registry-relay \
--no-default-features \
--features "${REGISTRY_RELAY_FEATURES}"
python3 release/scripts/check-release-relay-features.py \
"${CARGO_TARGET_DIR}/release/registry-relay"
'

mkdir -p "${stack_dir}/dist/image-bin"
install -m 0755 \
"${stack_dir}/target/opencrvs-linux-${relay_arch}/release/registry-relay" \
"${stack_dir}/dist/image-bin/registry-relay"
install -m 0755 \
"${stack_dir}/target/opencrvs-linux-${relay_arch}/release/registry-relay-rhai-worker" \
"${stack_dir}/dist/image-bin/registry-relay-rhai-worker"

docker buildx build \
--load \
--platform "${relay_platform}" \
--file "${stack_dir}/release/docker/Dockerfile.registry-relay" \
--tag "${image}" \
--label 'org.opencontainers.image.source=https://github.com/registrystack/registry-stack' \
--label "org.opencontainers.image.revision=${commit}" \
--label "org.opencontainers.image.version=${image_version}" \
--label "org.registrystack.registry-relay.features=${relay_features}" \
--build-arg SOURCE_DATE_EPOCH=0 \
"${stack_dir}"

image_architecture="$(
docker image inspect --format '{{.Architecture}}' "${image}"
)"
image_revision="$(
docker image inspect \
--format '{{index .Config.Labels "org.opencontainers.image.revision"}}' \
"${image}"
)"
image_features="$(
docker image inspect \
--format '{{index .Config.Labels "org.registrystack.registry-relay.features"}}' \
"${image}"
)"
if [[ "${image_architecture}" != "${relay_arch}" ||
"${image_revision}" != "${commit}" ||
"${image_features}" != "${relay_features}" ]]; then
printf 'candidate Relay image identity check failed\n' >&2
exit 1
fi

printf "export OPENCRVS_DEMO_REGISTRYCTL='%s'\n" \
"${stack_dir}/target/debug/registryctl"
printf "export OPENCRVS_DEMO_REGISTRYCTL_SOURCE_COMMIT='%s'\n" "${commit}"
printf "export OPENCRVS_DEMO_RELAY_IMAGE='%s'\n" "${image}"
printf "export OPENCRVS_DEMO_RELAY_SOURCE_COMMIT='%s'\n" "${commit}"
printf "export OPENCRVS_DEMO_RELAY_PLATFORM='%s'\n" "${relay_platform}"
179 changes: 179 additions & 0 deletions demos/opencrvs-v2/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
services:
opencrvs-db:
image: ${POSTGRES_IMAGE:-postgres:16-alpine}
restart: unless-stopped
entrypoint: ["/bin/sh", "/usr/local/bin/opencrvs-postgres-entrypoint.sh"]
command:
- postgres
- -c
- ssl=on
- -c
- ssl_cert_file=/var/lib/postgresql/server-ssl/server.crt
- -c
- ssl_key_file=/var/lib/postgresql/server-ssl/server.key
environment:
POSTGRES_USER: opencrvs_admin
POSTGRES_PASSWORD: ${POSTGRES_ADMIN_PASSWORD:-compose-validation-only}
POSTGRES_DB: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U opencrvs_admin -d postgres"]
interval: 2s
timeout: 3s
retries: 30
volumes:
- opencrvs-db-data:/var/lib/postgresql/data
- ../../scripts/postgres-entrypoint.sh:/usr/local/bin/opencrvs-postgres-entrypoint.sh:ro
- ${OPENCRVS_RUNTIME_PROJECT_DIR:-./.runtime/project}/../postgres:/run/solmara-postgres-ssl:ro

opencrvs-db-init:
image: ${POSTGRES_IMAGE:-postgres:16-alpine}
restart: "no"
environment:
POSTGRES_ADMIN_PASSWORD: ${POSTGRES_ADMIN_PASSWORD:-compose-validation-only}
OPENCRVS_RELAY_POSTGRES_RUNTIME_PASSWORD: ${OPENCRVS_RELAY_POSTGRES_RUNTIME_PASSWORD:-compose-validation-only}
OPENCRVS_RELAY_POSTGRES_MAINTENANCE_PASSWORD: ${OPENCRVS_RELAY_POSTGRES_MAINTENANCE_PASSWORD:-compose-validation-only}
OPENCRVS_RELAY_POSTGRES_READER_PASSWORD: ${OPENCRVS_RELAY_POSTGRES_READER_PASSWORD:-compose-validation-only}
command: ["/opt/opencrvs-demo/postgres-init.sh"]
volumes:
- ./postgres-init.sh:/opt/opencrvs-demo/postgres-init.sh:ro
depends_on:
opencrvs-db:
condition: service_healthy

opencrvs-relay-bootstrap:
image: ${REGISTRY_RELAY_IMAGE}
platform: ${OPENCRVS_DEMO_RELAY_PLATFORM:-linux/amd64}
restart: "no"
command:
- consultation
- bootstrap-state
- --config
- /etc/registry-relay/relay-consultation.yaml
- --migration-database-url-env
- REGISTRY_RELAY_STATE_MIGRATION_URL
- --owner-role
- opencrvs_demo_owner
- --keyring-maintenance-database-url-env
- REGISTRY_RELAY_STATE_KEYRING_MAINTENANCE_URL
- --keyring-reader-database-url-env
- REGISTRY_RELAY_STATE_KEYRING_READER_URL
- --active-key-id
- epoch-1
- --active-write-deadline-unix-ms
- "4102444800000"
- --audit-event-retention-ms
- "2592000000"
environment:
REGISTRY_RELAY_AUDIT_HASH_SECRET: ${OPENCRVS_RELAY_AUDIT_HASH_SECRET:-compose-validation-only}
REGISTRY_RELAY_AUDIT_PSEUDONYM_EPOCH_1: ${OPENCRVS_RELAY_AUDIT_PSEUDONYM_EPOCH_1:-compose-validation-only}
REGISTRY_RELAY_CONSULTATION_DATABASE_URL: postgresql://opencrvs_demo_runtime:${OPENCRVS_RELAY_POSTGRES_RUNTIME_PASSWORD:-compose-validation-only}@opencrvs-db:5432/opencrvs_demo?sslmode=require
REGISTRY_RELAY_STATE_MIGRATION_URL: postgresql://opencrvs_admin:${POSTGRES_ADMIN_PASSWORD:-compose-validation-only}@opencrvs-db:5432/opencrvs_demo?sslmode=require
REGISTRY_RELAY_STATE_KEYRING_MAINTENANCE_URL: postgresql://opencrvs_demo_keyring_maintenance:${OPENCRVS_RELAY_POSTGRES_MAINTENANCE_PASSWORD:-compose-validation-only}@opencrvs-db:5432/opencrvs_demo?sslmode=require
REGISTRY_RELAY_STATE_KEYRING_READER_URL: postgresql://opencrvs_demo_keyring_reader:${OPENCRVS_RELAY_POSTGRES_READER_PASSWORD:-compose-validation-only}@opencrvs-db:5432/opencrvs_demo?sslmode=require
OPENCRVS_CLIENT_ID: ${OPENCRVS_CLIENT_ID:-compose-validation-only}
OPENCRVS_SECRET: ${OPENCRVS_SECRET:-compose-validation-only}
volumes:
- ${OPENCRVS_RUNTIME_PROJECT_DIR:-./.runtime/project}/.registry-stack/build/local/private/relay/config:/etc/registry-relay:ro
- ${OPENCRVS_RUNTIME_PROJECT_DIR:-./.runtime/project}/../postgres/server.crt:/etc/opencrvs-demo/postgres/root.crt:ro
depends_on:
opencrvs-db-init:
condition: service_completed_successfully

opencrvs-relay:
image: ${REGISTRY_RELAY_IMAGE}
platform: ${OPENCRVS_DEMO_RELAY_PLATFORM:-linux/amd64}
restart: unless-stopped
command:
- --config
- /etc/registry-relay/relay-consultation.yaml
- --bind
- 127.0.0.1:8080
environment:
RUST_LOG: ${RUST_LOG:-info}
REGISTRY_RELAY_BIND: 127.0.0.1:8080
REGISTRY_RELAY_AUDIT_HASH_SECRET: ${OPENCRVS_RELAY_AUDIT_HASH_SECRET:-compose-validation-only}
REGISTRY_RELAY_AUDIT_PSEUDONYM_EPOCH_1: ${OPENCRVS_RELAY_AUDIT_PSEUDONYM_EPOCH_1:-compose-validation-only}
REGISTRY_RELAY_CONSULTATION_DATABASE_URL: postgresql://opencrvs_demo_runtime:${OPENCRVS_RELAY_POSTGRES_RUNTIME_PASSWORD:-compose-validation-only}@opencrvs-db:5432/opencrvs_demo?sslmode=require
OPENCRVS_CLIENT_ID: ${OPENCRVS_CLIENT_ID:-compose-validation-only}
OPENCRVS_SECRET: ${OPENCRVS_SECRET:-compose-validation-only}
healthcheck:
test: ["CMD", "/usr/local/bin/registry-relay", "healthcheck"]
interval: 3s
timeout: 5s
retries: 30
ports:
- "${OPENCRVS_DEMO_NOTARY_PORT:-4391}:8081"
volumes:
- ${OPENCRVS_RUNTIME_PROJECT_DIR:-./.runtime/project}/.registry-stack/build/local/private/relay/config:/etc/registry-relay:ro
- ${OPENCRVS_RUNTIME_PROJECT_DIR:-./.runtime/project}/../postgres/server.crt:/etc/opencrvs-demo/postgres/root.crt:ro
- opencrvs-relay-cache:/var/lib/registry-relay/cache
depends_on:
opencrvs-relay-bootstrap:
condition: service_completed_successfully

opencrvs-workload-agent:
build:
context: ../..
dockerfile: scenario-runner/Dockerfile
image: ${SOLMARA_SCENARIO_RUNNER_IMAGE:-solmara-lab-scenario-runner:local}
command: ["python", "scripts/relay_workload_identity_agent.py"]
restart: unless-stopped
network_mode: service:opencrvs-relay
environment:
WORKLOAD_ISSUER: http://127.0.0.1:8090
WORKLOAD_IDENTITIES_JSON: >-
[{"audience":"registry-relay","azp":"opencrvs-v2-demo-notary","subject":"opencrvs-v2-demo-notary","scopes":["registry:consult:opencrvs-birth-evidence"],"token_file":"/run/secrets/opencrvs-demo-notary-relay-token","private_jwk_env":"OPENCRVS_RELAY_WORKLOAD_JWK"}]
OPENCRVS_RELAY_WORKLOAD_JWK: ${OPENCRVS_RELAY_WORKLOAD_JWK:-compose-validation-only}
healthcheck:
test:
- CMD-SHELL
- python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8090/health', timeout=3)"
interval: 3s
timeout: 5s
retries: 30
volumes:
- opencrvs-workload-token:/run/secrets
depends_on:
opencrvs-relay:
condition: service_healthy

opencrvs-notary:
image: ${REGISTRY_NOTARY_IMAGE}
platform: ${REGISTRY_STACK_PLATFORM:-linux/amd64}
user: "65534:65534"
restart: unless-stopped
command:
- --config
- /etc/registry-notary/notary.yaml
- --bind
- 0.0.0.0:8081
network_mode: service:opencrvs-relay
environment:
RUST_LOG: ${RUST_LOG:-info}
REGISTRY_NOTARY_BIND: 0.0.0.0:8081
REGISTRY_NOTARY_AUDIT_HASH_SECRET: ${OPENCRVS_NOTARY_AUDIT_HASH_SECRET:-compose-validation-only}
OPENCRVS_DEMO_CALLER_TOKEN_HASH: ${OPENCRVS_DEMO_CALLER_TOKEN_HASH:-sha256:compose-validation-only}
OPENCRVS_DEMO_ISSUER_JWK: ${OPENCRVS_DEMO_ISSUER_JWK:-compose-validation-only}
healthcheck:
test:
- CMD
- /usr/local/bin/registry-notary
- healthcheck
- --url
- http://127.0.0.1:8081/ready
interval: 3s
timeout: 5s
retries: 30
volumes:
- ${OPENCRVS_RUNTIME_PROJECT_DIR:-./.runtime/project}/.registry-stack/build/local/private/notary/config/notary.yaml:/etc/registry-notary/notary.yaml:ro
- opencrvs-workload-token:/run/secrets:ro
depends_on:
opencrvs-relay:
condition: service_healthy
opencrvs-workload-agent:
condition: service_healthy

volumes:
opencrvs-db-data:
opencrvs-relay-cache:
opencrvs-workload-token:
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: opencrvs-v2-invalid-registration-number
classification: synthetic
input:
registration_number: INVALID
child_national_id: "9999000011"
tracking_id: SYN011
interactions: []
expect:
error: input.pattern_mismatch
outputs: {}
claims: {}
Loading
Loading