Skip to content
Registry StackDocsv0.13.0

Known limitations and non-guarantees

View as Markdown

You already know what Registry Stack is for: answer a question about a record without sharing the underlying record. This page answers a different question (what does Registry Stack not yet do or guarantee?) by giving you, in one place, the list of boundaries.

This is the canonical inventory of current limitations and non-guarantees across the whole stack. Each entry states the boundary plainly and links to where it is discussed in depth, so the rest of the documentation can point here whenever it says “this is not X.”

Each protocol and data-model specification carries its own limitations section; this hub collects those and links to them so you can read any one in full context.

Three things are out of scope here, and each is a link instead:

  • Why a given limit exists: read the relevant specification.
  • Whether it will change: see the project roadmap (ROADMAP.md in the repository root). This page describes current behavior only.
  • How to work around a limit: mitigations are not covered here. Follow the linked specification for each boundary, and see release/VERIFY.md in the repository for release verification.

Use this page as a checklist before you commit.

Every governing specification (architecture, security, protocol, and data-model) is currently at lifecycle status draft: under development or review, not current (in force). The contracts these limitations are stated against are themselves not yet finalized.

Registry Stack is a pre-1.0 technical release for evaluation, integration pilots, and public review. It is not a production support commitment and carries no hosted service-level agreement.

Two things follow. First, the behaviors and boundaries here may change as the specifications move toward current. Second, aligning with an external standard is not the same as conforming to it: speaking the shape of OIDC, OAuth 2.0, SD-JWT VC, OID4VCI, CCCEV, or the rest does not certify conformance to any of them. The standards register records how each one is actually adopted.

These boundaries cut across components. Read them first.

  • No source mutation, no event stream: Registry Relay does not write back to or otherwise mutate source registry data, and it has no event-stream backend. Registry-backed Notary claims consume Relay consultations; Registry Notary does not connect to registry sources directly.
  • Aggregate routes are not a privacy budget: Relay aggregate routes return the configured statistical observations, but provide no built-in longitudinal privacy budget and do not track cumulative disclosure across repeated or overlapping queries. Do not describe an aggregate route as privacy-budgeted unless a separate deployed control provides that protection.
  • A published manifest grants nothing: Publishing a dataset, policy, evidence offering, or federation relationship in a discovery artifact grants no access, enforces nothing, and asserts no fact about a live record. Federation discovery metadata is not a trust anchor: a published manifest does not bind a consumer to trust a JWKS endpoint, federation API host, or peer identity. Trust bootstrap stays in the consumer’s local policy and Notary peer configuration.
  • Solmara Lab and its hosted instance are demonstrations, not infrastructure: Solmara Lab is a separately maintained adopter demo that uses generated synthetic data and demo configuration. It is not a formal Registry Stack product and provides no production deployment guidance. Any hosted instance of Solmara Lab is likewise a demonstration, not production infrastructure: it carries no uptime or data-retention commitment.

For the rationale behind each of these, follow the linked specifications in each section.

Credential issuance and lifecycle limits (Notary)

Section titled “Credential issuance and lifecycle limits (Notary)”

Registry Notary issues credentials, but the issuance surface is deliberately narrow. Read the full context in the Registry Notary protocol.

  • One credential format, one OID4VCI holder profile: Issued Registry Notary credentials are SD-JWT VC only. Issuer signing supports EdDSA and ES256. Holder binding is a per-credential-profile setting that defaults to mode: did with did:jwk as the supported holder DID method. Direct issuance requires a holder DID by default; it verifies a fresh holder proof only when proof_of_possession: required is configured. An operator can explicitly set holder_binding.mode: none for a bearer-style credential profile, in which case registry-notary doctor reports a warning and the issued credential is unbound. The OID4VCI path requires EdDSA did:jwk binding. ES256 holder proof is not supported.
  • A profiled issuance subset, not a full issuer: The OID4VCI surface is a registry-backed issuer-initiated pre-authorized profile using the dc+sd-jwt format, not a full OID4VCI issuer and not a claim of general external-wallet interoperability. The identity provider’s authorization code is internal to Notary. There is no wallet-facing authorization-code grant, public nonce endpoint, response next nonce, EUDI, HAIP, PAR, DPoP, or wallet attestation profile. The capability-discovery document (/.well-known/evidence-service) declares openid4vci.support: not_full_issuer (announcing it is not a full issuer); this flag lives there rather than in the OID4VCI credential-issuer metadata.
  • Source-free and delegated self-attestation are evaluation-only: Both /v1/credentials and the OID4VCI credential endpoint reject source-free and delegated evaluations in 1.0. Configuration load rejects delegated relationship credential_profiles and credential-profile bindings on delegated claims. Remove that capability to keep delegated evaluation, or issue a separately modeled registry-backed, non-delegated claim.
  • No revocation flow, no issuer-metadata discovery endpoint, no erasure workflow: The RS-* specs define no revocation flow. The credential-status surface is optional and off by default; when an operator enables it, the public status endpoint reads a credential’s status, and only the admin status endpoint (which requires the registry_notary:admin scope) can mark a credential revoked. There is no /.well-known/jwt-vc-issuer endpoint and no built-in data-subject erasure workflow. A rotated-out signing key may remain published for verification, which is not revocation. These are documented pilot limitations, recorded in SECURITY.md.
  • Status-bearing credentials fail closed: The top-level status claim is never selectively disclosable. A client accepts a status-bearing credential only after validating the signed status response from its exact configured HTTPS trusted origin. Missing, invalid, unavailable, suspended, revoked, or expired status denies the credential.
  • CCCEV output is a profiled shape, not conformant: CCCEV-shaped output is a profiled subset and is not conformant to CCCEV 2.00. It is consumed by parsing the @graph for cccev:Evidence nodes.
  • Notary owns credential issuance: Notary issues SD-JWT VC credentials (dc+sd-jwt, signed with EdDSA/Ed25519 by default; ES256/P-256 is also supported per credential profile; with no W3C Verifiable Credentials Data Model JSON-LD envelope). Relay no longer issues signed response credentials or hosts issuer DID documents.
  • Standalone admin reload is not implemented: The standalone Notary /admin/v1/reload route returns HTTP 501 with code registry.admin.capability.not_supported and performs no reload, and non-swappable changes require a service restart. Signed config bundles are verified from a local bundle directory and activated by placing the bundle on the node and restarting; there is no admin config apply route and no hot apply.

Federation across institutions is static-peer only. Read the full context in the Registry Notary protocol and the security model.

  • Static peers only: Federation uses the global typed Notary correctness-state backend for request replay and jti checks. Production and multi-instance deployments require the Notary-owned PostgreSQL schema. Explicit in-memory state is limited to local, single-instance development. There is still no dynamic trust-chain discovery and no federated credential issuance; both are out of scope for this version.
  • Delegated evaluation returns a result, never a credential: Across a federation boundary, what crosses is a scoped evaluation result, never an issued credential.

Registry Relay exposes protected, read-only registry routes. Its boundaries are covered in depth in the Registry Relay protocol.

  • Read-only, batch or scan: Relay does not mutate source data in v1 and has no event-stream backend; it reads sources as batch snapshots or table scans only.
  • Feature-gated surfaces: Several Relay surfaces (the OGC API Features, Records, and EDR adapters and the SP DCI sync adapter) are feature-gated and present only in builds configured with the matching Cargo feature. Do not infer their presence in one build from another build’s route catalog.
  • Aggregates are not privacy-budgeted: As noted stack-wide, Relay aggregate routes provide no longitudinal privacy-budget or cumulative-differencing protection.
  • Relay does not evaluate or own the manifest: Relay does not evaluate claims or issue Notary’s SD-JWT VC credentials (that is Notary’s role), and it does not issue response credentials of its own. Relay also does not own or version the metadata manifest format, which belongs to Registry Manifest. Relay only serves and scopes compiled artifacts.
  • Governed enforcement is one PDP profile, not full interoperability: Governed runtime policy enforcement covers only the supported Evidence Gateway PDP profile (registry-evidence-gateway-pdp/v1, the single PDP profile this build recognizes). It is not full Evidence Gateway interoperability, not full OID4VCI issuer behavior, not dynamic external policy discovery, and not enforcement of ODRL terms outside the supported set.

These limits concern what the claim and manifest configuration loaders do and do not enforce. Read them in full in the Claim data model and Manifest data model.

  • The plugin rule type is unavailable: The enum remains declared, but configuration validation rejects it for both registry-backed and self-attested evidence modes. A conforming claim uses consultation_output, consultation_matched, or cel under the constraints of its evidence mode.
  • Claim evaluation formats are closed: A claim must include the canonical application/vnd.registry-notary.claim-result+json response format and may additionally use application/ld+json; profile="cccev". An empty list, SD-JWT VC, and unknown formats are rejected during configuration load. SD-JWT VC remains a credential-profile issuance format.
  • Manifests describe; they do not enforce: The portable metadata layer only describes: publishing in a discovery artifact grants no access and asserts no fact about a live record. Trust bootstrap stays in the consumer’s local policy and Notary peer configuration.
  • Rendered standards artifacts are well-formed, not certified: Manifest rendering emits standards-shaped artifacts but does not validate them against external standard bodies: a rendered CPSV-AP, DCAT, or SHACL document is well-formed by construction, not certified against the standard.
  • Vocabulary influence is not vocabulary emission: PROV-O is a design influence only: provenance-shaped concepts appear in audit fields and the claim provenance struct, but no PROV-O vocabulary terms are emitted as JSON-LD. No standalone SKOS artifact is published yet (only embedded SKOS-shaped nodes), and CPSV-AP has no Relay runtime metadata route.

A healthy, reachable, internally consistent deployment is not the same as a production-secure one. Read the full security boundary in the security model.

  • Health checks do not certify key custody: Readiness, liveness, and protocol-conformance checks do not certify production-grade private-key custody. A deployment using software keys, local JWK files, or demo-generated keys can be reachable and internally consistent yet not production-secure. Custody, rotation, and key-provider approval remain operator responsibilities.
  • Many guarantees are the operator’s to provide: Secret and key provisioning, key custody and rotation schedule, audit retention and storage, tenant isolation, transport termination, edge rate limiting, deployment configuration, and incident response are operator responsibilities, not behaviors the stack guarantees.
  • Audit fail-closed is a capability, not a guarantee about every build: A deployment can run audit fail-closed, so that a request whose audit record cannot be written does not return success. That is a switch a deployment is able to turn on, not a promise that every route in a given build has been individually audited, nor that every build ships with it on.
  • Demo and template code is not a production profile: Demo helper code and generated workflow snippets are integration examples, not a production freshness or replay-protection profile, and must not be relied on for freshness, expiry, or replay protection.

These concern how releases are signed and what that signing currently covers.

  • Partial release signing: GitHub Release assets are signed with keyless cosign and, when tag-triggered, carry SLSA provenance. However, OCI image signatures are not yet published, and Git version tags are not yet cryptographically signed (GPG, SSH, or Sigstore). The v0.8.0 prerelease was published before release-asset signing and does not currently include cosign signatures.

For how to verify what is signed, see the release verification guidance in release/VERIFY.md in the repository.

  • Why a given limit exists: the rationale and trade-offs live in each specification’s own limitations section: RS-PR-NOTARY, RS-PR-RELAY, RS-DM-CLAIM, and RS-DM-MANIFEST. For the security and architecture boundaries, read RS-SEC-G and RS-ARC-G.
  • How each external standard is actually adopted: the standards register records the adoption mode for every standard named across the stack.
  • What might change: the project roadmap (ROADMAP.md in the repository root). This page does not track it.
  • How to verify what is signed: release verification lives in release/VERIFY.md in the repository.