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
| 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):
Figure 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=[integer]}{&flag=[string]}{&label=[string]}{&passcode=[string]}
Note: The goal parameter has been removed. The operation always generates a QR code containing the VHL encoded as an HCERT/CWT structure.
Table 2:3.YY3.4.1.2-1: $generate-vhl Message HTTP query Parameters
| Query parameter Name | Cardinality | Type | Description |
|---|---|---|---|
| sourceIdentifier | [1..1] | token | The Patient Identifier that will be used to find documents associated with the Patient |
| exp | [0..1] | integer | Optional. Number representing expiration time in Epoch seconds, as a hint to help the SHL Receiving Application determine if this QR is stale. |
| 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 SHLink. |
| 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. |
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:
The VHL Sharer generates a QR code containing the VHL. The QR code is encoded as an HCERT/CWT structure per the WHO SMART Trust HCERT specification and contains the SHL payload embedded at claim key 5 within the hcert claim (claim key -260).
The generation process is as follows:
Passcode Handling (if provided)
If the passcode parameter is provided:
flag parameter of the SHL payloadVHL 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
[base]/List?_id=[folder-id]&code=folder&status=current&patient.identifier=[patient-id]&_include=List:item
[base]/List?_id=[folder-id]&code=folder&status=current&patient.identifier=[patient-id]
| Note: The manifest URL includes all mandatory FHIR search parameters (_id, code, status) and the patient identifier via FHIR chained search on the patient parameter (patient.identifier=system | value). It optionally includes _include=List:item if 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)exp: (optional) expiration time in Epoch secondsflag: (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 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: SHL Payload JSON (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)
After constructing the SHL payload (steps 1-4 above), the VHL Sharer SHALL encode it within an HCERT structure as per the WHO SMART TRUST specification. The HCERT claim SHALL be 5 for VHL.
The VHL Sharer shall than generate the QR Code as 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
Manifest URL Construction Notes:
The manifest URL constructed in step 3 MUST include all mandatory FHIR search parameters required by ITI-YY5:
_id: The unique folder ID (required)code: The List type, typically "folder" (required)status: The List status, typically "current" (required)patient.identifier: The patient identifier using FHIR chained search on the patient reference parameter, in system |
value format (required) |
_include=List:item: Include DocumentReferences (optional - only if VHL Sharer supports Include DocumentReference Option)The VHL Receiver will use this exact manifest URL when performing the ITI-YY5 Retrieve Manifest transaction, adding the SHL manifest parameters (recipient, passcode, embeddedLengthMax) separately in Part 2 of the multipart request.
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 a single output parameter:
| Parameter | Type | Cardinality | Description |
|---|---|---|---|
| qrcode | Binary | [1..1] | QR code image containing HCERT-encoded VHL |
QR Code Output:
HC1: prefixThe 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 SHL payload:
fhirBaseUrl value MUST 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 MUST NOT be present if the VHL Sharer does not support the OAuth with SSRAA Option, to avoid misleading s into attempting UDAP Discovery unnecessarily