Skip to content
Registry StackDocsDevelopment (unreleased)

Deliver to a wallet

For the operator

View as Markdown

If you run Registry Evidence and a wallet must receive its holder-bound SD-JWT VC responses over OID4VCI, run rstack evidence oid4vci serve beside it. The wallet-delivery service speaks the protocol Registry Evidence does not, and turns each response into the credential the wallet stores. It never signs, never holds a holder private key, and adds no Evidence semantics, so how Evidence works still describes every decision.

  • A definition with subjectBinding: holder-bound that permits sd-jwt-vc, as Enable SD-JWT VC sets up. The front end offers only holder-bound definitions.
  • A running Registry Evidence, as Build and deploy an Evidence project leaves you.
  • A TLS proxy that publishes the front end’s public HTTPS origin.
  • The Evidence component selected by rstack, installed through Install Registry Stack. rstack evidence oid4vci selects its matching managed wallet-delivery helper. You can instead use the image ghcr.io/registrystack/evidence-oid4vci:<tag> from the latest release. The image runs as the distroless nonroot user (uid 65532), exposes port 8090, and runs serve --runtime-config /etc/registry-evidence-oid4vci/runtime.yaml. Mount the runtime file and the token client and audit hash keys read-only. Mount persistent writable storage at /var/lib/registry-evidence-oid4vci for the adapter’s audit journal. The image has no shell, so your platform owns the probes.

The runtime file names the front end’s public origin, the Registry Evidence it fronts, the token client it calls that gateway with, and who may create a credential offer. Start from this one and replace every origin with your own:

runtime.yaml
# yaml-language-server: $schema=https://id.registrystack.org/schemas/evidence/oid4vci-runtime/oid4vci-runtime.v1alpha1.schema.json
apiVersion: id.registrystack.org/formats/evidence/oid4vci-runtime/v1alpha1
kind: EvidenceOid4vciRuntimeConfig
credentialIssuer: https://wallet.example.org
listener:
bind: 127.0.0.1:8090
secretProviders:
file:
root: /run/secrets/evidence-oid4vci
audit:
destination: file
path: /var/lib/registry-evidence-oid4vci/audit.jsonl
hashKeyRef: secret:file/audit-hash-key
evidence:
baseUrl: https://evidence.example.org
tokenClient:
tokenEndpoint: https://mint.example.org/token
clientId: evidence-oid4vci
privateKeyRef: secret:file/delivery-client.jwk.json
resource: https://evidence.example.org
offers:
issuer: https://mint.example.org
jwksUri: https://mint.example.org/.well-known/jwks.json
audiences: ["https://wallet.example.org"]
allowedClients: [adopter-front-end]
requiredScopes: [oid4vci:offer]
store:
maximumOffers: 4096

credentialIssuer is the public origin your TLS proxy publishes, which wallets see. listener.bind is the private address the proxy forwards to: keep a loopback or private address on a non-zero port such as 8090, not the public origin’s 443. The listener speaks plain HTTP.

privateKeyRef and audit.hashKeyRef follow the secret reference grammar. Both key files must be regular files owned by the service user, mode 0400 or 0600, with a single link. The audit key produces stable pseudonyms for the authenticated offer client, subject, or both without storing their raw identities. Preserve it for as long as those records must remain correlatable. A file destination is the durable journal; use stdout only when the deployment collector durably accepts and preserves every line. Every key has the bounds and default its schema gives it, and check also enforces the rules a schema cannot hold:

  • store.nonceLifetimeSeconds must not exceed store.accessTokenLifetimeSeconds.
  • The listener port must be non-zero.
  • metricsListener.bind must be a loopback or private address on a non-zero port the delivery listener does not use.
  • A reference must name a provider the file enables, and secretProviders.file.root must be absolute.

Check the file before the service reads it:

Terminal window
rstack evidence oid4vci check --runtime-config runtime.yaml
0 errors, 0 warnings in 1 file

check reads that one file and nothing else, so it does not prove that either key resolves, that the client key parses, or that the audit destination can open. inspect resolves and parses the client key to read Registry Evidence metadata, but it does not read the audit key or open the audit destination. serve resolves both keys, parses the client key, and opens the audit destination when it starts. See evidence-oid4vci check.

With the client key in place, inspect reads the Registry Evidence’s definitions and prints the metadata the service would publish. It can run beside the serving process because it does not open or lock the audit destination:

Terminal window
rstack evidence oid4vci inspect --runtime-config runtime.yaml

It prints one JSON document: the profile marker registry.evidence.oid4vci-profile/v1, the credential issuer and authorization server metadata, and a deployment block stating one replica, that a restart invalidates outstanding exchanges, and whether metrics are enabled. If the gateway cannot be reached, it exits 1 and logs that the credential source is unavailable. The wire behavior follows the frozen OID4VCI profile, which also lists what the front end does not support.

Render the HTTP contract your own front end and the wallet will call, then start the service:

Terminal window
rstack evidence oid4vci openapi --output evidence-oid4vci.openapi.json
Terminal window
rstack evidence oid4vci serve --runtime-config runtime.yaml

Your front end creates a credential offer at /offers with an access token the offers block admits; the wallet calls the two /.well-known metadata routes, /token, /nonce, and /credential. The wallet delivery API reference renders the same document. /health answers {"status":"ok"} while the process runs, and /ready answers {"status":"ready"} while the required local audit destination can accept entries. It answers 503 after that destination stops or stalls. Readiness does not depend on the state of the gateway or token issuer.

Run exactly one replica: offers, codes, and tokens live in process memory, and a restart invalidates every outstanding exchange. An independent process has a different tagging key and no matching live state, so it refuses another process’s codes and tokens as unknown. One replica keeps every later request routed to the process that created the exchange. A change to the gateway’s bundle or batch ceiling needs a coordinated restart: stop evidence-oid4vci, change or restart the gateway, then start evidence-oid4vci again so its first catalog comes from the new gateway.

The service bounds what a caller can make it do. Every response carries the shared security headers, and a request body over listener.maximumRequestBytes (16384 bytes by default, 1024 to 1048576) is refused before it is parsed. A request the web framework refuses, for a malformed body, an oversize body, or an unsupported content type, is answered in the service’s {"error", "error_description"} JSON shape and not in plain text.

The optional rateLimits block sets request budgets as token buckets. A runtime file without it is valid and takes the defaults below. A request over its budget is answered 429 with a Retry-After header and {"error": "temporarily_unavailable"}.

KeyDefaultWhat it budgets
offersPerPrincipalPerMinute600Offers one authorized principal (the token’s client, else its subject) may create per minute
offerBurst60The most offers one principal may create in a burst
walletRequestsPerMinute3000Requests per minute each of the token, nonce, and credential endpoints takes from all wallets together
walletRequestBurst300The most requests each of those endpoints admits in a burst

The token, nonce, and credential endpoints each have one budget shared by every wallet, so a busy deployment spends it quickly. These budgets use one key for all wallets, so they bound the service as a whole and cannot tell one client from another: a single source can spend a shared budget and lock every wallet out of that endpoint until it refills. Rate limit per source address at your ingress in front of those three paths as well. Check that the defaults suit your wallet traffic before you upgrade a busy deployment, and raise them in rateLimits rather than behind the proxy alone.

Set metricsListener.bind to serve Prometheus text at /metrics on a private address:

MetricWhat it counts
evidence_oid4vci_http_requests_totalDelivery requests by closed outcome class
evidence_oid4vci_http_request_duration_secondsDelivery request latency
evidence_oid4vci_outcomes_totalProtocol and upstream outcomes
evidence_oid4vci_store_entriesEntries in the fullest bounded offer, ledger, or token keyspace
evidence_oid4vci_store_capacityRefusal threshold for each bounded keyspace
evidence_oid4vci_cleanup_expired_totalExpired in-memory entries released by cleanup

The /credential request carries one jwt proof for each holder key. The service checks, in this order, a bare openid4vci-proof+jwt header typ, one key nomination (an inline public jwk or a local did:jwk kid), an ES256 alg that agrees with the key, the signature, and then the payload claims it uses: aud must be the credential issuer identifier as one string, iat must be fresh, nonce must be the current challenge, and an optional exp must not have passed. iss must be absent, because a pre-authorized code flow has no authenticated client.

Every other payload claim is ignored, as RFC 7519 section 4 directs for claims an implementation does not understand, so a wallet library that adds jti still receives its credential. Header parameters stay a closed set.

A refused proof answers invalid_proof with an error_description that names the failed rule, for example “the proof was not accepted: required claim nonce is missing”. The same wording goes to the service log. Neither repeats a nonce, a key, or any value the proof carried.

Each release is checked against one wallet: Inji Wallet, at the exact revisions of the wallet and its Kotlin and Swift OID4VCI clients that the pinned profile names. The check drives the release’s evidence-oid4vci binary through the pre-authorized code flow of OID4VCI 1.0 Final with a did:jwk holder key and an ES256 proof, and verifies that the dc+sd-jwt credential it returns is holder-bound Evidence. It also replays twelve refusals, among them a wrong proof audience, a reused or expired nonce, and a replayed access token. The profile records those wire shapes and cases, plus what the check excludes: device or UI testing, authorization code with PAR and DPoP, deferred or encrypted issuance, and more than one replica. The receipt records the run against those upstream revisions on 2026-08-09: the environment, the client tests that passed, and the claim boundary. A pass is bounded evidence for those revisions, not certification or general Inji compatibility. The check scripts live in the repository for contributors.

To confirm your own deployment, have your front end create a credential offer at /offers for a holder-bound definition and open it in the wallet your holders use. The wallet reads the metadata, redeems the pre-authorized code at /token, fetches a nonce, and calls /credential; the credential it stores is the Registry Evidence’s SD-JWT VC response, bound to the wallet’s key.

CodeMeaningRecovery
platform.runtime-config.unavailableThe runtime file could not be read.Check that the file exists and that the runtime user can read it.
evidence.oid4vci.https-requiredAn origin is not https in strict mode.Write an https URL, or set validationMode: supervised-local-development for a loopback process group.
evidence.oid4vci.listener-portThe listener port is zero.Bind the listener to a non-zero private port your TLS proxy forwards to.
evidence.oid4vci.nonce-lifetimeThe nonce outlives the access token.Lower store.nonceLifetimeSeconds to at most store.accessTokenLifetimeSeconds.
evidence.oid4vci.secret-file-rootThe file provider root is relative.Write secretProviders.file.root as an absolute directory path.
evidence.oid4vci.secret-provider-disabledThe key reference names a provider the file does not enable.Declare that provider under secretProviders, or reference the key through an enabled one.
evidence.oid4vci.audit-secret-provider-disabledThe audit hash key reference names a provider the file does not enable.Declare that provider under secretProviders, or reference the audit key through an enabled one.
evidence.oid4vci.invalid-auditThe audit destination settings do not describe a usable file or stdout destination.Use an absolute file path with valid rotation and retention settings, or select stdout with no file-only settings.
evidence.oid4vci.metrics-shared-bindingThe metrics listener shares the delivery binding.Bind the metrics listener to a port the delivery listener does not use.
evidence.oid4vci.wildcard-spelled-itemAn offers list item spells * or unrestricted, which matches only itself (a warning).Write unrestricted in place of the list, or remove the item.
invalid_proof (wallet response)The proof failed a named check.Read the check in error_description, then correct that header parameter or claim in the wallet’s proof.

evidence-oid4vci runtime configuration

Source preview, pre-1.0

Generated from products/evidence/generated/oid4vci-runtime/oid4vci-runtime.schema.json. 65 key paths. Explained in docs/site/src/content/docs/configure/evidence-oid4vci.mdx.

Key pathTypeRequiredAccepted valuesConstraints
apiVersionThe format version of this file.stringYes
  • id.registrystack.org/formats/evidence/oid4vci-runtime/v1alpha1
None specified
auditThe required durable audit journal for offer attribution and delivery outcomes. stdout is available for a collector-managed deployment; only a file destination supplies durability itself.objectYesNot specifiedNone specified
audit.destinationThe configured audit destination kind, as written in product configuration.stringNo
  • file
  • stdout
Schema default, where declared: "file"
None specified
audit.hashKeyRefSecret reference to the audit hash key.stringYesNot specified
  • pattern: ^(?:secret:env/[A-Z][A-Z0-9_]{0,127}|secret:file/[a-z][a-z0-9._-]{0,127})$
audit.pathstringNoNot specified
  • pattern: ^/
audit.retentionDaysintegerNoNot specified
  • format: uint32
  • maximum: 36500
  • minimum: 1
audit.rotateBytesintegerNoNot specified
  • format: uint64
  • maximum: 4294967295
  • minimum: 1048576
credentialIssuerThe credential_issuer identifier this service publishes, and the value a wallet proof must carry as its aud: a bare origin with no path, query, or fragment. https in strict mode. A trailing slash is removed, so what is published and what is compared are the same bytes.stringYesNot specified
  • format: uri
  • maxLength: 2048
  • pattern: ^[Hh][Tt][Tt][Pp][Ss]?://[^/?#@\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+([/?#][^\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*)?$
draft13ProfileServes the OpenID4VCI Draft 13 compatibility profile beside the 1.0 Final profile, at its own issuer identifier: the credentialIssuer followed by /protocol/oid4vci/draft-13. Written as an empty mapping, draft13Profile: {}; absent means the profile is not served and none of its routes exist. It shares the offer store and the offer authorization with the 1.0 profile, and an offer made for one profile cannot be redeemed through the other.objectNoNot specifiedNone specified
evidenceThe Evidence deployment this service requests credentials from.objectYesNot specifiedNone specified
evidence.baseUrlThe Evidence base URL, with no query or fragment. https in strict mode.stringYesNot specified
  • format: uri
  • maxLength: 2048
  • pattern: ^[Hh][Tt][Tt][Pp][Ss]?://[^/?#@\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+([/?#][^\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*)?$
kindThe document kind.stringYes
  • EvidenceOid4vciRuntimeConfig
None specified
listenerThe listener a wallet and an adopter reach.objectYesNot specifiedNone specified
listener.bindSocket address the runtime listens on, written host:port with an IP address host ([addr]:port for IPv6).stringYesNot specified
  • maxLength: 128
  • minLength: 1
listener.maximumRequestBytesThe largest request body accepted, in bytes. A limit no wallet request can survive leaves the service reporting itself ready while every request fails.integerNoNot specifiedSchema default, where declared: 16384
  • format: uint32
  • maximum: 1048576
  • minimum: 1024
listener.requestTimeoutMillisecondsHow long one request may take, in milliseconds.integerNoNot specifiedSchema default, where declared: 5000
  • format: uint64
  • maximum: 30000
  • minimum: 1
metricsListenerThe optional operator-only metrics listener: a loopback or private address the delivery listener does not use. Absent means no metrics endpoint exists.objectNoNot specifiedNone specified
metricsListener.bindSocket address the runtime listens on, written host:port with an IP address host ([addr]:port for IPv6).stringYesNot specified
  • maxLength: 128
  • minLength: 1
offersThe authorization boundary of the adopter-facing offer endpoint.objectYesNot specifiedNone specified
offers.algorithmsThe one signature algorithm an offer token may be signed with.arrayNoNot specifiedSchema default, where declared: ["EdDSA"]
  • maxItems: 1
  • minItems: 1
  • uniqueItems: true
offers.algorithms[]Array itemThe signature algorithms an offer token may be signed with. The same closed vocabulary Evidence accepts on its own resource-server profile. Mixing families is refused when the configuration loads rather than when the first token arrives.stringNo
  • ES256
  • EdDSA
  • RS256
None specified
offers.allowInsecureHttpPermit plain HTTP beyond loopback to the offer-token issuer and to jwksUri.booleanNoNot specifiedSchema default, where declared: falseNone specified
offers.allowedClientsClient identifiers permitted to create offers, each at most 128 bytes, or unrestricted for any client the issuer vouched for.array | stringYes
  • unrestricted

No bound

or

  • minItems: 1
  • uniqueItems: true
offers.allowedClients[]Array itemAn identifier another system issues, written exactly as its issuer gives it.stringConditionalNot specified
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.audiencesThe audiences this service answers to, each at most 256 bytes. A token issued for anything else is refused.arrayYesNot specified
  • minItems: 1
  • uniqueItems: true
offers.audiences[]Array itemAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specified
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claimsContextual claim names used by this offer-token issuer. Keep these aligned with Evidence when both verify tokens from the same deployment.objectNoNot specifiedSchema default, where declared: {"actorKind":"registry_actor_kind","approver":"registry_approver","grantBounds":"registry_grant_bounds","grantClient":"registry_grant_client","grantExp":"registry_grant_exp","grantId":"registry_grant_id","grantResource":"registry_grant_resource","grantSourceIssuer":"registry_grant_source_issuer","purpose":"registry_purpose"}None specified
offers.claims.actorKindAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_actor_kind"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claims.approverAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_approver"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claims.grantBoundsAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_grant_bounds"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claims.grantClientAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_grant_client"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claims.grantExpAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_grant_exp"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claims.grantIdAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_grant_id"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claims.grantResourceAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_grant_resource"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claims.grantSourceIssuerAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_grant_source_issuer"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.claims.purposeAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specifiedSchema default, where declared: "registry_purpose"
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
offers.issuerThe authorization server that issues offer tokens, compared exactly against a token's iss. https in strict mode.stringYesNot specified
  • format: uri
  • maxLength: 2048
  • pattern: ^[Hh][Tt][Tt][Pp][Ss]?://[^/?#@\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+([/?#][^\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*)?$
offers.jwksUriThe offer-token issuer's key set. https in strict mode.stringYesNot specified
  • format: uri
  • maxLength: 2048
  • pattern: ^[Hh][Tt][Tt][Pp][Ss]?://[^/?#@\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+([/?#][^\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*)?$
offers.maximumTokenLifetimeSecondsThe longest lifetime an offer token may carry, in seconds.integerNoNot specifiedSchema default, where declared: 900
  • format: uint64
  • maximum: 3600
  • minimum: 60
offers.requiredScopesScopes every offer token must carry, each an RFC 6749 scope token of at most 256 bytes, or unrestricted for no scope gate. Generated configurations state oid4vci:offer.array | stringYes
  • unrestricted

No bound

or

  • minItems: 1
  • uniqueItems: true
offers.requiredScopes[]Array itemAn identifier another system issues, written exactly as its issuer gives it.stringConditionalNot specified
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
rateLimitsRequest budgets. Absent means the defaults of each member.objectNoNot specifiedNone specified
rateLimits.offerBurstThe most offers one authorized principal may create in a burst.integerNoNot specifiedSchema default, where declared: 60
  • format: uint32
  • maximum: 100000
  • minimum: 1
rateLimits.offersPerPrincipalPerMinuteOffers one authorized principal may create per minute.integerNoNot specifiedSchema default, where declared: 600
  • format: uint32
  • maximum: 100000
  • minimum: 1
rateLimits.walletRequestBurstThe most requests each wallet endpoint admits in a burst.integerNoNot specifiedSchema default, where declared: 300
  • format: uint32
  • maximum: 100000
  • minimum: 1
rateLimits.walletRequestsPerMinuteRequests per minute each of the token, nonce and credential endpoints takes from all wallets together.integerNoNot specifiedSchema default, where declared: 3000
  • format: uint32
  • maximum: 1000000
  • minimum: 1
secretProvidersThe secret providers tokenClient.privateKeyRef may name.objectYesNot specifiedNone specified
secretProviders.environmentEnables secret:env/NAME references, read from the process environment. Declared as an empty mapping: environment: {}.objectConditionalNot specifiedNone specified
secretProviders.fileEnables secret:file/name references, read from files under root.objectConditionalNot specifiedNone specified
secretProviders.file.rootAbsolute directory holding one file per secret. Each file must be a regular file owned by the runtime user, mode 0400 or 0600, with exactly one hard link.stringConditionalNot specified
  • pattern: ^/
storeThe bounds of the in-memory store.objectNoNot specifiedSchema default, where declared: {"accessTokenLifetimeSeconds":300,"maximumOffers":4096,"maximumTransactionCodeAttempts":3,"nonceLifetimeSeconds":120,"offerLifetimeSeconds":300}None specified
store.accessTokenLifetimeSecondsHow long an access token lives, in seconds.integerNoNot specifiedSchema default, where declared: 300
  • format: uint64
  • maximum: 900
  • minimum: 60
store.maximumOffersHow many offers the store holds. A store too small to hold a deployment's live offers refuses new ones rather than forgetting old ones.integerNoNot specifiedSchema default, where declared: 4096
  • format: uint32
  • maximum: 1048576
  • minimum: 256
store.maximumTransactionCodeAttemptsHow many wrong transaction codes an offer survives.integerNoNot specifiedSchema default, where declared: 3
  • format: uint32
  • maximum: 10
  • minimum: 1
store.nonceLifetimeSecondsHow long a nonce lives, in seconds; at most the access token lifetime.integerNoNot specifiedSchema default, where declared: 120
  • format: uint64
  • maximum: 900
  • minimum: 30
store.offerLifetimeSecondsHow long an offer lives, in seconds. Minutes, in both directions: shorter than a person can scan a code and read a message, and the flow cannot complete; longer, and a stolen offer stays useful.integerNoNot specifiedSchema default, where declared: 300
  • format: uint64
  • maximum: 900
  • minimum: 60
tokenClientThe identity this service authenticates to its token issuer with.objectYesNot specifiedNone specified
tokenClient.clientAssertionAudienceThe value the endpoint expects as the client assertion aud. Absent means the token endpoint, which is the usual registration.stringNoNot specified
  • format: uri
  • maxLength: 2048
  • pattern: ^[Hh][Tt][Tt][Pp][Ss]?://[^/?#@\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+([/?#][^\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*)?$
tokenClient.clientIdThe client identifier registered with the token issuer, at most 128 bytes.stringYesNot specified
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
tokenClient.privateKeyRefThe client's own private JWK, as secret:file/<name> under secretProviders.file.root or secret:env/<NAME>. Resolved when the outbound client is built, never logged and never rendered.stringYesNot specified
  • pattern: ^(?:secret:env/[A-Z][A-Z0-9_]{0,127}|secret:file/[a-z][a-z0-9._-]{0,127})$
tokenClient.resourceThe fixed RFC 8707 resource identifier of the Evidence API: an absolute URI with no fragment or user information.stringNoNot specified
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
tokenClient.scopesThe exact scopes requested from the issuer for Evidence access: 1 to 32 distinct RFC 6749 scope tokens. Absent requests no scope.arrayNoNot specified
  • maxItems: 32
  • minItems: 1
  • uniqueItems: true
tokenClient.scopes[]Array itemAn identifier another system issues, written exactly as its issuer gives it.stringNoNot specified
  • maxLength: 512
  • minLength: 1
  • pattern: ^[^\u0000-\u001F\u007F-\u009F]+$
tokenClient.tokenEndpointThe token endpoint, with no query or fragment. https in strict mode.stringYesNot specified
  • format: uri
  • maxLength: 2048
  • pattern: ^[Hh][Tt][Tt][Pp][Ss]?://[^/?#@\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+([/?#][^\u005C\u0000-\u0020\u007F-\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*)?$
validationModeThe transport validation boundary. Absent means strict.stringNo
  • strict
  • supervised-local-development
Schema default, where declared: "strict"
None specified