Unreleased documentation. These pages follow the main branch and can change before the next release. For supported guidance, use v0.46.0.
If you are writing a registry project and want to see Base Registry Engine (BReg) and Registry
Casework serve it together, rstack dev starts both from your project directory, runs a short
journey against them, and removes everything when you stop. It does not start PostgreSQL and does
not use Docker: you supply a development PostgreSQL server over TLS. This page takes you from a
checkout to a running pair, using the licensing example that ships with Registry Stack.
Before you start
Section titled “Before you start”You need:
- PostgreSQL 17 or newer command-line tools (
initdb,pg_ctl,psql) andopensslon yourPATH, to run the local server below. A server you already have works too if it serves TLS and has an administrator role withLOGIN CREATEROLE CREATEDB. curlandjq.- A checkout of Registry Stack at the release you installed, for the example project.
Install the components
Section titled “Install the components”Install rstack from one verified release, then add the two components the example uses. The
steps are in Decide your first Base Registry Engine registry;
install casework the same way.
rstack install breg caseworkCheck the selected installation before you continue:
rstack components listSuccess is a breg line and a casework line that each say installed. available means that the
selected release provides the component but it is not installed, so run the rstack install
command again. unavailable means that the selected release does not provide the component for
your platform. If your shell cannot find rstack, or the command says No installation selected,
repeat the verified rstack installation steps linked above.
Start a local TLS PostgreSQL server
Section titled “Start a local TLS PostgreSQL server”rstack dev always verifies the server certificate and host name, so the server needs a
certificate your machine trusts. This recipe makes a private certificate authority, starts the
server on 127.0.0.1, and creates a least-privilege administrator. Keep the working directory
outside any repository. If port 5432 is taken, change PORT.
export DEV="$HOME/rstack-dev-postgres"PORT=5432mkdir -p -m 700 "$DEV"umask 077openssl rand -hex 16 > "$DEV/postgres.pass"openssl rand -hex 16 > "$DEV/devadmin.pass"initdb -D "$DEV/data" -U postgres --auth=scram-sha-256 --pwfile="$DEV/postgres.pass" -E UTF8
openssl req -new -x509 -newkey rsa:2048 -nodes -days 30 -subj /CN=rstack-dev-ca \ -addext basicConstraints=critical,CA:TRUE -keyout "$DEV/ca.key" -out "$DEV/ca.pem"openssl req -new -newkey rsa:2048 -nodes -subj /CN=localhost \ -keyout "$DEV/data/server.key" -out "$DEV/server.csr"printf 'subjectAltName=DNS:localhost,IP:127.0.0.1\nextendedKeyUsage=serverAuth\n' \ > "$DEV/server.ext"openssl x509 -req -in "$DEV/server.csr" -CA "$DEV/ca.pem" -CAkey "$DEV/ca.key" \ -CAcreateserial -days 30 -extfile "$DEV/server.ext" -out "$DEV/data/server.crt"
printf "listen_addresses = '127.0.0.1'\nport = %s\nssl = on\n" "$PORT" \ >> "$DEV/data/postgresql.conf"pg_ctl -D "$DEV/data" -l "$DEV/postgres.log" -w startThe passwords are random and stay in owner-only files, so nothing secret reaches your shell history or a process list. Create the administrator with the password from its file:
CONNECTION="host=127.0.0.1 port=$PORT user=postgres dbname=postgres sslmode=verify-full sslrootcert=$DEV/ca.pem"PGPASSWORD="$(cat "$DEV/postgres.pass")" psql "$CONNECTION" <<'SQL'\set pw `cat "$DEV/devadmin.pass"`CREATE ROLE devadmin LOGIN CREATEROLE CREATEDB PASSWORD :'pw';SQLSuccess is CREATE ROLE. The server must be running before you start a project. Point rstack dev
at it:
export RSTACK_DEV_DATABASE_CA="$DEV/ca.pem"export RSTACK_DEV_DATABASE_URL="postgresql://devadmin:$(cat "$DEV/devadmin.pass")@127.0.0.1:$PORT/postgres?sslmode=verify-full"Set the URL through an environment variable, not --database-url, because a flag is visible to
other local users in the process list. For a spatial project, install PostGIS for this server and
create the administrator as a superuser instead.
Adapt the development plan
Section titled “Adapt the development plan”Copy the licensing example from your checkout, then work in the copy:
cp -R path/to/registry-stack/products/platform/examples/licensing ./licensingThe directory holds a BReg project (registry/), a Casework project (casework/) and the plan
dev.yaml. Open dev.yaml: rstack dev reads only this file to decide what to start. Product
files stay byte-for-byte unchanged, and generated settings, keys and packages live in the run’s
owner-only scratch directory.
To adapt the plan to your own project, change these parts and leave the structure alone:
issuernames the identity issuer the local test tokens claim. Use a name that is yours.productslists each product’s project directory and token audience, in startup order.peopledeclares synthetic test people, each with a subject and one grant per product. A grant selects an access profile of that product’s project, its scopes, and extra claims. A BReg grant must name a profile the BReg project declares.journeyis the sequence of requests the run makes before it reports ready. Each step names a person, a product, a method, a path starting with/v1/, and what it expects back.
The rstack dev reference
describes every key, capture type and limit.
Check, then start
Section titled “Check, then start”check validates the plan and resolves its fixtures, grants and references with the installed
authoring tools. It works with the database offline.
rstack dev check ./licensingSuccess is Development plan is valid and exit status 0. Add --deny-warnings to refuse any
warning, and --json for a machine-readable report. Fix every error before you start: the report
names the plan field that caused it.
Start the run. The time to live (TTL) begins when the run is ready and defaults to 30 minutes:
rstack dev start ./licensing --ttl 30mThe command creates separate databases and logins for the run, starts both products on loopback ports, runs the journey, and returns while the services keep running:
Run 2f17770cb47d4502ad0b809a529f4309 ready breg http://127.0.0.1:64930 casework http://127.0.0.1:64931 Journey licensing-approval passed Logs STATE_DIRECTORY/2f17770cb47d4502ad0b809a529f4309/logs rstack dev token 2f17770cb47d4502ad0b809a529f4309 --as administrator rstack dev token 2f17770cb47d4502ad0b809a529f4309 --as applicant rstack dev token 2f17770cb47d4502ad0b809a529f4309 --as intake rstack dev token 2f17770cb47d4502ad0b809a529f4309 --as reviewerYour run ID and ports differ, and STATE_DIRECTORY stands for the state directory your run reports. Copy the run ID: every later command takes it. The
journey has already created an application in BReg and had a reviewer approve it in Casework.
rstack dev status RUN_ID repeats this report at any time.
Call the products with a token
Section titled “Call the products with a token”token writes a short-lived bearer header file for a test person and reports where it is. Tokens
expire five minutes after issue, or with the run if that is sooner, so ask again when one lapses.
Pass the header file to curl with --header @FILE:
RUN=2f17770cb47d4502ad0b809a529f4309HEADERS="$(rstack dev token "$RUN" --as applicant --json | jq -r '.credentials[0].header_file')"curl -sS --header @"$HEADERS" \ "http://127.0.0.1:64930/v1/records/applications?accessProfile=applicant"Use the BReg URL from your own report. BReg needs the selected profile as the accessProfile
query parameter, and the response lists the application the journey created:
{"items":[{"domainData":{"profession":"Surveyor","reference":"application-001"},"recordIdentifier":"23257c7f-1acd-4fbf-8a3c-4b253238043c","revisionIdentifier":"1"}],"meta":{"datasetIdentifier":"licensing","recordTypeIdentifier":"application","registryIdentifier":"licensing"},"pageInfo":{"nextCursor":null}}Casework needs no query parameter, because its header file carries the profile. This asks for the reviewer’s open tasks; the queue is empty because the journey already decided the request:
HEADERS="$(rstack dev token "$RUN" --as reviewer --json | jq -r '.credentials[0].header_file')"curl -sS --header @"$HEADERS" "http://127.0.0.1:64931/v1/review-tasks?queue=applications"{"items":[],"status":"complete"}A BReg project with encrypted fields runs without extra setup: each run gets its own development
data key, removed when the run ends, so encrypted data does not outlive its run. A step in the
project’s tests/journeys.yaml that touches an encrypted Record type fails the pre-activation
test, because that test has no key. Exercise those Record types in the plan’s journey instead.
Stop the run
Section titled “Stop the run”rstack dev stop "$RUN"Success is Run RUN_ID stopped. Stop, and TTL expiry, terminate both services and remove the run’s
databases, roles, keys and files. Stop the PostgreSQL server itself when you finish:
pg_ctl -D "$DEV/data" stopWhen a run fails
Section titled “When a run fails”A failed journey is different from a startup failure. start exits 1 but prints the normal run
report. With --json, its schema_version is registry.rstack.dev.v1, its status is ready,
and journey.result is failed; the journey includes the failed step and its reason. The services
keep running, and rstack dev status RUN_ID repeats the report, so use the run ID to inspect the
products and logs before you stop the run.
Other refusals and failures produce an error report instead. With --json, the report is one
object on standard output with schema_version registry.rstack.error.v1 and status refused.
Its process exit status and error.class identify the kind of failure:
| Exit | error.class | Meaning |
|---|---|---|
| 1 | domain | The request, the project, the plan or the run’s state was refused. Fix the plan or the command. |
| 2 | usage | The command line is wrong, such as a malformed run ID, --ttl or test person name. |
| 3 | operational | The environment failed: PostgreSQL is unreachable or refuses the administrator, a product binary cannot start, no loopback port is free, a product or the run does not start in time, or a run needs its resources released. |
For example, rstack dev start ./licensing --json with the PostgreSQL server stopped (the operating
system error number varies by platform):
{"error":{"class":"operational","message":"cannot establish the PostgreSQL administrator session over verified TLS: the PostgreSQL connection handshake failed: error connecting to server: Connection refused (os error 61)"},"schema_version":"registry.rstack.error.v1","status":"refused"}Start the server and run the command again. Without --json, the same message goes to standard
error as rstack dev: MESSAGE with the same exit status.
When a start fails before the run becomes available, the run directory is removed but its logs are
kept at <state>/failed/<run_id>/logs, and the error names the path. A live run’s logs are in
<run>/logs: supervisor.log for the supervisor and one file per product stage, such as
breg-check.log or casework-runtime.log. rstack dev status RUN_ID names the logs directory.
Delete kept logs yourself.
When a run still holds databases, roles or processes, the error carries its run_id and a
recovery object listing them. This happens if PostgreSQL is unavailable during cleanup for
longer than the supervisor retries (up to 30 minutes), or if the supervisor was lost. Release the
run with:
rstack dev stop RUN_ID --recoverIf the supervisor is still running, use plain stop. For a lost supervisor, its process guards
stop the products and any product tools still running. Use the original PostgreSQL cluster and
maintenance database for --recover. Recovery waits for the guards, drops the databases and
roles, and removes the run directory, including its development key file. If a check or cleanup
step fails, the report explains what to inspect before retrying. The
reference
lists the manual steps and the recovery fields.
rstack devreference for the full plan format, journey steps and recovery behaviour.- Call an API with rstack to make short requests against the running pair.
- Test with journeys to write the BReg project’s own journey tests.
- Encrypt a field for the key custody a deployment uses.
Cookies on Registry Stack
We use optional cookies to understand how you use the main Registry Stack website and this documentation. If you contact us, we may link this activity to your enquiry. You can change your choice at any time. Read the privacy policy.
Your browser asks sites not to track you, so optional tracking stays off.
We could not use or save that choice. Optional tracking remains off.