Stream: implementers
Topic: Client signatures in the Provenance resource
Christopher Gentle (Jun 16 2019 at 08:28):
I have a neophyte question about the Provenance resource.
I'm looking at ways to use Provenance to allow a FHIR client to record a signature that asserts the both client's identity and provides non-repudiation for a resource's content. I'm wondering if there is a recommended implementation pattern for clients signing resources that I'm missing, or if I misunderstand the protocol.
My assumption is that a resource's signature can't be generated until the server has assigned an ID for a new resource, and a Provenance resource can't be generated until the version of the new resource is known. These two pieces of information aren't known to a client until the resource has been POSTed, PUT or PATCHed. I infer from this that the client can't generate a signature for the resource until the server returns its copy of of the persisted resource. The bundle and Provenance HTTP header methods described in the documentation seem to support Server-side Provenance completion, but not client-side.
The flow I envisage implementing to allow a client to provide a client signature in the Provenance resource isn't atomic. In my implementation design the FHIR client POST/PUT/PATCHes the resource and if the client finds the generated resource is the same (modulo the server-generated ID) then it signs a canonical form of the server's FHIR, adds that to a Provenance resource and POSTs it to the server.
I'm wondering if there is a better/more atomic way to client-sign resources.
Thanks for your consideration.
Grahame Grieve (Jun 16 2019 at 10:49):
I can't think of a better way directly. OTOH the question is ask is, in practice, systems have to fiddle with content all the time - what are you signing, and why? what kind of trust are you trying to prove? What does the client signing it gain that the server doesn't?
Christopher Gentle (Jun 16 2019 at 21:46):
Thanks Grahame.
My requirements are to ensure that all modifications to server data have a provable link to the actor that provided or changed the data. I want to be able to verify the provenance of any resource changes out to the "FHIR edge" which would be an ecosystem of FHIR HTTP clients - apps, applications, non-FHIR EDC gateways etc. required to provide compliant Provenance. This is mostly going to be the resources supporting QuestionnaireResponses.
Put another way, I _want_ to be able to assert that my on my FHIR server, any version of any resource stored is accompanied by a Provenance resource with identity and non-repudiation, and if it doesn't that represents possible evidence of tampering or corruption and a target for audit.
I suspect that not all protocol stage change semantics are going to be client-attributable, but I can probably colour in the server-side changes with AuditEvents.
Grahame Grieve (Jun 16 2019 at 22:03):
do you use OAuth to log the user in?
Grahame Grieve (Jun 16 2019 at 22:04):
if you do, then do you trust that? if no, how can you trust any provenance? if yes, why does the client need to sign?
Christopher Gentle (Jun 17 2019 at 06:23):
We will use OAuth2/OIDC, but I think there is value in storing enough information to make resources tamper-evident. The threat I'm interested in mitigating is internal. While I don't think this kind of defense in depth is going to be required in many implementations, I'd like to be able to verify provenance and integrity after the resources are persisted.
I guess the server could sign and garnish the Provenance resource, but is there a mechanism for delegating resource signing to the FHIR server in the standard?
Grahame Grieve (Jun 17 2019 at 06:36):
well, for that use case, I'd sign the AuditEvents, or if I was really facing serious insider threats, I'd keep the auditevents in a block chain (that's the only actual use case for blockchain I know of in healthcare, and there's at least one in production)
Grahame Grieve (Jun 17 2019 at 06:37):
that still leaves open that a truly gifted insider can tamper with the content as it is submitted, but if I was really worried about someone with that good an access, I'd store my own log on the client and sign that for forensic purposes
John Moehrke (Jun 17 2019 at 16:51):
Grahame has covered the bases. Yes the most basic model for a signature is that you submit a Provenance with a .signature AFTER the server has done their fixup. You could submit a Provenance at the time of submitting the CREATE, but any signature you have in that Provenance would be broken by the server fixup. You might want this, you might find that this zeroth Provenance is unnecessary. (See X-Provenance mechanism for how to submit a Provenance body with POST of a ~Resource~. http://build.fhir.org/provenance.html#header So your Provenance with non-repudiation signature would be as you describe the one created after the server fixup. Which is likely a proper inspection by the client of the server fixup, as the client likely should confirm each fixup is the one intended.
John Moehrke (Jun 17 2019 at 16:54):
The blockchain as external Provenance/AuditEvent repository is indeed intreguing, but much of the same functionality one gets from this architecture can be done with simply a normal FHIR Server that has Create/Read (no update) governance that the memberships trust. (Same is true of blockchain, but is usually wrapped in the use of the word "blockchain") -- but fun anyhow https://healthcaresecprivacy.blogspot.com/2019/03/blockchain-provenance-service.html
Grahame Grieve (Jun 17 2019 at 17:49):
a normal FHIR Server that has Create/Read (no update) governance that the memberships trust
Which is the rub. Blockchain is good where you don't even have that because you don't trust the insider. And given that the there is pretty good documented evidence (and also my personal experience) that one of the most likely attacks on a system is against the audit trail by a highly trusted insider... it isn't stupid. (it is very costly to protect against though)
John Moehrke (Jun 17 2019 at 19:44):
well, there are ways to have private blockchains that do support update... that was my point. The requirement must be said, and should not be assumed just because someone said the technology was blockchain technology.
Christopher Gentle (Jun 17 2019 at 20:17):
I had been wondering if there was a way of tagging the portions of a resource that are invariant during a server update so that invariants alone can be signed? Maybe an extension of the canonicalization rules for facilitating signing with the X-Provenance header?
Grahame Grieve (Jun 17 2019 at 21:32):
maybe. but we're definitely into custom extensions there, I think
Christopher Gentle (Jun 17 2019 at 23:01):
Just a thought. I want to keep my implementation firmly inside the standard.
John Moehrke (Jun 19 2019 at 16:39):
Look at the signature details in FHIR there are some defined http://build.fhir.org/xml.html#canonical
John Moehrke (Jun 19 2019 at 16:41):
http://build.fhir.org/signatures.html
Grahame Grieve (Jun 19 2019 at 22:10):
right but not more flexible ones like desired here
Hendrik Jablonski (Mar 17 2020 at 16:33):
Hi there, I am new to FHIR and try to figure out, where to put the canonization-Method e.g. http://hl7.org/fhir/canonicalization/xml#static into a signature-object or like bundle-header? Can you give me a hint?
Lloyd McKenzie (Mar 17 2020 at 19:52):
It should be in the signature object
Hendrik Jablonski (Mar 18 2020 at 07:45):
Hey Lloyd, thanks for the quick response. I searched for a field in the Signature object, but Signature.type and Signature.targetFormat sigFormat are used for other purposes. Or would you suggest an Extension in the Signature object.
John Moehrke (Mar 18 2020 at 12:32):
The canonicalization method used in the signature algorithm is put into the blob that is produced by the digital signature standard (XML-Signature, JWT, etc). We did not duplicate this standard method. It is required within those digital signature standards, and is critical to processing a digital signature. There is not much use to duplicating this in the FHIR Signature datatype. It is very important to leverage the digital signature standard when validating a signature, as those standards cover integrity of the parameters of the digital signature algorithm.
We did expose the mime-types so that ( a ) you would know the format of the digital signature blob, and ( b ) you would know the mime-type of the object 'this' signature signed (FHIR json, vs FHIR xml).
Hendrik Jablonski (Mar 18 2020 at 15:01):
Excellent answer, thiss helped a lot. In XMl-DSig we have the Signature.SignedInfo.CanonicalizationMethod. In an other article I found the following statement: "In this way, the JWS specification creators eliminated the need for canonicalization, but they introduced a discrepancy in the intuitive definition of equality of JSON objects between the JSON spec and the JWS spec."
That may be the reason why the RFC for JWS does not care about the canonicalization.
And for our project we use a CAdES-Signature and I havnt found anything about canonicalization in ASN.1 PKCS#7-samples.
I see the point of naming the canonicalization method in FHIR. So, maybe we start with an Extension to the Signature definition to name and transport the canonicalization method?
John Moehrke (Mar 18 2020 at 15:21):
I am not understanding why? Or are you speaking of needing canonicalization method only for JWS?
John Moehrke (Mar 18 2020 at 15:22):
There is much unknown with JSON based signatures... XML-Signature is more mature and more accepted
John Moehrke (Mar 18 2020 at 15:22):
@Luis Maas @Julie Maas ?
John Moehrke (Mar 18 2020 at 15:23):
The Signature is under-construction, so any recommendations for improvement are welcome. This is my datatype to manage in the security wg.
Hendrik Jablonski (Mar 18 2020 at 15:26):
Well, we receive a FHIR-XML-Bundle, that needs to get signed. We want to name the canonicalization method #static, to remove the narrative and meta-field before signing. The result (PKCS#7 base64-encoded) will be transported with the bundle in the signature node.
The client that is validating the signature needs to canonicalize in the same way. We can write down several requirements into our specification but we'd rather use a standard way to transport the chosen canonicalization method to be more flexible in the future.
Hendrik Jablonski (Mar 18 2020 at 15:27):
unfortunately we cannot use XML signature because of legacy issues and in a future useCase we want to use JSON signature that is more commonly used on mobile devices.
John Moehrke (Mar 18 2020 at 15:30):
okay, so you do have json signature requirement... I have added Loui and Julie; they are much more of expert on this
Hendrik Jablonski (Mar 18 2020 at 15:54):
"so you do have json signature requirement"
yes!
We get a FHIR-XML-Bundle that is signed with CAdES and we create a copy in FHIR-JSON-format and we want to sign this JSON-Bundle in a way that is easy to read on mobile devices.
Luis Maas (Mar 18 2020 at 18:08):
Several themes in this thread...
- Yes, there are a few open issues with JSON canonicalization, e.g. around decimals: 0.00010 or 1.0E-04 or 0.10e-3 are equivalent and generally once stored the original representation would not be known when a system is generating the canonicalized form for validation against a previous signature. This could be addressed by adding a new rule for decimals to the canonicalization rules. There are other potential issues around the use of escaped characters in strings or element names.
- Some JSONistas may conclude that canonicalization methods are not relevant to validating a JWS because the signed data is commonly included in the payload portion of the JWS. However, FHIR uses detached signatures (for good reasons), where the payload section is removed from the JWS after the signature is generated, thus the canonicalization information is needed to properly reconstruct the payload in order to validate the signature.
- Although canonicalization method is a defined element in XML digital signatures, it is NOT currently a defined JWS JOSE Header parameter (because the base JWS spec doesn't use canonicalization). So, there is no standardized way to include canonicalization information in the Signature.data blob for JSON signatures. We will need to define an appropriate JOSE header extension parameter to use with JWS for FHIR to express this, or alternatively add a new element to Signature to hold the canonicalization method information.
- The FHIR spec isn't clear as to whether regular serialization or compact serialization should be used for JWS. This implies (to me) that either is allowed. In fact, regular serialization would generally be smaller than compact serialization for this use case (ironically) because of the double Base64-encoding that would be involved.
- Agree with @Grahame Grieve re: the OP's approach of validating the resource as stored and then providing a signature. Unclear what happens if the client declines to submit a Provenance resource with a signature on the data as stored.
- Key management is out of scope for the FHIR spec, but critical to the trust of any signature. If the "system" is managing the individual signer's keys used to generate signatures, it can be subject to similar trusted insider risks.
Hendrik Jablonski (Mar 19 2020 at 14:25):
We came to the following solution:
- we define an extension to the signed element, so we add the canonicalization method to the bundle, maybe as meta-attribute or near the identifiers
- when signed this information is also signed and integrity safe against some canonicalization-attacks
Last updated: Apr 12 2022 at 19:14 UTC