Preview release. These docs are a work in progress. Pages are still being written, links may break, and structure may shift without notice. Treat everything here as a draft and report issues on GitHub.
Adoption mode: profiled. Registry Notary issues a constrained SD-JWT VC profile
(application/dc+sd-jwt, EdDSA over Ed25519, did:jwk holder binding); it does
not claim full SD-JWT VC or OpenID4VCI conformance.
Registry Notary currently issues one credential format: SD-JWT VC using the current digital credential media type.
This profile is intentionally narrow. It documents the credential contract that Registry Notary can test and support today, and it names adjacent ecosystem features that are not yet part of the product surface.
Supported Credential Format
Section titled “Supported Credential Format”| Field | Value |
|---|---|
| Credential media type | application/dc+sd-jwt |
Compact JWT typ header | dc+sd-jwt |
| Signing algorithm | EdDSA |
| Issuer key type | OKP/Ed25519 |
| Holder binding DID method | did:jwk |
| Credential status methods | Default: none. Optional: RegistryNotaryCredentialStatus when credential_status.enabled = true, with statusUrl at /v1/credentials/{credential_id}/status. StatusList and revocation-list profiles are not supported. |
Registry Notary rejects credential profile format aliases such as
sd_jwt_vc and application/vc+sd-jwt. Operator configuration must use the
wire media type application/dc+sd-jwt.
Issuer-Signed JWT Header
Section titled “Issuer-Signed JWT Header”Issued credentials use a compact issuer-signed JWT as the first component of the SD-JWT value. The protected header has these Registry Notary invariants:
algisEdDSA.typisdc+sd-jwt.kidis thekidon the credential profile’s configured signing key.
Only Ed25519 EdDSA signing keys are supported. Local JWK keys are supported for development and tests; PKCS#11 keys are available behind the optional server feature.
Signing key configuration examples are documented in signing-key-provider.md.
Issuer-Signed JWT Payload
Section titled “Issuer-Signed JWT Payload”Registry Notary sets these payload claims:
iss: credential profile issuer.sub: holder DID for holder-bound credentials, otherwise the evaluation subject reference.iat: evaluation issue instant supplied by the caller.exp:iat + credential_profile.validity_seconds.vct: credential profile verifiable credential type URI.jti: generated credential identifier.id: same generated credential identifier asjti._sd: sorted disclosure digest list.cnf: holder confirmation for holder-bound credentials.
For citizen-facing holder-bound credentials, sub is the holder DID. Registry
Notary does not claim that the holder DID is the same identifier as the civil
or registry subject.
Holder Binding
Section titled “Holder Binding”When a credential profile requires holder proof of possession:
holder_binding.modeisdid.holder_binding.proof_of_possessionisrequired.holder_binding.allowed_did_methodsmust contain onlydid:jwk.- The issuance request must provide a holder DID and proof payload accepted by the server holder-proof validator.
- The issued credential includes
cnf.kidequal to the holder DID. - The issued credential includes
cnf.jwkwith the public holder JWK only.
Registry Notary does not support did:key, did:web, CWT proof, or mDoc
holder binding in this profile.
Disclosures
Section titled “Disclosures”Each evaluated claim result becomes one selectively disclosable claim. The disclosure payload contains:
claim_idversionvaluesatisfiedsubject_typeissued_at
The issuer-signed JWT stores disclosure digests in sorted order. The raw compact SD-JWT value is returned separately from the issuer-signed JWT and disclosure list so callers can verify or present the pieces without reparsing the whole credential.
Discovery
Section titled “Discovery”/.well-known/evidence-service exposes a credential_capabilities object with
the same constants listed in this profile:
- supported credential media types;
- SD-JWT VC JWT
typ; - signing algorithms;
- issuer signing key types;
- holder binding methods;
- configured credential profiles;
- unsupported adjacent features.
The metadata is Registry Notary capability metadata. It is not a claim of full OpenID4VCI issuer conformance.
When OID4VCI is enabled, Registry Notary serves SD-JWT VC Type Metadata at the
well-known location derived from each configured HTTPS vct. Per the SD-JWT VC
Type Metadata convention, a consumer dereferences an HTTPS vct by inserting
/.well-known/vct between the host and the path, so the metadata is served at
GET /.well-known/vct/{vct_path}.
- Matching. The handler strips the
/.well-known/vctprefix and reconstructs the candidatevctashttps://{host}/{vct_path}, then matches it exactly against a configured credential configuration. The route uses a trailing-wildcard capture, so nested configured paths such as/.well-known/vct/credentials/dhis2/health-status/v1are supported, not only two segments. - Direct dereference. The bare
GET /credentials/{vct_path}route is also served for consumers that dereference thevctdirectly. - Auth and prefixes. Both routes are public (no authentication) and expect path-prefix deployments to strip the issuer prefix before forwarding to Notary, while preserving the external host and scheme.
- Not found. Both return
404when OID4VCI is disabled or the reconstructed absolute URL does not exactly match a configured credential configurationvct. - Document contents. The Type Metadata document includes the exact configured
vct, display metadata, and one claim metadata entry for the OID4VCI configuration’sclaim_id. Notary-issued claim results are always selectively disclosable, so claim metadata usessd: "always". - CORS. Browser-based wallets from configured self-attestation wallet origins
receive CORS headers on the
/.well-known/vct/...metadata surface.
Verification
Section titled “Verification”Registry Notary ships a verifier compatibility harness that exercises the
verify_sd_jwt_vc path in registry-notary-client against a committed set of
golden fixtures. The harness requires no secret material and no network access.
Run the harness:
cargo test -p registry-notary-server --test sd_jwt_vc_verifier_compatOr with cargo-nextest:
cargo nextest run -p registry-notary-server sd_jwt_vc_verifier_compatFixture files live under tests/fixtures/sd_jwt_vc/. To regenerate them using
the server issuance path:
cargo run -p xtask -- gen-sd-jwt-vc-fixturesThe fixture set covers one valid credential, one valid holder-bound credential,
and seven negative variants: unsupported algorithm, wrong kid, wrong vct,
missing cnf when holder binding is required, malformed disclosure, expired
credential, and holder proof mismatch. Each negative fixture is asserted against
its exact error code from the verifier API.
Explicit Non-Support
Section titled “Explicit Non-Support”The following features are out of scope for the current profile:
application/vc+sd-jwtcompatibility alias;- JSON-LD Verifiable Credential issuance;
- Data Integrity proofs;
- external status-list or revocation-list profiles;
- mDoc/mDL;
- CWT proof binding;
- full OpenID4VCI issuer behavior.
These features require separate compatibility, lifecycle, and security design before implementation.