Verifiable Health Link
0.0.2-current - ci-build
Verifiable Health Link, published by IHE IT Infrastructure Technical Committee. This guide is not an authorized publication; it is the continuous build for version 0.0.2-current built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/IHE/ITI.VHL/ and changes regularly. See the Directory of published versions
The Generate VHL transaction enables a VHL Holder to request a Verifiable Health Link (VHL) from a VHL Sharer for a Patient identified by a business identifier (e.g., MRN, passport number, national ID). The VHL Sharer locates the Patient, authorizes the caller, assembles a folder of available health documents, and returns a VHL that the VHL Holder can subsequently transmit to a VHL Receiver via ITI-YY4 Provide VHL for downstream document retrieval via ITI-YY5 Retrieve Manifest.
The VHL payload conforms to the SMART Health Links payload format and carries the manifest URL, a symmetric decryption key, and optional metadata (expiration, flags, label, purpose-of-use bindings). By default the VHL is returned as a QR code encoded as an HCERT/CWT structure per the WHO SMART Trust HCERT specification. When the VHL Sharer supports the VC Enveloped VHL Carrier Option, the caller MAY instead request the VHL as a signed W3C Verifiable Credential (application/vc+ld+json).
The transaction also supports optional passcode protection, purpose-of-use authorization metadata (which MAY populate an IHE PCF Consent.provision.purpose when the VHL Sharer is grouped with a Consent Creator/Recipient), and the OAuth with SSRAA Option for downstream authenticated manifest retrieval.
| Actor | Role |
|---|---|
| VHL Holder | Request that a VHL authorization mechanism be issued |
| VHL Sharer | Generate a VHL Authorization Mechanism Based on Query Parameters |
OAuth with SSRAA (Optional):
VC Enveloped VHL Option(Optional):
DataIntegrityProofFigure 2:3.YY3-1: Generate VHL Interaction Diagram
This message is implemented as an HTTP GET operation from the client app used by the Holder to the VHL Sharer using the FHIR $generate-vhl operation described in 2:3.YY3.4.1.2 Message Semantics.
A VHL Holder initiates a request to a VHL Sharer to generate a Verified Health Link (VHL) that references one or more health documents. The resulting VHL allows the Holder to subsequently share access to those documents with a VHL Receiver. The Holder MAY include optional parameters to constrain or protect the issued VHL-such as defining an expiration period, scoping which documents are included, or requiring a passcode for retrieval. These parameters guide the Sharer's issuance of the VHL and influence the conditions under which the associated documents may be accessed.
Preconditions:
The Generate VHL message is a FHIR operation request as defined in FHIR (http://hl7.org/fhir/operations.html) with the $generate-vhl operation definition.
Given that the parameters are not complex types, the HTTP GET operation shall be used as defined in FHIR (http://hl7.org/fhir/operations.html#request).
The name of the operation is $generate-vhl, and it is applied to FHIR Patient Resource type.
The URL for this operation is: [base]/Patient/$generate-vhl
Where [base] is the URL of VHL Sharer Service provider.
The Generate VHL message is performed by an HTTP GET command shown below:
GET [base]/Patient/$generate-vhl?sourceIdentifier=[token]{&exp=[positiveInt]}{&flag=[string]}{&label=[string]}{&passcode=[string]}{&purposeOfUse=[token]}{&format=[token]}
Each purposeOfUse value is serialized in FHIR token form (system|code, e.g., http://terminology.hl7.org/CodeSystem/v3-ActReason|TREAT) and MAY repeat.
Note: By default the operation generates a QR code containing the VHL encoded as an HCERT/CWT structure. When the VHL Sharer supports the VC Enveloped VHL Option the caller MAY set format=vc to request the VHL as a signed Verifiable Credential instead. See Output Carrier Options below for both carrier definitions.
Table 2:3.YY3.4.1.2-1: $generate-vhl Message HTTP query Parameters
| Query parameter Name | Cardinality | Search Type | Description |
|---|---|---|---|
| sourceIdentifier | [1..1] | token | A FHIR Identifier (business identifier — e.g., MRN, passport number, national ID) that the VHL Sharer uses to locate the Patient record and that Patient's documents. |
| exp | [0..1] | postiveInt | Optional. Number representing expiration time in Epoch seconds. |
| flag | [0..1] | string | Optional. String created by concatenating single-character flags in alphabetical order. L (long-term use), P (Passcode required), U (direct file access). |
| label | [0..1] | string | Optional. String no longer than 80 characters that provides a short description of the data behind the VHL. |
| passcode | [0..1] | string | Optional. User-supplied passcode for passcode-protected VHLs. If provided, the VHL Sharer SHALL securely hash and store this passcode for validation during manifest retrieval (ITI-YY5). The 'P' flag SHALL be included in the flag parameter when a passcode is set. |
| purposeOfUse | [0..*] | token | Optional. Purpose(s) of use the VHL Holder is authorizing for this share, bound (extensible) to PurposeOfUse (e.g., TREAT, HPAYMT, HRESCH). Serialized as FHIR system\|code. See Purpose of Use Handling. |
| format | [0..1] | token | Optional. Requested carrier for the returned VHL. Allowed values: qrcode (default) or vc. vc requires the VHL Sharer to support the VC Enveloped VHL Carrier Option; if unsupported, the VHL Sharer SHALL return an OperationOutcome error. See Output Carrier Options below. |
The format request parameter selects one of two carriers for the returned VHL. Both carriers convey the same VHL payload (manifest URL, decryption key, flags, label, expiration, optional extension); they differ only in encoding, signature format, and the trust chain used for verification. Exactly one of the response output parameters qrcode or verifiableCredential (see 2:3.YY3.4.2.2 Message Semantics) SHALL be populated.
QR Code Carrier (Default — format=qrcode)
The default carrier when format is omitted or set to qrcode. The VHL payload is embedded in an HCERT structure at claim key 5 per the WHO SMART Trust HCERT specification, signed as a CWT, and rendered as a QR code with the HC1: prefix. The VHL Receiver verifies the CWT signature against the trust list. See 2:3.YY3.4.1.3 Expected Actions for the full VHL Payload Construction and HCERT/CWT encoding steps, including a worked example.
VC Enveloped VHL Carrier (Option — format=vc)
Optional carrier. Available only when the VHL Sharer supports the VC Enveloped VHL Option (see Volume 1 §XX.2.6 VC Enveloped VHL Option); if requested but unsupported, the VHL Sharer SHALL return an OperationOutcome error. The same VHL payload is carried under credentialSubject of a JSON-LD W3C Verifiable Credential (VC Data Model v2) with an embedded DataIntegrityProof (VC Data Integrity 1.0) signed by the VHL Sharer using its trust-network key — no new trust framework is introduced. See 2:3.YY3.4.1.3 Expected Actions for the full construction steps and a worked example.
Naming note: This "VC Enveloped VHL Option" at ITI-YY3/YY4 carries the VHL itself. It is distinct from the "Verifiable Credential Option" at ITI-YY5, which is a separate option for VHL Receiver authentication where the Receiver self-issues a VC as the manifest request body.
The VHL Sharer SHALL generate a Verified Health Link (VHL) to be issued to a VHL Holder.
The Sharer SHALL conduct all necessary tasks to prepare the content referenced by the VHL. These tasks MAY be further defined by applicable content profiles or implementation guides, and MAY include:
Once content preparation is complete, the Sharer SHALL construct the VHL payload and sign it to produce a cryptographically verifiable authorization mechanism.
Optional behaviors:
Based on the requested format, the VHL Sharer generates the VHL as either a QR code (HCERT/CWT-encoded per the WHO SMART Trust HCERT specification, with the VHL payload embedded at claim key 5) or a Verifiable Credential (JSON-LD per the W3C VC Data Model v2, with the VHL payload under credentialSubject). Both carriers share the same VHL payload construction.
The generation process is as follows:
VHL Payload Construction
The VHL payload SHALL be constructed in alignment with the SMART Health Links specification. The VHL Sharer SHALL:
Generate a unique folder ID with 256-bit entropy to serve as the List resource identifier
Generate a 32-byte (256-bit) random encryption key, base64url-encode it (resulting in 43 characters) - this is the 'key' parameter. The VHL Receiver uses this key to decrypt document binaries retrieved via ITI-68; see ITI-YY5 Document Encryption.
[base]/List?_id=[folder-id]&code=folder&status=current&patient.identifier=[sourceIdentifier-system|value]&_include=List:item
[base]/List?_id=[folder-id]&code=folder&status=current&patient.identifier=[sourceIdentifier-system|value]
Note: The manifest URL is a FHIR search on List using the search parameters that the Document Responder in IHE MHD ITI-66 Find Document Lists is required to support — specifically _id, code, status, and the patient identifier expressed as a chained search on the patient reference parameter (patient.identifier=system|value). _include=List:item is added only when the VHL Sharer supports the Include DocumentReference Option.
url: the manifest URL from step 3key: the base64url-encoded encryption key from step 2 (43 characters). Used by the VHL Receiver as the symmetric key for JWE dir/A256GCM decryption of document binaries; see ITI-YY5 Document Encryption.exp: (optional) expiration time in Epoch seconds, as a hint to help the VHL Receiver determine if this QR is staleflag: (optional) flags string (e.g., 'P' for passcode, 'L' for long-term, 'U' for direct file access)label: (optional) description string (max 80 characters)v: version number (defaults to 1)extension: (conditional) object containing implementation-defined extensions. Required when the VHL Sharer supports the OAuth with SSRAA Option, in which case it SHALL include:
fhirBaseUrl: the FHIR base URL of the VHL Sharer (e.g., https://vhl-sharer.example.org). This enables the VHL Receiver to perform UDAP Discovery (per Section 2 of the HL7 Security for Scalable Registration, Authentication, and Authorization IG) and Dynamic Client Registration (per Section 3) with the VHL Sharer before making an authenticated manifest request via ITI-YY5.Example VHL Construction:
// Step 4: VHL Payload JSON (SHL payload format, with OAuth with SSRAA extension)
{
"url": "https://vhl-sharer.example.org/List/_search?_id=abc123def456&code=folder&status=current&patient.identifier=urn:oid:2.16.840.1.113883.2.4.6.3|PASSPORT123&_include=List:item",
"key": "86F8LY5LlWAa1-OS_FgrTnYNqFHJP2ey5RSKLJBN9jk",
"exp": 1735689600,
"flag": "LP",
"label": "Patient Health Summary",
"v": 1,
"extension": {
"fhirBaseUrl": "https://vhl-sharer.example.org"
}
}
// Step 5: Minify, Base64url-encode, and prefix with vhlink:/
// Step 5a – Minified JSON:
{"url":"https://vhl-sharer.example.org/List/_search?_id=abc123def456&code=folder&status=current&patient.identifier=urn:oid:2.16.840.1.113883.2.4.6.3|PASSPORT123&_include=List:item","key":"86F8LY5LlWAa1-OS_FgrTnYNqFHJP2ey5RSKLJBN9jk","exp":1735689600,"flag":"LP","label":"Patient Health Summary","v":1,"extension":{"fhirBaseUrl":"https://vhl-sharer.example.org"}}
// Step 5b – Base64url-encoded:
eyJ1cmwiOiJodHRwczovL3ZobC1zaGFyZXIuZXhhbXBsZS5vcmcvTGlzdC9fc2VhcmNoP19pZD1hYmMxMjNkZWY0NTYmY29kZT1mb2xkZXImc3RhdHVzPWN1cnJlbnQmcGF0aWVudC5pZGVudGlmaWVyPXVybjpvaWQ6Mi4xNi44NDAuMS4xMTM4ODMuMi40LjYuM3xQQVNTUE9SVDEyMyZfaW5jbHVkZT1MaXN0Oml0ZW0iLCJrZXkiOiI4NkY4TFk1TGxXQWExLU9TX0ZnclRuWU5xRkhKUDJleTVSU0tMSkJOOWprIiwiZXhwIjoxNzM1Njg5NjAwLCJmbGFnIjoiTFAiLCJsYWJlbCI6IlBhdGllbnQgSGVhbHRoIFN1bW1hcnkiLCJ2IjoxLCJleHRlbnNpb25zIjp7ImZoaXJCYXNlVXJsIjoiaHR0cHM6Ly92aGwtc2hhcmVyLmV4YW1wbGUub3JnIn19
// Step 5c – Final VHL link (prefixed with vhlink:/):
vhlink:/eyJ1cmwiOiJodHRwczovL3ZobC1zaGFyZXIuZXhhbXBsZS5vcmcvTGlzdC9fc2VhcmNoP19pZD1hYmMxMjNkZWY0NTYmY29kZT1mb2xkZXImc3RhdHVzPWN1cnJlbnQmcGF0aWVudC5pZGVudGlmaWVyPXVybjpvaWQ6Mi4xNi44NDAuMS4xMTM4ODMuMi40LjYuM3xQQVNTUE9SVDEyMyZfaW5jbHVkZT1MaXN0Oml0ZW0iLCJrZXkiOiI4NkY4TFk1TGxXQWExLU9TX0ZnclRuWU5xRkhKUDJleTVSU0tMSkJOOWprIiwiZXhwIjoxNzM1Njg5NjAwLCJmbGFnIjoiTFAiLCJsYWJlbCI6IlBhdGllbnQgSGVhbHRoIFN1bW1hcnkiLCJ2IjoxLCJleHRlbnNpb25zIjp7ImZoaXJCYXNlVXJsIjoiaHR0cHM6Ly92aGwtc2hhcmVyLmV4YW1wbGUub3JnIn19
// NOTE: extension.fhirBaseUrl is only present when the VHL Sharer supports the OAuth with SSRAA Option
// The VHL link (step 5c) will be embedded in the HCERT structure (see QR Code Generation below)
QR Code Generation (HCERT/CWT Encoding) — format=qrcode
After constructing the VHL payload (steps 1–4 above), the VHL Sharer SHALL encode it within an HCERT structure per the WHO SMART Trust specification with the VHL payload at HCERT claim 5, then generate the QR code per the HCERT Specification.
Example HCERT/CWT Structure:
// CWT Claims
{
"1": "US", // iss: issuer country code
"4": 1735689600, // exp: expiration timestamp
"6": 1704067200, // iat: issued at timestamp
"-260": { // hcert: health certificate claim
"5": "vhlink:/eyJ1cmwiOiJodHRwczovL3ZobC1zaGFyZXIuZXhhbXBsZS5vcmcvTGlzdC9fc2VhcmNoP19pZD1hYmMxMjNkZWY0NTYmY29kZT1mb2xkZXImc3RhdHVzPWN1cnJlbnQmcGF0aWVudC5pZGVudGlmaWVyPXVybjpvaWQ6Mi4xNi44NDAuMS4xMTM4ODMuMi40LjYuM3xQQVNTUE9SVDEyMyZfaW5jbHVkZT1MaXN0Oml0ZW0iLCJrZXkiOiI4NkY4TFk1TGxXQWExLU9TX0ZnclRuWU5xRkhKUDJleTVSU0tMSkJOOWprIiwiZXhwIjoxNzM1Njg5NjAwLCJmbGFnIjoiTFAiLCJsYWJlbCI6IlBhdGllbnQgSGVhbHRoIFN1bW1hcnkiLCJ2IjoxLCJleHRlbnNpb25zIjp7ImZoaXJCYXNlVXJsIjoiaHR0cHM6Ly92aGwtc2hhcmVyLmV4YW1wbGUub3JnIn19"
}
}
// After signing, compressing, and Base45 encoding:
HC1:NCF3R0KLBBA...V8N8W.CE8WY
VC Envelope Generation (Option — format=vc)
When format=vc is requested and the VHL Sharer supports the VC Enveloped VHL Option, the VHL Sharer SHALL construct a JSON-LD document per the W3C VC Data Model v2 with an embedded proof of type DataIntegrityProof per the W3C VC Data Integrity 1.0 specification (cryptosuite selected per the central Cryptographic Algorithm Selection). The issuer SHALL identify the VHL Sharer using a key from the same trust network used for HCERT/CWT signatures — no new trust framework is introduced. The credentialSubject SHALL carry the VHL payload from step 4 (url, key, flag, label, exp, v, extension). The VC is delivered to the VHL Holder and subsequently transmitted to the VHL Receiver per ITI-YY4 Provide VHL.
Example VC carrying the VHL payload:
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiableCredential", "VHLEnvelopeCredential"],
"issuer": "did:web:vhl-sharer.example.org",
"issuanceDate": "2024-01-01T00:00:00Z",
"expirationDate": "2025-01-01T00:00:00Z",
"credentialSubject": {
"url": "https://vhl-sharer.example.org/List?_id=abc123def456&code=folder&status=current&patient.identifier=urn:oid:2.16.840.1.113883.2.4.6.3|PASSPORT123&_include=List:item",
"key": "86F8LY5LlWAa1-OS_FgrTnYNqFHJP2ey5RSKLJBN9jk",
"exp": 1735689600,
"flag": "LP",
"label": "Patient Health Summary",
"v": 1,
"extension": {
"fhirBaseUrl": "https://vhl-sharer.example.org"
}
},
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "ecdsa-2019",
"created": "2024-01-01T00:00:00Z",
"verificationMethod": "did:web:vhl-sharer.example.org#sharer-key-1",
"proofPurpose": "assertionMethod",
"proofValue": "z3FD9sJ8kL2m9pQ7rT4vW5xY6zAb3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4yZ"
}
}
Handling Notes
The following handling rules apply within the steps above:
sourceIdentifier Validation — The VHL Sharer SHALL parse sourceIdentifier as a FHIR Identifier in system|value form, resolve it to a known Patient, authorize the caller, and echo the exact system|value into the manifest URL as patient.identifier (never substituting Patient.id). In patient-constrained contexts (e.g., SMART launch/patient scope), mismatches with the patient-in-context SHALL be rejected with 403. Other failures return OperationOutcome with 400 / 404 / 403 as appropriate.
Purpose of Use Handling (if provided) — The VHL Sharer SHALL validate each purposeOfUse value against PurposeOfUse (extensible binding) and persist the value(s) against the folder ID for downstream enforcement at ITI-YY5. When grouped with an IHE PCF Consent Creator or Consent Recipient, the persisted value(s) SHALL populate Consent.provision.purpose. purposeOfUse value(s) SHALL NOT be embedded in the QR code, VC, or VHL payload — they are share metadata held by the VHL Sharer, not content consumed by the VHL Receiver.
Passcode Handling (if provided) — The VHL Sharer SHALL hash the passcode with a strong one-way function (e.g., bcrypt, Argon2, PBKDF2), store the hash against the folder ID for ITI-YY5 validation, and set the P flag in the VHL payload. The plaintext passcode SHALL NOT appear in the VHL URL, QR code, or VC, and SHALL NOT be stored by the VHL Sharer; the VHL Holder retains it for out-of-band sharing with the VHL Receiver.
The VHL Sharer returns failure, or generates and returns a QR code containing the VHL encoded as an HCERT/CWT structure.
This message shall be sent when a request initiated by the VHL Holder has been processed successfully.
See ITI TF-2: Appendix Z.6 for more details on response format handling.
The response message is a FHIR operation response (http://hl7.org/fhir/operations.html#response).
On Failure, the response message is an HTTP status code of 4xx or 5xx indicates an error, and an OperationOutcome Resource shall be returned with details.
Success Response:
The response SHALL include exactly one of the following output parameters, selected by the format input:
| Parameter | Type | Cardinality | Description |
|---|---|---|---|
| qrcode | Binary | [0..1] | QR code image containing HCERT-encoded VHL. Populated when format=qrcode or when format is absent, as the default format. |
| verifiableCredential | Binary | [0..1] | A Verifiable Credential (application/vc+ld+json) carrying the VHL. Populated when format=vc and the VHL Sharer supports the VC Enveloped VHL Carrier Option. |
QR Code Output:
HC1: prefixVerifiable Credential Output (VC Enveloped VHL Option only):
Content-Type: application/vc+ld+jsoncredentialSubject (same fields otherwise embedded at HCERT claim key 5)DataIntegrityProof with its trust-network key (cryptosuite selected per Cryptographic Algorithm Selection)The VHL Holder SHALL:
The VHL Holder MAY:
_include parameter SHOULD only be included if the VHL Sharer supports the Include DocumentReference OptionWhen the VHL Sharer supports the OAuth with SSRAA Option, it SHALL include extension.fhirBaseUrl in the VHL payload:
fhirBaseUrl value SHALL be the canonical FHIR base URL of the VHL Sharer (e.g., https://vhl-sharer.example.org){fhirBaseUrl}/.well-known/udap) and, if not already registered, Dynamic Client Registration with the VHL Sharer before initiating ITI-YY5fhirBaseUrl value is typically derivable from the url field (manifest URL) by stripping the path, but including it explicitly avoids ambiguity when the authorization server is hosted separatelyfhirBaseUrl to avoid re-registering on every VHL scanfhirBaseUrl field SHALL NOT be present if the VHL Sharer does not support the OAuth with SSRAA Option, to avoid misleading VHL Receivers into attempting UDAP Discovery unnecessarilyDataIntegrityProof SHALL chain to a trust anchor in the trust list (same framework used for HCERT/CWT verification).expirationDate SHOULD be consistent with the VHL payload exp; the VHL Receiver SHALL reject the VHL if either has passed.key and MUST be treated as sensitive.