Skip to content
Registry StackDocsv0.20.0

Run the OID4VCI interoperability checks

For the operator

View as Markdown

Run the maintained OpenID for Verifiable Credential Issuance (OID4VCI) adopter journey and interoperability checks. You will copy a complete configuration, exercise the real adapter binary, then learn when to run the opt-in upstream Inji client check and how narrowly to describe either result.

Outcome
A checked and exercised local OID4VCI adapter configuration, plus reproducible evidence for the frozen profile and optional pinned Inji revisions.
Time
About 10 minutes for the ordinary check; longer for the opt-in upstream builds
Level
Source checkout and synthetic interoperability evidence
Prerequisites
A registry-stack source checkoutThe repository Rust toolchainBashPython 3Loopback ports 18440 through 18442 availableFor the optional upstream check: macOS, Git, network access, npm, Java 17, Android SDK platform 34 with Build Tools 33.0.1, full Xcode, and an iPhone 15 simulator

The runners create their disposable working material and remove it when they exit. They use a sanitized profile and synthetic values. Do not replace the fixture with a live credential, token, proof, nonce, selector, subject identifier, or issuer response.

Start at the root of a clean registry-stack source checkout. The ordinary runner uses only the checked-in sanitized profile at products/evidence/fixtures/interoperability/inji-oid4vci/profile.json and the Registry-side tests. The upstream runner is opt-in because it fetches and builds three pinned public source revisions.

Create an owner-only working directory. The runner will create the delivery client key there, restrict it to the owner, and remove it before returning:

Terminal window
umask 077
mkdir -p .tutorial/oid4vci-adopter

Copy this complete loopback configuration exactly:

version: 1
validationMode: supervised-local-development
credentialIssuer: http://127.0.0.1:18440
listener:
address: 127.0.0.1
port: 18440
metricsListener:
address: 127.0.0.1
port: 18441
evidence:
baseUrl: http://127.0.0.1:18442
mint:
tokenEndpoint: http://127.0.0.1:18442/token
clientId: evidence-oid4vci-tutorial
privateKeyFile: delivery-client.jwk.json
offers:
issuer: http://127.0.0.1:18442
jwksUri: http://127.0.0.1:18442/.well-known/jwks.json
audiences: ["http://127.0.0.1:18440"]
algorithms: [ES256]
authorizedClients: [tutorial-operator]
store:
maximumOffers: 256
offerLifetimeSeconds: 300
accessTokenLifetimeSeconds: 300
nonceLifetimeSeconds: 120
maximumTransactionCodeAttempts: 3

This is a supervised local configuration. Its public and metrics listeners are distinct loopback ports. The maintained runner supplies deterministic synthetic Evidence and authorization support; it does not contact a live issuer or use a real subject.

Run the ordinary check against the configuration you copied:

Terminal window
EVIDENCE_OID4VCI_ADOPTER_ROOT="$PWD/.tutorial/oid4vci-adopter" \
products/evidence/scripts/compat/inji-oid4vci.sh

The successful run ends with this exact receipt:

PASS: sanitized Inji OID4VCI profile and Registry-side interoperability tests

The runner follows the published metadata rather than fixed protocol paths. It resolves the offered credential configuration, redeems the pre-authorized code, requests a nonce with an unauthenticated empty POST, submits an Inji-shaped ES256 proof through self-contained did:jwk#0, reads plural credentials, and independently verifies the returned holder-bound Evidence presentation contract.

The maintained harness creates every value that is not in the copied configuration: the delivery client, offer signer, holder key, codes, tokens, nonces, synthetic Evidence response, and relying policy. It fixes the independently trusted relying policy before any credential is issued. Those runtime-only values stay in the owner-only working directory and are removed when the run ends.

Before those compatibility cases, the runner invokes the actual evidence-oid4vci binary. It runs check against the copied file, runs inspect and checks the derived batch ceiling, starts serve, probes /health and /ready, confirms that /metrics exists only on the separate private listener, completes an authorized wallet flow through the published metadata, and verifies the returned holder-bound presentation independently. Its safe milestones include:

CONFIG COPIED: complete configuration has no untracked inputs
CONFIG CHECKED: complete delivery configuration is valid
METADATA INSPECTED: derived holder-bound batch ceiling is 4
SERVICE READY: health and readiness are available on the delivery listener
METRICS PRIVATE: metrics exist only on the separate loopback listener
PRESENTATION VERIFIED: public wallet flow returned holder-bound Evidence
CLEANUP COMPLETE: generated private material was removed

The same run refuses malformed or private holder keys, an unsupported proof algorithm, the wrong proof audience, an unknown or tampered nonce, an expired proof, a remote key reference, an excessive proof batch, and a duplicate holder key. The state-recovery suite separately pins the expired-nonce boundary. A recognized live access token is consumed before proof validation, and a refused proof makes no Evidence request. A separate case reuses one nonce across two live authorizations, then proves that two concurrent requests with one token have at most one successful Evidence call.

The sanitized profile records the upstream target reviewed on 2026-08-09:

ComponentRevision
Inji Wallet2fa12c3285b6523db340c3dd2333454b750b40a4
Inji Android VCI clientf1d7ee2b14e996e18bfc7c40fbf89ec31b768951
Inji iOS VCI clientdbe60eef9a8c7b71ba58ee81cc7d0e5a92af7c7c

The ordinary run records the checked-in fixture and Registry-side behavior. Ordinary continuous integration validates the stored receipt’s shape and consistency with the profile, then runs the Registry-side tests. It does not fetch or rerun the pinned upstream clients.

The separate upstream receipt records bounded exact-pin evidence from 2026-08-09: the focused public tests from all three pinned repositories built and passed beside the sanitized Registry flow in the stated clean environment. It does not record a pinned Inji client crossing HTTP to Registry.

Run the opt-in check when the acceptance process requires a clean build against the exact public Inji revisions:

The combined upstream runner is macOS-only because its final suite uses Xcode and the iOS Simulator. Before running it, install Java 17, Android SDK platform 34 with Build Tools 33.0.1, full Xcode, and an iPhone 15 simulator. The runner requires git, npm, java, xcodebuild, and xcrun on PATH, plus network access.

Terminal window
EVIDENCE_INJI_OID4VCI=1 products/evidence/scripts/compat/inji-oid4vci-upstream.sh

The successful run ends with this exact receipt:

PASS: pinned Inji OID4VCI source and client tests

The runner fetches only the pinned revisions. It exercises the public client tests from clean temporary checkouts and removes those checkouts on exit. Its sanitized result is recorded in products/evidence/fixtures/interoperability/inji-oid4vci/receipt.json; keep the revision pins, test date, environment, and exclusions together when retaining a later result.

A completed runner removes generated private material. Remove the copied configuration and its now-empty working directories:

Terminal window
rm -f .tutorial/oid4vci-adopter/oid4vci.yaml
rmdir .tutorial/oid4vci-adopter .tutorial 2>/dev/null || true

The source checkout and checked-in sanitized fixture remain unchanged. If a runner is interrupted, remove only .tutorial/oid4vci-adopter; do not delete or rewrite the source checkout.

  • The sanitized Registry profile and Registry-side tests agree on the metadata-driven OID4VCI Final flow.
  • The actual adapter binary accepted the copied configuration and completed its local public HTTP journey with health, readiness, private metrics, and independent presentation verification.
  • An opt-in passing run confirms the exact pinned Inji client source tests in that clean build environment.
  • Neither receipt is full OID4VCI certification or a compatibility promise for another Inji revision.

The checks include no Android or iOS user-interface or device automation, live issuer, live user data, durable state, or multi-replica deployment. They do not cover authorization code, DPoP, deferred or encrypted issuance, notification, credential status, or other credential formats.

SymptomCauseResolution
The ordinary runner reports fixture driftThe sanitized profile no longer matches the runtime metadata or request and response shapes.Review the profile change and the failing Registry test together. Do not update the fixture without the corresponding runtime evidence.
The adopter journey cannot bind a listenerOne of loopback ports 18440 through 18442 is already in use.Stop the conflicting local service and rerun. Do not change only one copy of the configuration because the executable fixture intentionally checks exact drift.
Cargo cannot build the Registry testsThe checkout lacks the repository Rust toolchain or locked dependencies.Install the pinned toolchain and rerun from the repository root.
The upstream runner exits before cloningThe opt-in environment variable is absent, or the runner has no network access.Set EVIDENCE_INJI_OID4VCI=1 only in a network-enabled clean runner.
The runner prints Pinned Inji OID4VCI checking requires macOS because the combined receipt includes iOS client tests.The combined runner was started on another operating system.Rerun the optional combined check on macOS.
The runner prints Pinned Inji OID4VCI checking needs Java 17; the installed runtime is not Java 17., Pinned Inji OID4VCI checking needs ANDROID_HOME or ANDROID_SDK_ROOT to name an installed Android SDK., or Pinned Inji OID4VCI checking needs Android SDK platform 34 and Build Tools 33.0.1.The Android client prerequisites are missing or not selected.Install a Java 17 JDK, set JAVA_HOME, install the named Android packages, and set ANDROID_HOME or ANDROID_SDK_ROOT.
The runner prints Pinned Inji OID4VCI checking needs full Xcode, not Command Line Tools alone., Pinned Inji OID4VCI checking could not inspect installed iOS simulators., or Pinned Inji OID4VCI checking needs an available iPhone 15 simulator.Full Xcode or the iPhone 15 simulator is missing or unavailable.Install full Xcode, select it with xcode-select, accept its licence, and install an iPhone 15 simulator.
A pinned upstream build failsThe checked revision, toolchain, or resolved dependencies did not reproduce in this environment.Retain the failed result and environment details. Do not replace the pin with a mutable branch or describe the failed run as compatibility evidence.