Released docs. You are viewing the documentation published with v0.41.0. Development docs are available at Latest.
Package and run a Registry Discovery index
When to use this
Section titled “When to use this”Use this procedure to build and serve an immutable index of approved Evidence Gateway provider descriptions. Discovery returns public metadata only; the consuming application owns provider trust, credentials, and invocation.
Before you start
Section titled “Before you start”You need these inputs:
- A provider-supplied public description URL, such as
https://<provider-host>/catalog.jsonld. Record the URL out of band with the provider. - A local directory for the catalog project, a new output directory for the package, and a separate deployment runtime file.
- The
discoveryctlanddiscoverybinaries.
The provider description uses the closed Registry Discovery JSON-LD profile. The profile is a selected alignment with Data Catalog Vocabulary (DCAT) 3, DCAT-AP 3.0.1, and BRegDCAT-AP terms. It does not claim complete DCAT-AP or BRegDCAT-AP conformance.
Install the authoring tool and runtime
Section titled “Install the authoring tool and runtime”Registry Stack releases publish the discovery-<tag>-linux-amd64 runtime asset. The first release
eligible to publish a matching discoveryctl-<tag>-linux-amd64 authoring asset is v0.38.0. For a
published v0.38.0 or later release, choose <tag> from the
latest release and authenticate
both assets through the shared SHA256SUMS
procedure at https://github.com/registrystack/registry-stack/blob/<tag>/release/VERIFY.md, then
install the exact pair:
tag="${TAG:?set TAG to the selected published tag}"mkdir -p ~/.local/binfor binary in discovery discoveryctl; do install -m 0755 "${binary}-${tag}-linux-amd64" "$HOME/.local/bin/${binary}"doneexport PATH="$HOME/.local/bin:$PATH"discovery --versiondiscoveryctl --versionEarlier releases contain the Linux runtime asset but require a source build for discoveryctl.
For another platform, build both binaries from the same Registry Stack checkout:
cargo build --release --locked -p registry-discovery -p registry-discoveryctlexport PATH="$PWD/target/release:$PATH"The release also publishes ghcr.io/registrystack/discovery:<tag>. Authenticate its digest through
the release manifest and deploy that digest instead of the mutable tag. The image runs
/usr/local/bin/discovery as the Distroless cc-debian13 nonroot user, with
/etc/registry-discovery/runtime.yaml as its default runtime file. Mount that file and the complete
package directory read-only. Discovery keeps no writable local state.
Add the approved provider URLs
Section titled “Add the approved provider URLs”Create <discovery-project>/origins.yaml. Each enabled origin is fetched only during packaging.
apiVersion: id.registrystack.org/formats/discovery/origins/v1alpha1kind: DiscoveryOriginsorigins: - originId: evidence-provider catalogUrl: https://<provider-host>/catalog.jsonld profile: registry-discovery-v1alpha1 enabled: trueUse a unique originId for each approved URL. Production origins use HTTPS. The
--allow-loopback option exists only for a local development origin.
Add evidence-type mappings
Section titled “Add evidence-type mappings”Create <discovery-project>/mappings/adult-status.yaml for each requirement that needs
evidence-type resolution. A mapping can offer alternatives, but every ID in one alternative is
required together.
apiVersion: id.registrystack.org/formats/discovery/evidence-mapping/v1alpha1kind: DiscoveryEvidenceMappingmappingId: urn:example:mapping:adult-statusmappingAuthorityId: urn:example:authorityrequirementId: urn:example:requirement:adult-statusjurisdiction: urn:example:jurisdictionalternatives: - evidenceTypeListId: urn:example:list:adult-status evidenceTypeIds: - urn:example:evidence-type:adult-statusjurisdiction is optional. Use the same exact identifier in a resolve request when your mapping
declares one.
Check the authoring project
Section titled “Check the authoring project”Run the offline check before packaging.
discoveryctl check --project "<discovery-project>"Expected output reports the validated origin and mapping counts, then the files it read:
valid origins=1 mappings=10 errors, 0 warnings in 2 filesThe check reads origins.yaml, every mapping, and every runtime file beside them, and does not
contact the provider URL. Each finding names its file, line, column, and the edit that fixes it.
--format json prints one report instead, with every finding in the same shape the other Registry
Stack checks use. The command exits 0 when nothing was refused, 1 when something was (or a warning
was reported under --deny-warnings), 2 when the command line is wrong, and 3 when a file could not
be read.
Package one bounded index
Section titled “Package one bounded index”Package into a new directory when the approved provider descriptions are available.
discoveryctl package \ --project "<discovery-project>" \ --output "<deployment-directory>/discovery-package" \ --revision "<source-revision>"Expected output reports the package digest and independent semantic revisions:
packaged packageDigest=sha256:<64-lowercase-hex-digits> catalogRevision=sha256:<64-lowercase-hex-digits> mappingRevision=sha256:<64-lowercase-hex-digits>The command fetches every enabled origin once, records the exact fetched-byte digest and fetch time,
and records builtAt after every origin has been collected and the semantic revisions compile. It
writes discovery-index.json, optional REVISION, and SHA256SUMS into a directory that must not
already exist. The package digest is the SHA-256 digest of the exact SHA256SUMS bytes.
Packaging the same compiled index bytes and revision twice produces the same package digest. A new
collection records new originFetchedAt and builtAt provenance, so its package digest may change
even when catalogRevision and mappingRevision stay the same. Build a new directory and deploy it
as a unit. Do not edit a package in place.
discoveryctl check --index <package-directory>/discovery-index.json parses an index offline
exactly as the runtime parses it, and reports its origin, service, and mapping counts and its two
revisions. An index packaged before the index carried apiVersion and kind is refused with
discovery.index.retired-header; package it again and update package.expectedDigest if you pin it.
Deploy and restart the service
Section titled “Deploy and restart the service”Place this runtime.yaml outside the package directory. Set package.root to its absolute path and
copy the reported package digest into package.expectedDigest when you want to pin the deployment.
apiVersion: id.registrystack.org/formats/discovery/runtime/v1alpha1kind: DiscoveryRuntimeConfiglistener: bind: 127.0.0.1:8080 requestTimeoutMilliseconds: 10000package: root: /srv/registry-discovery/package expectedDigest: sha256:<digest-of-SHA256SUMS>limits: maximumRequestBytes: 65536 maximumResponseBytes: 1048576 maximumResultRecords: 100 maximumResultAlternatives: 100 shutdownGraceMilliseconds: 10000logLevel: infoCheck the file before you start the service. discoveryctl check --runtime-config <file> reads it
as the runtime does, without the package, the network, or the environment; add --environment to
fill its ${NAME} expressions from the current environment and check the values they produce.
Start the new revision after deploying the complete package directory.
discovery --runtime-config "<absolute-deployment-directory>/runtime.yaml"The runtime file is read through the shared runtime configuration loader, as the other Registry
Stack runtimes read theirs. Its path must be absolute and free of symbolic links, listener.bind is
required and takes an IP address host, and a string value may name an environment variable as
${NAME}, ${NAME:-default}, or ${NAME:?message}. A key from the earlier grammar, such as
schemaVersion, listener.address, or indexPath, is refused with the name of its replacement.
Before binding the listener, the runtime recomputes every SHA256SUMS entry, refuses changed,
missing, or extra files by name, checks package.expectedDigest when set, then parses the exact
verified discovery-index.json bytes. The process remains running with that captured index. Verify
readiness from a network location that can reach the listener.
curl --fail-with-body "http://127.0.0.1:8080/ready"{"status":"ready"}The runtime accepts only its listener, package location and optional pin, limits, and log level. It does not carry provider credentials, origin-fetch configuration, mappings, or application trust configuration. The runtime acquires one of four request-body permits before reading a body and holds the permit through request handling. It also rejects malformed percent escapes, invalid UTF-8 query values, duplicate media-type headers, and request media parameters other than UTF-8 JSON.
Verify resolution and exact search
Section titled “Verify resolution and exact search”Resolve an application requirement to its evidence-type alternatives.
curl --fail-with-body \ -H 'Content-Type: application/json' \ --data '{"requirementId":"urn:example:requirement:adult-status","jurisdiction":"urn:example:jurisdiction"}' \ "http://127.0.0.1:8080/v1/evidence-types/resolve"The response contains mappingRevision and the configured alternative with its mapping authority.
{"requirementId":"urn:example:requirement:adult-status","jurisdiction":"urn:example:jurisdiction","mappingRevision":"sha256:<64-lowercase-hex-digits>","alternatives":[{"evidenceTypeListId":"urn:example:list:adult-status","evidenceTypeIds":["urn:example:evidence-type:adult-status"],"mappingId":"urn:example:mapping:adult-status","mappingAuthorityId":"urn:example:authority"}]}Search the catalog for a public Evidence Gateway advertisement. Copy the selected recordId,
endpointUrl, and origin provenance from the result into your application selection record.
curl --fail-with-body --get \ --data-urlencode 'serviceKind=evidence' \ --data-urlencode 'evidenceType=urn:example:evidence-type:adult-status' \ "http://127.0.0.1:8080/v1/services"The response has a catalogRevision and an items array. Each item carries the provider endpoint,
its advertised capability IDs, and the origin URL, content digest, and fetch time.
Hand off to native product trust
Section titled “Hand off to native product trust”Treat the selected record as inert metadata. The application validates and accepts the Evidence Gateway endpoint under its own trust configuration, then calls it with the native Evidence client. No credential, evidence request, or assertion passes through Discovery.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
discoveryctl check fails | An origin, mapping, or runtime file does not match its closed format. | Make the edit each finding names at its line and column, then rerun the offline check. |
| Packaging cannot fetch an origin | The approved description is unavailable or violates the fetch policy. | Restore the exact approved publication and package into a new directory. |
| Startup reports a digest mismatch | The package is incomplete, changed, or different from expectedDigest. | Redeploy the complete reviewed package. |
Startup says the index was built before it carried apiVersion and kind | The package predates the current index header. | Package it again with discoveryctl package, then update package.expectedDigest if you pin it. |
| Search returns no items | No Evidence advertisement matches every supplied filter. | Review the indexed descriptions and requested identifiers. |
Check commands
Section titled “Check commands”Every file Registry Discovery reads has a command that checks it offline, with no service running. Each prints the diagnostics, JSON output, and exit codes that Check a file before you deploy it describes.
| Format and files | Check command |
|---|---|
Discovery approved origins
| discoveryctl check --project <project> |
Discovery Evidence mapping
| discoveryctl check --project <project> |
Discovery runtime configuration
| discoveryctl check --runtime-config <file> |