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

# Deploy Relay with your own data

> Run Registry Relay against your own bounded local dataset and verify protected reads before adding a Registry Stack project.

Use this guide when you operate CSV, XLSX, Parquet, or PostgreSQL data and need a protected
read-only Registry Relay API. This page covers Relay only. Add Registry Notary through a Registry
Stack project when you need registry-backed claims, or deploy Notary alone for source-free and
self-attested claims.

## When to use this

Use this path for an operator-managed Relay deployment whose data is already available to the
Relay host. Use [Registry Stack project authoring](../author-registry-project/) when you also need
bounded HTTP or script adaptation, exact snapshot consultations, Notary claims, or a combined
Relay and Notary topology.

This is an evaluation and pilot path, not a high-availability deployment profile.

## Before you start

You need:

- A Linux container host or a host that can run the Relay binary
- A stable local dataset and logical schema
- A deployment-specific audit hash secret
- An API-key fingerprint or OpenID Connect configuration for each caller
- A writable cache directory when Relay materializes file-backed data

Use synthetic examples while validating the configuration. Do not place raw API keys, source
credentials, or production records in commands or source control.

## Pin the Relay image

Pull a release tag or verified digest rather than `latest`:

```sh
docker pull ghcr.io/registrystack/registry-relay:v0.13.0
```

Review the release verification evidence before promoting an image into an institutional
environment.

## Prepare the deployment directory

Create separate configuration, source, and cache directories:

```sh
mkdir -p registry-relay/{data,cache}
cd registry-relay
touch config.yaml
```

Mount source data read-only. Mount the cache read-write when the selected provider needs local
materialization.

## Write the Relay configuration

Start from the [Relay configuration reference](../../products/registry-relay/configuration/) and
define only the datasets, entities, fields, filters, scopes, and providers this deployment needs.
Keep physical paths, table names, connection references, and credentials in private deployment
configuration.

At minimum, review:

- `deployment.profile` and deployment evidence
- `server.bind`, cache path, request limits, and authenticated OpenAPI policy
- One authentication mode and narrowly scoped principals
- The audit sink and deployment-specific hash secret reference
- Logical dataset and entity schemas
- Physical provider and column bindings
- Allowed filters, projection, pagination, purpose requirements, and optional aggregates

Registry Relay fails startup when required bindings, secrets, schemas, or security posture are
invalid.

## Provision a caller credential

Generate an API key and store only its fingerprint in the environment named by the Relay config:

```sh
docker run --rm \
  ghcr.io/registrystack/registry-relay:v0.13.0 \
  generate-api-key --id program-system
```

The command prints a raw API key and its fingerprint. Store the raw value in the institution's
secret distribution process. Put only the fingerprint in the runtime environment.

Create a stable audit hash secret through the institution's secret process. The value must remain
outside YAML, logs, shell history, and source control.

## Run Relay

Run the container with private configuration and source mounts:

```sh
docker run --rm \
  --name registry-relay \
  -p 127.0.0.1:8080:8080 \
  -v "$(pwd)/config.yaml:/etc/registry-relay/config.yaml:ro" \
  -v "$(pwd)/data:/var/lib/registry-relay/data:ro" \
  -v "$(pwd)/cache:/var/lib/registry-relay/cache" \
  --env-file <verified-private-env-file> \
  ghcr.io/registrystack/registry-relay:v0.13.0 \
  --config /etc/registry-relay/config.yaml
```

The process exits non-zero when configuration parsing, source binding, authentication, audit, or
listener validation fails.

## Verify Relay

Check liveness and readiness:

```sh
curl -i http://127.0.0.1:8080/healthz
curl -i http://127.0.0.1:8080/ready
```

Both routes return `200 OK` after the configured providers are ready. Confirm that an anonymous
protected read returns `401 Unauthorized`, then repeat the request with the authorized caller
credential and declared purpose.

```sh
curl -i \
  -H "Authorization: Bearer <caller-api-key>" \
  -H "Data-Purpose: https://example.gov/purpose/registry-consultation" \
  "http://127.0.0.1:8080/v1/datasets/<dataset>/entities/<entity>/records?<filter>=<value>"
```

The successful response contains only configured projected fields. Confirm that the audit sink
records the authorized request without the raw credential or sensitive lookup value.

## Add Notary through project authoring

Do not add a direct source connection to Registry Notary. A combined Registry Stack project
compiles the source integration and consultation into Relay, then compiles Notary claims against
the pinned Relay contract. A Notary-only project contains source-free or self-attested claims.

Follow [Author an HTTP Registry Stack project](../author-registry-project/) to run offline fixtures,
inspect the redacted plan, and build separate unsigned product inputs. Package, sign, verify, and
activate each product input through its Config Bundle workflow.

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| Relay exits before listening | Configuration, secret resolution, binding, or posture validation failed. | Read the named field in the startup error and correct the private configuration or environment. |
| `/ready` returns `503` | A configured provider or materialization is not ready. | Inspect the bounded provider error and verify the source mount, schema, and cache path. |
| A protected route returns `401` | The credential is absent or does not match the configured fingerprint. | Send the authorized raw key and verify only its fingerprint is configured. |
| A protected route returns `403` | The principal lacks the route scope or required purpose. | Correct the principal scopes or request purpose without widening unrelated access. |
| A registry-backed claim needs source access | Notary was configured as if it owned the source. | Author a combined project and keep every source binding in Relay. |

## Next

- [Author an HTTP Registry Stack project](../author-registry-project/) for combined Relay and
  Notary claims.
- [Relay protected read flow](../../explanation/consultation-flow/) for Relay request processing.
- [Harden a production deployment](../../security/hardening-checklist/) before public exposure.