April26#38
Conversation
Introduces a third authentication option for the Retrieve Manifest transaction alongside HTTP Message Signatures and OAuth with SSRAA. The VHL Receiver self-issues an LDP-VC (W3C VC Data Model v2) whose credentialSubject is the manifest decoded from the QR code, with an embedded DataIntegrityProof signed using the receiver's key from the trust network. The signed VC is sent as the POST body with Content-Type application/vc+ld+json, and FHIR search parameters are carried in the URL query string. Closes ToDo_006. - ITI-YY5.md: new section 2:3.YY5.4.1.5, updated scope, referenced standards, expected actions, and security considerations - volume-1.md: added option to actor options table and new XX.2.5 section describing the mechanism - ITI-YY5.plantuml: sequence diagram now shows three-way alt for the authentication options - testplan.md: added LDP-VC construction, proof verification, and rejection test cases; fixed FAST -> SSRAA typo - issues.md: moved ToDo_006 to Closed with resolution - usecases.fsh: referenced VC Option in Hajj and EUVAC use cases Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
||
| #### 2:3.YY3.4.3 VC Envelope Option | ||
|
|
||
| VHL Sharers MAY support the **VC Envelope Option**, in which the VHL payload is returned as a signed W3C Verifiable Credential instead of a QR code. This is selected at request time via `format=vc` and returned in the `verifiableCredential` output parameter. It is an alternative carrier for the same VHL payload — the manifest URL, decryption key, flags, label, expiration, and optional extension are identical to those otherwise embedded at HCERT claim key 5. |
|
https://build.fhir.org/ig/IHE/ITI.VHL/branches/April26/index.html The title for this page appears to be "ToDo": I am not sure which of these this might come from: Line 70 in 35ed355 Line 4348 in 35ed355 |
| * max = "1" | ||
| * type = #Identifier | ||
| * documentation = "An identifier for the patient. Required if 'bundle' is not provided." | ||
| * type = #string |
There was a problem hiding this comment.
@a-mahr updated searchType and type parameters, also for other types like integer -> number
There was a problem hiding this comment.
In generate-vhl, exp is an integer, but in YY3, it is a number. Could we write this in the same style as we did sourceIdentifier? d
| - Mutual authentication is required for all document retrieval operations. | ||
|
|
||
| ### XX.5.3 VHL Integrity and Authorization | ||
| ### XX.5.3 Cryptographic Algorithm Selection |
There was a problem hiding this comment.
@a-mahr central language about Algorithm
| **Table 2:3.YY3.4.1.2-1: $generate-vhl Message HTTP query Parameters** | ||
|
|
||
| | Query parameter Name | Cardinality | Type | Description | | ||
| | Query parameter Name | Cardinality | Search Type | Description | |
|
@oliveregger the QA errors seem to be from an out of date IHE FHIR Template. I chatted with @costateixeira and it seems updating the FHIR template should solve the 100 + duplicate TOC errors |
|
@ritikarawlani yes the templates need to be updated, i check with @costateixeira |
There was a problem hiding this comment.
@oliveregger this update removed the 100+ QA errors
There was a problem hiding this comment.
@oliveregger we seem to have 10 warnings that I can't take away right now. Are 10 warnings okay? or shall I suppress it?
They are because of the use of TestPlan and ActorDefinition resources that are R5 and the publisher isn't working well with them.
| * type = #CodeableConcept | ||
| * binding.strength = #extensible | ||
| * binding.valueSet = "http://terminology.hl7.org/ValueSet/v3-PurposeOfUse" | ||
| * documentation = "Optional. Purpose(s) of use the VHL Holder is authorizing for this share (e.g., TREAT, HPAYMT, HRESCH). The VHL Sharer SHALL persist these value(s) against the generated folder ID. When the VHL Sharer is grouped with an IHE PCF Consent Creator or Consent Recipient, these values SHALL populate Consent.provision.purpose on any Consent created for or bound to this folder. At ITI-YY5 the VHL Sharer MAY use the recorded purpose to enforce consistency with the VHL Receiver's declared purpose claim (e.g., the OAuth access token's purposeOfUse claim, the UDAP sub_purpose extension, or an equivalent claim carried in a Verifiable Credential)." |
There was a problem hiding this comment.
I am not sure where sub_purpose is coming from.
In SSRAA, this is purpose_of_use in the hl7-b2b extension: https://build.fhir.org/ig/HL7/fhir-udap-security-ig/b2b.html#b2b-authorization-extension-object
In UDAP, this is an example extension key of purpose_of_use.
Propose: "the SSRAA hl7-b2b extension"
There was a problem hiding this comment.
Thank you so much! nice catch. Fixed
| * use = #in | ||
| * min = 0 | ||
| * max = "*" | ||
| * type = #CodeableConcept |
There was a problem hiding this comment.
This is not serializable in a GET request. This should have the same change made as sourceIdentifier did.
There was a problem hiding this comment.
@a-mahr in refernce to the comment below about exp as an integer..
if you see here https://hl7.org/fhir/R4/operationdefinition.html, then the fhir type allows for all FHIR data types, but a searchType can be only used if type=string. I don't understand it fully but it seems like the same pattern for sourceIdentifier wont do here.
I could change the type to number though.
There was a problem hiding this comment.
I'm not sure I'm following, but the way it currently looks makes sense to me
| * max = "1" | ||
| * type = #Identifier | ||
| * documentation = "An identifier for the patient. Required if 'bundle' is not provided." | ||
| * type = #string |
There was a problem hiding this comment.
In generate-vhl, exp is an integer, but in YY3, it is a number. Could we write this in the same style as we did sourceIdentifier? d
| * max = "1" | ||
| * type = #integer | ||
| * documentation = "Optional. Number representing expiration time in Epoch seconds, as a hint to help the SHL Receiving Application determine if this QR is stale." | ||
| * documentation = "Optional. Number representing expiration time in Epoch seconds, as a hint to help the VHL Receiver determine if this QR is stale." |
There was a problem hiding this comment.
There is no YY3 expectation for the VHL Sharer to evaluate the exp parameter.
In YY3, including exp in the payload is optional, and seems entirely up to the Sharer.
So, the exp in $generate-vhl is a hint to the Sharer to request a particular expiration.
The exp in the resulting payload is the actual hint to the receiver to indicate that a VHL may be expired, and it may or may not be the same as the requested exp, based on Sharer policy.
There was a problem hiding this comment.
i have updated the type to be positiveInt both in the operationDefn and the ITI-YY3. I moved the hint statement to be what the VHL SHarer sets in the payload and removed it from the operationdefn
GET should serliaize and FHIR primitive data type so i imagine positiveInt will do. @a-mahr
| 2. Persist the value(s) against the generated folder ID so that they remain discoverable for downstream enforcement at ITI-YY5. | ||
| 3. When grouped with an IHE PCF [Consent Creator](https://profiles.ihe.net/ITI/PCF/) or [Consent Recipient](https://profiles.ihe.net/ITI/PCF/), populate `Consent.provision.purpose` on any Consent created for or bound to this folder from the persisted value(s). | ||
|
|
||
| At [ITI-YY5](ITI-YY5.html) the {{ linkvhls }} MAY use the recorded purpose to enforce consistency with the {{ linkvhlr }}'s declared purpose claim — for example, the `purposeOfUse` claim of an OAuth access token under the OAuth with SSRAA Option, the `sub_purpose` extension of a UDAP assertion, or an equivalent claim carried in a Verifiable Credential under the Verifiable Credential Option. Inconsistent purposes MAY be rejected with HTTP `403 Forbidden`. |
There was a problem hiding this comment.
This has the same issue as in the $generate-vhl OperationDefinition, sub_purpose is not a claim I have heard used with SSRAA.
There was a problem hiding this comment.
I am also noticing that SSRAA and UDAP are described as distinct options, but SSRAA is the UDAP IG specific to healthcare.
| | Parameter | Type | Cardinality | Description | | ||
| |-----------|------|-------------|-------------| | ||
| | qrcode | Binary | [1..1] | QR code image containing HCERT-encoded VHL | | ||
| | qrcode | Binary | [0..1] | QR code image containing HCERT-encoded VHL. Populated when `format=qrcode` (default). | |
There was a problem hiding this comment.
Since format is an optional parameter in $generate-vhl, can we reword as
"Populated when format=qrcode or when format is absent, as the default format."
| - `_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 Receiver will use this exact manifest URL when performing the ITI-YY5 Retrieve Manifest transaction, adding the SHL-defined manifest parameters (`recipient`, `passcode`, `embeddedLengthMax` — per the [SMART Health Links specification](http://hl7.org/fhir/uv/smart-health-cards-and-links/links-specification.html)) separately in Part 2 of the multipart request. |
There was a problem hiding this comment.
Is it worthwhile to link to YY5 where the multipart request is described?
I had to figure out where the multipart request this is referring to was
There was a problem hiding this comment.
@a-mahr this led me to restructing many parts across YY3, YY4 and YY5. we are not doing multipart requests, and I have now restructured a lot of content. could you kindly re - review please?
There was a problem hiding this comment.
ITI-YY1 and ITI-YY2 are optional for Sharers and Receivers, and so this should not be a SHALL.
| ##### 2:3.YY4.4.1.3 Expected Actions - VHL Holder | ||
|
|
||
| The VHL Holder SHALL: | ||
| 1. Verify QR code validity (not expired, CWT signature valid) |
There was a problem hiding this comment.
I think this should be generalized for the VC option (verifying a VC signature)
There was a problem hiding this comment.
fixed made updates
| | label | [0..1] | string | Optional. String no longer than 80 characters that provides a short description of the data behind the SHLink. | | ||
| | 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](http://terminology.hl7.org/ValueSet/v3-PurposeOfUse) (e.g., `TREAT`, `HPAYMT`, `HRESCH`). Serialized as FHIR `system\|code`. See [Purpose of Use Handling](#purpose-of-use-handling). | |
There was a problem hiding this comment.
I think this should be "system|code", it is serializing as "system\|code" rather than properly escaping. The one on line 86 looks correct in the rendered view.
|
|
||
| ###### 2:3.YY3.4.1.2.1 Output Carrier Options | ||
|
|
||
| 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](#23yy3422--message-semantics)) SHALL be populated. |
There was a problem hiding this comment.
Is the SHALL conditional? Does it need to be populated if the response is only an OperationOutcome?
|
I am comparing 1cf9152 and 748416e and noticing that YY3, around line 231, had "Manifest URL Construction Notes" removed. These notes made parameters like _id required. Now, it appears that the URL is completely up to the VHL Sharer, with the exception of the requirement to include the sourceIdentifier. Previously, code, status, and _id were required fields in the URL, and YY5 still requires their presence. |
| ``` | ||
|
|
||
| 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. | ||
| 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](https://profiles.ihe.net/ITI/MHD/ITI-66.html) 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 {{ linkvhls }} supports the Include DocumentReference Option. |
There was a problem hiding this comment.
@a-mahr manifest url notes is coalesced here instead of being separate, and clearly demarcates those are required because ITI-66 marks them as such and we're delegating to ITI-66 here
There was a problem hiding this comment.
Does the current state make clear that those parameters need to always be included when generating a manifest URL?
At the ITI-66 reference, I see this "The Document Consumer shall include search parameter patient or patient.identifier, code, and status. The other parameters described below are optional.", which makes it sound like _id is not required if we don't create a requirement for it.
One option could be to link to https://build.fhir.org/ig/IHE/ITI.VHL/branches/April26/ITI-YY5.html#23yy5412-message-semantics as a reference for required cardinality of parameters.
| - Obtain access token using JWT client assertion | ||
| - Include token in Authorization header | ||
| - Reuse token for subsequent requests until expiration | ||
| - **One-time per VHL Sharer:** if not already registered with this {{ linkvhls }}, perform UDAP Discovery (SSRAA §2) using the FHIR Base URL from the VHL payload and Dynamic Client Registration (SSRAA §3) to obtain a client ID. Cache the registration per FHIR Base URL. |
There was a problem hiding this comment.
This is actually a not-so-obvious requirement for SSRAA: In SSRAA Discovery, it states that
FHIR servers with the same registration_endpoint URL belong to the same logical group. A registration for any FHIR server in this logical group registers the client application for all endpoints in that group.
That means that registrations should be cached per Registration Server rather than FHIR Server. I think the detail can be updated or omitted.
Closes #
📑 Description
✅ Checks
ℹ Additional Information