Released docs. You are viewing the documentation published with v0.46.0. Development docs are available at Latest.
You have a package built with registry-render package and callers that need PDFs. When you are
done, one registry-render serve process serves that package on a private address behind your
TLS proxy, under API-key authentication, with an audit file you ship to append-only storage.
Render your first document builds a package.
Registry Render is pre-1.0 and an experimental surface, outside the compatibility promise.
What you provide
Section titled “What you provide”- One package directory, mounted read-only. Serve verifies it at startup and in the worker on every request, and refuses a package that changes while it runs.
- One API key in an owner-only file. At least 32 bytes of ASCII. Serve trims one trailing line ending and refuses any other whitespace, because a mis-read key would reject every caller while health stays green.
- A writable audit directory, or a log collector on standard output. Serve refuses a directory that group or others can write.
- A TLS proxy in front. The listener serves plain HTTP, reads no forwarded header, and accepts only a loopback, private, or link-local address.
- A host for one process and its render workers. Each render runs in a worker that is killed at the timeout and, on Linux, capped in address space.
Install the binary
Section titled “Install the binary”Releases from v0.38.0 attach a Linux amd64 binary, registry-render-<tag>-linux-amd64. Choose
<tag> from the latest release,
verify the asset with that release’s release/VERIFY.md, then install it. This replaces any
existing ~/.local/bin/registry-render, so keep a copy first when you need a rollback:
tag="${TAG:?set TAG to a published tag that includes Registry Render}"mkdir -p ~/.local/bininstall -m 0755 "registry-render-${tag}-linux-amd64" ~/.local/bin/registry-renderexport PATH="$HOME/.local/bin:$PATH"registry-render --versionregistry-render <version> (typst 0.15.1)Record that line: every audit entry carries the same version, and a stored PDF’s provenance is
this binary plus the package digest. On another platform, build from a checkout as the tutorial
does; the workspace lockfile is part of Render’s byte contract, so always build with --locked.
The same release publishes the image ghcr.io/registrystack/registry-render:<tag>. It runs
registry-render serve with /etc/registry-render/runtime.yaml from Distroless cc-debian13 as
the nonroot user (UID 65532), with /var/lib/registry-render as its working directory, and holds
no package. Mount the runtime file and the package read-only. Keep the API key owned by UID 65532
with mode 0400 or 0600, and the audit directory owned by UID 65532 with mode 0700. Deploy by
the digest release/VERIFY.md authenticates. A proxy in another container reaches Render on its
private container address, so set listener.bind to that address; 0.0.0.0 is refused.
Write the runtime configuration
Section titled “Write the runtime configuration”Serve reads one YAML file. Unknown keys are refused, and the configuration reference lists every key with its range and default:
apiVersion: id.registrystack.org/formats/render/runtime/v1alpha1kind: RenderRuntimeConfiglistener: bind: 127.0.0.1:8080 shutdownGraceMilliseconds: 30000package: root: /var/lib/registry-render/package expectedDigest: sha256:<package-digest>secretProviders: file: root: /run/secrets/registry-renderauthentication: apiKeyRef: secret:file/render-api-keylimits: renderTimeoutSeconds: 20 maximumConcurrentRenders: 4audit: path: /var/lib/registry-render/audit/render.jsonlThese rules are not in the tables:
package.rootis an absolute path with no.or..segment;audit.pathandsecretProviders.file.rootare absolute paths.- In
manifest.yaml, each document’sentryFileandschemaFileis relative to the bundle root and contains no... package.expectedDigestis optional; when set, serve refuses any other package.secret:file/<name>resolves undersecretProviders.file.root.secret:env/<NAME>works only whensecretProviders.environment: {}is declared. A reference to an undeclared provider is refused.- A file a
secret:file/reference names (the API key, an OIDC key set, a seal key, a CA bundle) is a regular file owned by the user serve runs as, with mode0400or0600and a single link. Serve follows no symbolic link to one, and refuses any other file at startup withruntime-invalidand the messagethe referenced secret file is unsafe. - A string value may come from the environment as
${VAR},${VAR:-default}, or${VAR:?message}, except inapiKeyRefand undersecretProviders. audit.destination: stdouthands entries to your collector and takes nopath.shutdownGraceMillisecondsis how long in-flight renders and seals get to finish on SIGTERM; open connections then get the same again. Align it with your supervisor’s stop timeout, and with a seal’sattemptTimeoutMilliseconds, which a seal waiting on its authority may need.- The server installs its
SIGTERMandCtrl-Chandlers before it accepts requests. If either cannot be installed, startup fails with “cannot install the stop signal handlers” instead of serving with no way to stop cleanly.
Check the configuration
Section titled “Check the configuration”Check the file before you deploy it. The check runs offline and reads no secret, so the package, key, and audit directory need not exist yet. Pass the absolute path serve will use, because serve refuses a relative one that check accepts:
registry-render check --runtime-config /etc/registry-render/runtime.yaml0 errors, 0 warnings in 1 fileA refused file lists every finding with its position and fix, and exits 1:
registry-render check refused the input.error[render.runtime.public-bind] /etc/registry-render/runtime.yaml:4:9 /listener/bind listener.bind is not a loopback, private, or link-local address; Render never listens publicly or on all interfaces next: Bind the private address your proxy forwards to; the proxy terminates TLS.1 error, 0 warnings in 1 fileA ${VAR} value is left for the deployment unless you add --environment, which substitutes it
from the current environment first. In a container preflight, add --require-audit-under <directory> to prove the audit file lands on persistent storage:
audit file resolves under /var/lib/registry-render/audit0 errors, 0 warnings in 1 fileIt refuses a stdout destination, and a path outside the directory with
error[render.runtime.audit-outside-root].
Start and verify
Section titled “Start and verify”registry-render serve --runtime-config /etc/registry-render/runtime.yamlServe logs JSON lines to standard error, starting with registry-render serve starting and the
package and configuration digests. If it refuses the file, it prints the same findings as check,
prefixed registry-render: runtime-invalid: the runtime configuration was refused, and exits 20.
Probe both endpoints before you route traffic:
curl -s http://127.0.0.1:8080/healthcurl -s http://127.0.0.1:8080/ready{"bundleHash":"<package-digest>","bundleVersion":1,"rendererVersion":"<version> (typst 0.15.1)","status":"ok","typstPin":"0.15.1"}{"status":"ready"}bundleHash is the package digest without sha256:; compare it with what you deployed.
Readiness includes the audit writer, so it fails when the writer stopped or a stdout collector
stalled. A stalled collector recovers when it reads again; a stopped writer needs a restart, as
audit retention describes. A supervisor can
run the same probe:
registry-render healthcheck --runtime-config /etc/registry-render/runtime.yamlhealthy at 127.0.0.1:8080One process writes one audit file. A second process pointed at the same path does not start:
registry-render: audit-failed: cannot open audit destination: audit sink single-writer lock is already held by another writer: /var/lib/registry-render/audit/render.jsonl.lockGive each replica its own audit path.
Answer callers
Section titled “Answer callers”Callers POST one JSON body to /v1/render/<document-type> with the API key. Keep the key off the
command line: write the header to a file only the caller reads, as
the tutorial does, and pass the file.
curl -s -X POST http://127.0.0.1:8080/v1/render/<document-type> \ -H @auth.header \ -H "Content-Type: application/json" \ -d '{"issuedAt":"<issuance-time>","data":<document-data>}' \ -o document.pdf -D headers.txtThe answer is the PDF with x-registry-pdf-digest, x-registry-data-digest,
x-registry-warning-count, and x-registry-document-version headers; each digest is labelled
sha256:<hex>. With Accept: application/json it is a JSON object with pdfDigest,
dataDigest, documentVersion, warnings, and the PDF as pdfBase64. The bare hex
pdfSha256 and dataSha256, and their x-registry-pdf-sha256 and x-registry-data-sha256
headers, are still sent and are deprecated.
Requests must carry Content-Length; a chunked body is refused with invalid-argument, because
one that passes the limit mid-stream could not be answered. Idempotency-Key is echoed and
recorded as an opaque correlation id; rendering is deterministic, so nothing is deduplicated.
registry-render validate --bundle <package> --type <document-type> --data <file> checks data
against the document’s schema without rendering.
Failures are RFC 9457 problem documents from a closed vocabulary, such as data-invalid (400),
unknown-document (400), unauthorized (401), body-too-large (413), render-timeout (504),
and audit-failed (503).
Seal documents
Section titled “Seal documents”Sealing is optional. Without a signing block, Render loads no key, makes no timestamp call, and
serves no seal route. With one, POST /v1/seal/<document-type> renders the document and returns
it with a PAdES signature made with your institution’s key. Render seals only what it just
rendered from the verified package, never bytes a caller sends. A production seal’s private key
stays in Transit, which signs for Render; a test seal’s key file is loaded in the serving process.
Neither is ever sent to a render worker. The seal is PAdES baseline B-B or B-T. Render makes no
claim that it is a qualified seal under eIDAS or any other scheme: that depends on your
certificate, its issuer, and how you hold the key.
Enable a seal
Section titled “Enable a seal”You need an OIDC deployment (a seal never works with the legacy API key), a seal certificate chain
in a PEM file with the seal certificate first, and the seal key in Vault or OpenBao Transit: an
ecdsa-p256 key created non-exportable, reached through a Transit signing proxy on a Unix socket
on the Render host. The proxy holds the Transit token; Render sends none. Create the key and its
least-privilege policy as
Configure Transit signing for Registry Evidence
does, and run the proxy
with a forced token,
its socket group admitting the Render service. Render makes the same calls, a read of the key and a
prehashed sha2-256 sign with the pinned key_version, so that policy works with your key name and
version in place of Evidence’s.
With use_auto_auth_token = "force", the proxy puts its own token on every request that reaches
its socket, so the socket’s owner, group, and mode are the only check on who can sign with the seal
key. Keep the tutorial’s proxy settings, with Render’s values. socket_mode = "0660", with
socket_group set to Render’s service group, lets only the proxy’s user and that group connect.
require_request_header = true makes the proxy refuse a request without the
X-Vault-Request: true header, which Render sends on every call. num_retries = -1 makes the
proxy fail fast instead of retrying a stalled Vault or OpenBao, so one Render call is one provider
request and attemptTimeoutMilliseconds stays the bound on it. After the proxy starts, check the
socket with ls -l: its mode must read srw-rw---- and its group must be Render’s. If they do
not, correct them before you start serve.
With the proxy running,
registry-render keygen --csr <file> --common-name <seal name> --transit-unix-socket-path <socket> --transit-mount <mount> --transit-key-name <key> --transit-key-version <version> reads
the key version’s public key and has Transit sign the certificate request your certificate
authority issues the seal certificate from. The key never leaves Transit, and keygen writes only
the request. Name the seal in the document type’s manifest.yaml entry with seal: ministry,
then bind it in the runtime file:
authentication: oidc: issuer: https://issuer.example.invalid audience: urn:example:render allowedClients: [portal, records-service]assuranceProfile: productionsigning: seals: ministry: signer: type: transit unixSocketPath: /run/registry-render/transit.sock mount: transit keyName: render-seal keyVersion: 1 attemptTimeoutMilliseconds: 2000 certificateChainFile: /etc/registry-render/seal/chain.pem timestampAuthority: url: https://tsa.example.invalid/tsr attemptTimeoutMilliseconds: 10000 allowedClients: [records-service]Render reads the issuer’s signing keys from its OpenID Connect discovery document, or from
authentication.oidc.jwksSource: a key set URL (type: uri) or a key set held as a secret
(type: static with documentRef, such as secret:file/jwks.json).
Connect an OIDC issuer covers each choice.
assuranceProfileis required at the top of the runtime file once it declares a seal, with the same member and values Evidence uses.productionmeans every seal signs throughtransit: Render refuses a production runtime with a key file (render.runtime.signer-assurance-mismatch).localmeans every seal is a test seal signed with a key file; see Use a test seal in development.signer.unixSocketPathis the proxy’s socket, an absolute path.mount,keyName, andkeyVersionname one Transit key version: pinning the version means a rotation in Transit never changes the key behind your certificate unnoticed.attemptTimeoutMilliseconds(1 to 30000) bounds each call to the proxy.allowedClientsis required and names each client allowed to seal. Whenauthentication.oidc.allowedClientslists clients, each seal client must also be in that list, or Render refuses the file. Keep these separate from any citizen-facing client.unrestrictedand wildcards are refused.- Callers need the
render:sealscope.render:renderdoes not imply it. timestampAuthoritytimestamps each seal (B-T), so it keeps validating after the certificate expires. DeclarewithoutTimestamp: seal-stops-validating-when-certificate-expiresinstead to seal without a timestamp (B-B), and accept that the seal stops validating at expiry. Declare exactly one.- Seal one test document through your timestamp authority before you rely on it for B-T. Render accepts only a DER answer whose token is signed with RSA PKCS#1 v1.5 or ECDSA and names the authority’s certificate in an ESS signing-certificate attribute; the configuration reference lists the limits.
- Render reaches the timestamp authority over TLS with the serving host’s root certificates. If
the authority’s TLS certificate chains to a national or other private root, set
timestampAuthority.caBundleRefto a secret reference to that root as PEM, such assecret:file/tsa-ca.pem. The bundle then replaces the host’s roots for that authority alone. - A failing timestamp authority fails the request with
timestamp-failed(502). Render does not retry and never returns an untimestamped file in its place. The audit’s response entry and oneseal refusedlog warning name the failing check asreason, such astimed-outornonce-mismatch; the configuration reference lists them. - A seal releases its render slot before it signs and waits on the timestamp authority. Seals in
flight are bounded by
limits.maximumConcurrentRenderson their own: one more is refused withrate-limited(429) rather than queued behind a slow authority.
Run registry-render check --bundle <package> --runtime-config runtime.yaml --environment. It
reads each chain file, never the key, and it fails on an unreadable or malformed chain, a seal
certificate without a signing key usage, or a chain too large for the signature space. It warns
about a certificate that is expired, not yet valid, or expires within 30 days, and about one whose
extended key usage names no document-signing purpose (render.runtime.seal-certificate-purpose):
validators such as Acrobat flag its seals, so serve also logs a seal certificate purpose excludes document signing warning for it at startup. When serve
starts, it also checks that the key matches the certificate, and it refuses to start if it does
not. For a Transit seal, serve reads the key version’s public key from Transit and signs once to
test it. It refuses to start if the proxy does not answer or refuses the key read, if the key is
not a non-exportable, non-derived ecdsa-p256 key without plaintext backup, or if keyVersion is
outside the key’s live versions (render.runtime.seal-transit-unavailable). A seal that cannot load, for any of these reasons or
an unreadable key or CA bundle, stops
serve with exit code 20 (runtime-invalid) and an error at the member’s line in the runtime
file. If the runtime names a seal the package does not use, or the package names a seal the
runtime does not bind, check reports it, and serve refuses the second case. If the package
names seals and the runtime has no signing block at all, check and serve warn
(render.runtime.seals-not-served): sealing is off, those document types render unsealed on the
render route, and the seal route does not exist.
Then call the route with a token that carries render:seal. The request body is the render
route’s. The PDF answer carries X-Registry-Document-Digest, X-Registry-Signed-File-Digest,
X-Registry-Seal-Id, X-Registry-Seal-Level (B-T or B-B), and
X-Registry-Certificate-Digest, plus X-Registry-Timestamped-At for B-T. It also carries
X-Registry-Package-Digest (packageDigest in JSON), the form package.expectedDigest takes,
so a client that holds only render:seal can compare the package with what you deployed without
reading /v1/documents. A document type that
names no seal is refused with document-not-sealable (400); /v1/documents lists the seal of each
document type the route takes as seal, so a client can tell them apart first. The
configuration reference lists the keys,
problems, and response shapes.
Use a test seal in development
Section titled “Use a test seal in development”Issue a test certificate from your own test authority and set assuranceProfile: local in the runtime file.
Under that profile every seal keeps its key in a file instead of Transit: signer.type: local-jwk with
privateKeyRef naming one ES256, ES384, RS256, or RS384 private JWK under the file secret
provider, such as secret:file/seal.jwk; an environment reference is refused
(render.runtime.seal-key-requires-file-provider). registry-render keygen --key <file> --csr <file> --common-name <seal name> writes a new key owner-only with its certificate request; add
--from-pem <file> to convert a key you hold as unencrypted PKCS #8 instead. The
template then receives signing.testOnly: true in its payload on the seal route, and can print a
visible test marking (the payload contract is products/render/PAYLOAD.md in the repository); the
registry-render init scaffold prints it. Render also says so where a template cannot hide it:
testOnly: true in the JSON answer’s seal, in /ready and in the audit, an
X-Registry-Seal-Test-Only: true header on the PDF answer, and one test-only seal warning per
seal when serve starts. Use a loopback timestamp authority (http://127.0.0.1:<port>/...
is accepted on loopback only) or withoutTimestamp while you develop. Never copy a test seal’s
runtime into production.
Make a test seal in ten minutes
Section titled “Make a test seal in ten minutes”Render refuses a CA certificate as the seal certificate, so a self-signed root alone cannot seal.
This makes a test root and a seal key, and has the root issue the seal certificate: a leaf with
basicConstraints CA:FALSE. It needs OpenSSL and registry-render. Run it in an empty
directory:
mkdir -m 700 secretscat > test-root.cnf <<'EOF'[req]distinguished_name = subjectx509_extensions = rootprompt = no[subject]CN = Test seal root (development only)[root]basicConstraints = critical,CA:TRUEkeyUsage = critical,keyCertSign,cRLSignsubjectKeyIdentifier = hashEOFopenssl req -x509 -config test-root.cnf -newkey ec -pkeyopt ec_paramgen_curve:P-256 \ -nodes -days 365 -keyout test-root.key -out test-root.pemregistry-render keygen --key secrets/seal.jwk --csr seal.csr \ --common-name "Test seal" --organization "Example Ministry (test)" --country FRcat > seal.ext <<'EOF'basicConstraints = critical,CA:FALSEkeyUsage = critical,digitalSignature,nonRepudiationextendedKeyUsage = 1.3.6.1.5.5.7.3.36subjectKeyIdentifier = hashauthorityKeyIdentifier = keyidEOFopenssl x509 -req -in seal.csr -CA test-root.pem -CAkey test-root.key -CAcreateserial \ -days 90 -sha256 -extfile seal.ext -out seal.pemcat seal.pem test-root.pem > chain.pem1.3.6.1.5.5.7.3.36 is the document-signing extended key usage (RFC 9336). Set
secretProviders.file.root to the absolute path of secrets, and bind the seal as a test seal
without a timestamp:
assuranceProfile: localsigning: seals: ministry: signer: type: local-jwk privateKeyRef: secret:file/seal.jwk certificateChainFile: /absolute/path/to/chain.pem withoutTimestamp: seal-stops-validating-when-certificate-expires allowedClients: [records-service]Put assuranceProfile and this signing block in a runtime file that has the authentication block from
Enable a seal. Name the seal in the document type’s manifest.yaml entry with
seal: ministry, and run registry-render package again. Then run check --environment and
serve as above. Callers need a token from your issuer that carries render:seal, issued to a
client the seal’s allowedClients names. test-root.key can issue certificates: keep it out of
every deployment, and never trust the test root outside development.
Renew the certificate
Section titled “Renew the certificate”Run check --environment on a schedule. Thirty days before expiry it warns with
render.runtime.seal-certificate-expiring. serve logs the same window when it starts, as a
seal certificate expiring warning with the seal_id, and a seal that cannot sign then as a
seal unavailable warning with the seal_id and the /ready reason. It does not log again
while running, so restart or /ready is how a later expiry shows. To renew, write the new chain file with the seal
certificate first, point certificateChainFile at it (or replace the file), and restart serve:
Render reads the chain at startup. To move a Transit seal to a new key version, rotate the key in
Transit, run keygen with the new --transit-key-version, have the new certificate issued, then
change keyVersion and the chain file together and restart serve. After the old certificate
expires the seal is unavailable and
plain rendering is unaffected. A file sealed earlier with a timestamp is built to keep validating after the certificate expires,
subject to the validator’s trust decisions; a file sealed without one stops validating at expiry.
Read readiness
Section titled “Read readiness”When seals are configured, /ready adds a signing member with one entry per seal id. Each is
{"status": "ready"} or {"status": "not-ready", "reason": ...}, where the reason is
certificate-expired, certificate-not-yet-valid, or signer-not-ready. A seal never changes
the status code: Render stays ready for plain rendering while a seal cannot sign, and a seal
request answers signing-unavailable or seal-certificate-invalid (503) until it can. Readiness
reads the certificate validity and the signer’s last known state; it never calls the timestamp
authority, so a ready seal can still fail with timestamp-failed. A Transit seal turns
signer-not-ready only after a sign call fails, so after its proxy stops, /ready reports it
ready until a seal request fails.
A Transit seal whose proxy stops answering fails the seal request in progress with
signing-unavailable and turns signer-not-ready. /ready calls and seal requests then start
probes, each of which has Transit sign one probe message, and the seal can sign again once a probe
succeeds. /ready starts the probe and never waits for it: it answers at once with the state the
last finished probe left, so the seal shows ready on a later call. A seal request waits for the
probe it starts. Each seal has at most one probe in flight, and after a probe fails the
next starts no sooner than one second after it ended, however many calls arrive. You do not
restart serve after a Transit or proxy outage.
Reconcile audit hashes with your records
Section titled “Reconcile audit hashes with your records”A seal call writes a request entry and a response entry that share correlation, like any
render. Both carry sealId. The response entry adds documentDigest (the first revision, the
document Render rendered), signedFileDigest (the whole signed file), certificateDigest,
and, for B-T, timestampTokenDigest, each labelled sha256:<hex>. Store the two document
digests with the record. To check a stored file against the audit:
sha256sum signed.pdfThe digest, prefixed with sha256:, must equal signedFileDigest in the response entry. A
sealed file has no pdfDigest;
two seals of the same request differ in their signed bytes, because each carries its signing
time, but their first revision is the same. The audit never holds a certificate subject, a signer
name, a key, or a token.
What a citizen’s PDF viewer shows
Section titled “What a citizen’s PDF viewer shows”A PDF viewer decides trust from its own trust list. When your seal’s issuing root is not in a viewer’s list, the viewer may show the signature as “validity unknown”. That is the viewer’s verdict on the issuer, not a failure of the file’s integrity.
Know the limits
Section titled “Know the limits”- The signature field is invisible. A template prints any visible seal block from the payload’s
signingmember.registry-render compile --preview-seal test-only(orproduction) renders that block offline, with--signer-nameas the certificate’s display name, and signs nothing. - Render embeds no revocation data (no B-LT or B-LTA) and does not pin the timestamp authority’s identity; validators decide trust in both.
- The seal key comes from a secret reference to a local JWK, and no HSM or managed-key custody
exists yet. A render worker that gained code execution runs as the serving user and can read a
secret:filekey, so keep a production seal key off such a host until that custody lands. - A render worker starts from an empty environment but is not a sandbox. A worker that gained code
execution could get arbitrary content sealed, because it renders the content, and could rewrite
a
fileaudit destination. For a deployment that seals, useaudit.destination: stdoutand ship it to storage the serving user cannot write. - On macOS, such a worker can also read the serving process’s environment, including every
${VAR}andsecret:envvalue. Seal on Linux, whereservecloses that. - veraPDF has passed a test template at every PDF/A level Render accepts, and at PDF/UA-1, both as rendered and once sealed. Your own template is not checked against its level: validate a sealed sample of each document type with a PDF/A validator before you issue it.
Keep the audit file
Section titled “Keep the audit file”Each line is one entry with schema (render.registrystack.org/audit/v1), eventId, time,
phase, correlation, and a value-free record: hashes, versions, the caller’s key fingerprint,
and the outcome. To list outcomes:
jq -c '{correlation, phase, outcome: .record.outcome, problem: .record.problem}' \ /var/lib/registry-render/audit/render.jsonlA call that reaches the renderer writes a request entry before the render starts and a
response entry before the answer leaves; both share correlation. Data the schema rejects is
found inside the render, so it also writes both. A refusal before the render, such as an unknown
document type or a chunked body, writes one response entry. If any of these writes fails, the
call fails closed with audit-failed. A wrong key or an oversized body also writes one entry, but
if that write fails the refusal is still answered and the failure is logged. A call whose caller
disconnects is recorded as unfinished.
When the active file would pass rotateBytes, it is renamed to <path>.<sequence> and a new file
opens. At startup and at each rotation, sealed files older than retentionDays are deleted. The
file is not chained or signed, so ship sealed files, or the stdout stream, to append-only storage
before retention deletes them. A render worker runs as the serving user, so one that gained code
execution could rewrite the file; a deployment that seals should use stdout.
Never rename, edit, or truncate the active file while the process runs. The writer then stops, and
every render fails closed with audit-failed until a restart.
Upgrade
Section titled “Upgrade”A Typst, compression-library, or template change can change output bytes. Build every template
change into a new package directory and point package.root at it; registry-render package
refuses an existing directory, so a published digest never gains different bytes. Before you
switch to a new binary, render a stored request with it and compare pdfDigest with the stored
value. A changed hash means documents rendered after the switch differ from earlier ones.
Check commands
Section titled “Check commands”Every file Render reads has a command that checks it offline. Each prints the diagnostics, JSON output, and exit codes that Check a file before you deploy it describes.
| Format and files | Check command |
|---|---|
Render bundle manifest
| registry-render check --bundle <project> |
Render label catalogue
| registry-render check --bundle <project> |
Render runtime configuration
| registry-render check --runtime-config <file> |
Render document data schema
| None |
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.