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

# Verify OpenCRVS claims with registryctl

> Generate a local Registry Notary project from OpenCRVS credentials, validate the config, and run a live birth-record claim evaluation smoke test.

Use this tutorial when you have OpenCRVS client credentials and want the shortest local
Registry Notary path to a live claim check.
`registryctl` generates the Notary project, stores your OpenCRVS client credentials in
`secrets/local.env`, and writes local Notary demo credentials under `secrets/`.
The generated project evaluates the starter `opencrvs-birth-record-exists` claim.

This tutorial validates delegated claim evaluation only.
It does not configure governed policy, production signing, or credential issuance.
OpenCRVS remains the evidence source, and Registry Notary evaluates the claim locally.

Estimated time: about 10 minutes after you have credentials and a test UIN.

## Before you start

You need:

- Docker with Compose v2.20 or later.
- `registryctl` 0.8.3 or newer, with `init notary --source-kind opencrvs-dci` support.
- `curl` and `jq` for the explicit evaluation check.
- OpenCRVS OAuth client credentials for a test environment.
- A known test UIN for the live smoke test.

Install `registryctl` if you have not already:

```sh
curl -fsSL https://raw.githubusercontent.com/registrystack/registry-stack/v0.8.3/crates/registryctl/install.sh | REGISTRYCTL_VERSION=v0.8.3 sh
registryctl --version
```

## Generate the Notary project

Generate the project with the OpenCRVS DCI source kind and the known test UIN:

```sh
registryctl init notary opencrvs-notary \
  --source-kind opencrvs-dci \
  --source-url https://opencrvs.example.gov \
  --smoke-target-id <test-uin>

cd opencrvs-notary
```

The generated `notary/config.yaml` records the source URL, including the OAuth token URL.
The generated `registryctl.yaml` records the smoke target.

## Set the source credentials

Open `secrets/local.env` and replace the generated placeholders with your OpenCRVS
OAuth client credentials:

```dotenv
DCI_CLIENT_ID=<opencrvs-client-id>
DCI_CLIENT_SECRET=<opencrvs-client-secret>
```

Keep `secrets/local.env` private.
Use the exact `DCI_CLIENT_ID` and `DCI_CLIENT_SECRET` names.
The 0.8.3 generator does not read `OPENCRVS_DCI_*` aliases or a DCI SHA secret.
Do not paste bearer tokens into the file.
Registry Notary uses the OAuth client-credentials settings to fetch a source token.

The generated project contains:

```text
opencrvs-notary/
  .gitignore
  registryctl.yaml
  compose.yaml
  README.md
  notary/
    config.yaml
  secrets/
    local.env
  output/
  bruno/
```

`secrets/local.env` contains local Notary API, audit, replay, demo issuer, and OpenCRVS
OAuth values.
The generated `compose.yaml` loads that file into the Notary container.

## Validate and start

Run the local doctor before starting services:

```sh
registryctl doctor --profile local --format json | jq '{ok, result}'
```

`doctor` checks the generated project and delegates Registry Notary config validation when a
compatible `registry-notary` binary is available.
If the report says the `registry-notary` doctor binary is not installed, continue with the Docker
smoke test below.
The report must not print your OpenCRVS client secret.

Start the generated stack:

```sh
registryctl start
```

On Apple silicon, v0.8.3 images are published for linux/amd64.
If Docker reports that no linux/arm64 manifest exists, start with the amd64 platform override:

```sh
DOCKER_DEFAULT_PLATFORM=linux/amd64 registryctl start
```

Registry Notary listens on:

```text
http://127.0.0.1:4255
```

Open the local API docs when you want to inspect the generated routes:

```sh
registryctl notary open
```

## Run the first live claim

Run the live smoke test:

```sh
registryctl notary smoke
```

The smoke test checks health, readiness, authenticated Notary access, and the live OpenCRVS-backed
evaluation.
`registryctl` writes the detailed report to:

```text
output/notary-smoke-results.json
```

To test a different UIN, edit `notary.smoke_target_id` in `registryctl.yaml` and rerun
`registryctl notary smoke`.

## Read the result safely

Inspect the redacted smoke report:

```sh
jq '.checks[] | {name, status}' output/notary-smoke-results.json
```

Do not paste the full report into support channels unless you have reviewed it.
The smoke report is designed to avoid raw OpenCRVS rows, target UINs, and secret values, but local
operators remain responsible for handling evidence reports as sensitive artifacts.

## Run an explicit evaluation

The smoke command proves the live claim works, but it does not print the raw evaluation response.
Run one explicit evaluation when you want a safe, minimal result summary:

```sh
export OPENCRVS_DEMO_SUBJECT_UIN='<test-uin>'

NOTARY_API_KEY="$(
  awk -F= '$1 == "REGISTRY_NOTARY_TUTORIAL_EVALUATOR_RAW" { sub(/^[^=]*=/, ""); print; exit }' \
    secrets/local.env
)"

curl -fsS http://127.0.0.1:4255/v1/evaluations \
  -H "content-type: application/json" \
  -H "accept: application/vnd.registry-notary.claim-result+json" \
  -H "x-api-key: $NOTARY_API_KEY" \
  -H "data-purpose: https://example.local/purpose/tutorial" \
  -d '{
    "target": {
      "type": "person",
      "identifiers": [
        {
          "scheme": "UIN",
          "value": "'"$OPENCRVS_DEMO_SUBJECT_UIN"'"
        }
      ]
    },
    "claims": ["opencrvs-birth-record-exists"],
    "disclosure": "predicate",
    "purpose": "https://example.local/purpose/tutorial"
  }' | jq '{
    claim_id: .results[0].claim_id,
    satisfied: .results[0].satisfied,
    evaluation_id_present: (.results[0].evaluation_id != null)
  }'
```

Expected result:

```json
{
  "claim_id": "opencrvs-birth-record-exists",
  "satisfied": true,
  "evaluation_id_present": true
}
```

Do not paste the full evaluation response into support channels unless you have reviewed it.

## What the generated config does

The generated `notary/config.yaml` configures:

- An OpenCRVS source connection named `opencrvs_crvs`.
- OAuth client-credentials auth using `DCI_CLIENT_ID` and `DCI_CLIENT_SECRET`.
- The `/registry/sync/search` source path used by this OpenCRVS connection.
- A UIN lookup for birth registrations.
- The `opencrvs-birth-record-exists` claim.
- `predicate` disclosure as the default response.
- Claim-result JSON as the starter response format.
- Local signing material for later demo issuance configuration, not production trust.

For the mental model behind these blocks, see the Registry Notary
[OpenCRVS onboarding model](../../products/registry-notary/opencrvs-dci-onboarding/).

## Next

- [OpenCRVS onboarding model](../../products/registry-notary/opencrvs-dci-onboarding/)
- [Registry Notary overview](../../products/registry-notary/)
- [Signing key providers](../../products/registry-notary/signing-key-provider/)