Stream: Security and Privacy
Topic: JWS for authenticating FHIR resources
Josh Mandel (Sep 23 2021 at 20:22):
Work in SMART Health Cards has given us some experience creating JWS signatures over FHIR bundles. It'd be nice to have similar capabilities of signing over any resource that a REST API server returns, to make data verifiable when re-sharing downstream. There are some practical challenges though...
https://hackmd.io/1LG5WJfcTnGP8JtYIAAyFA has a brief write-up re: working with JWS in FHIR Signatures. No show-stoppers but it's a bit awkward. Issues include:
- Mandatory fields in the
Signature
datatype (when
,who
) overlap with JWS claims and aren't authenticated; why require non-authenticated elements, when they can get out of sync with the authenticated claims? - Same story for
Provenance.agent
if the only purpose for a Provenance resource is to convey a signature - Data needs to be base64binary, but a JWS is already encoded as a string (base64url segments separated by
.
), so this creates overhead and potential confusion
Have others thought through some of these issues? (I have a proposal for a "cheap hack" alternative at the bottom of the doc ;-))
Eric Haas (Sep 24 2021 at 04:30):
I was just going to ask about this topic... Where is your "Work in SMART Health Cards has given us some experience creating JWS signatures over FHIR bundles" documented.
Eric Haas (Sep 24 2021 at 04:35):
did the same issues you document above apply to bundle.signature...?
John Moehrke (Sep 24 2021 at 13:09):
Josh, I would love to discuss these. Seems these are questions againt the Signature datatype? Or is this questions about how to do JWS signatures over bundles? --- Note I want both.
I will respond expecting these are questions against the Signature datatype.
John Moehrke (Sep 24 2021 at 13:15):
The elements in Signature are NOT expected to be covered by the non-repudiation of the signature. They are there in FHIR format using FHIR datatypes to make them easy to understand. For those use-cases that need to confirm they are valid, it is expected they will be in the signature blob. This is true of XML-Signatures, and as you note they are also inside the JWS content. Thus for someone needing non-repudiation, they should use the values inside the signature blobs.
Note that there is a comment on these elements indicating that "This should agree with the information in the signature."
Note that the comment on the Signature element indicates that "
The elements of the Signature Resource are for ease of access of these elements. For digital signatures (Xml DigSig, JWS), the non-repudiation proof comes from the Signature validation, which includes validation of the referenced objects (e.g. Resources) (a.k.a., Content) in the XML-Signature Detached form."
This should likely be more prominent, as today it is only viewable when hovering over "Signature" or clicking on "Signature"
John Moehrke (Sep 24 2021 at 13:17):
the data element.... Yes, we likely should figure out a better and more friendly way to do this. We didn't have much experience to base our datatype choice, and base64Binary is always going to be safe. But as you point out it is a bit inconvenient.
Grahame Grieve (Sep 24 2021 at 13:27):
@Josh Mandel it seems a bigger problem to me. For a start, where is the JSON canonicalization method?
John Moehrke (Sep 24 2021 at 13:27):
http://build.fhir.org/datatypes.html#JSON ?
Grahame Grieve (Sep 24 2021 at 13:28):
no. http://build.fhir.org/json.html#canonical
Grahame Grieve (Sep 24 2021 at 13:28):
Why do you put the JWS in the resource, and not in an http header?
John Moehrke (Sep 24 2021 at 13:30):
are we discussing the Signature datatype, or the JWS signature method? I think they are both needed, but different.
Grahame Grieve (Sep 24 2021 at 13:31):
well, I want to talk about the JWS itself first, because I want to know why Signature is relevant, and what the purpose of the signature is
Josh Mandel (Sep 24 2021 at 14:09):
Sorry for the shorthand, when I wrote canonicalization I meant specifically https://datatracker.ietf.org/doc/rfc8785/
Josh Mandel (Sep 24 2021 at 14:10):
(this is a scheme with pretty broad library support and of course it is standardized.)
Josh Mandel (Sep 24 2021 at 14:12):
(the signatures could go in a resource or in a header or wherever. A challenge with headers in particular is that we don't have a good way to represent arbitrary headers in a bundle response today, so if I'm getting a bundle of resources back from a batch or a search, I don't have a way to provide specific headers for each one.)
Grahame Grieve (Sep 24 2021 at 15:21):
do you need a signature for each resource in a bundle?
Grahame Grieve (Sep 24 2021 at 15:21):
And you missed the point with canonicalization. The question is what parts of the resource are you signing?
Josh Mandel (Sep 24 2021 at 16:52):
I think it's pretty important for a lot of use cases to be able to mix and match resources; so if I do a search for all labs to pull data into a consumer app, I would like to have individual signatures on them so I can decide to share subsets of labs downstream.
Josh Mandel (Sep 24 2021 at 16:53):
For canonicalization, I don't have firm answers. My initial thought was just to include the full resource contents except for of course the element that contains the signature (whether that's a contained province resource or a tag or whatever -- details TBD). The idea would be if I'm giving you this resource together with a signature, there is some well-specified and not extremely complicated set of steps you can follow to verify the signature.
Josh Mandel (Sep 24 2021 at 16:54):
(of course with fhir graphs, the whole story of signatures across links is very complicated. I'm not trying to do anything on this front right now. This is a place where rdf might shine... But it's a problem I'm trying to avoid for now.)
Eric Haas (Sep 25 2021 at 15:10):
I think what @John Moehrke is / has suggesting it wrap whatever you want in a signature envelope and point to the binary with docref. Instead of the target type. Forget about bundle.sig or provenance or some meta element. I may be misrepresenting him so I welcome his feedback.
Grahame Grieve (Sep 26 2021 at 23:54):
share subsets with signatures
Well, you've got complicated right there. Have you got any references for other protocols doing anything like that?
Josh Mandel (Sep 27 2021 at 00:57):
It's just a set of signed resources -- if you attach signature to each, you allow the recipient to select and re-share whatever subset they like. Of course many protocols do more complicated things (e.g., ISO mobile driver's license signs a set of hashes, so then you can selectively reveal a subset of pre-images).
John Moehrke (Sep 27 2021 at 12:23):
The technology for signing can support anything you want. However each signing methodology has strengths and weaknesses. Eric is referring to the strength of a document signature, that is a signature where the thing being signed is fully self-contained, thus not relying on references to outside stuff. When you have a signature relying on references to outside resources, you have the risk that what you are pointing at is either originally wrong, or in the future wrong. With partial signatures, excluding the signature element from the signature because you need to put the signature blob there later, you leave room for unsigned elements to be inserted. Encapsulating signatures are handy when you know that all uses of the data must validate the signature first, where as detached signatures are more handy when the signatures are only needed occasionally. etc...
John Moehrke (Sep 27 2021 at 12:27):
I look forward to the JWS signature method used in the vaccine credential to be made more broadly usable. I like it for use-cases where all/most uses of the data have business rules need to validate the signature. They should also inspect the signature element for unexpected elements.
John Moehrke (Sep 27 2021 at 12:37):
I think the topic is moving toward signatures that are intentionally sub-sets of the data. Possible, but warning I think this will add risks and complexity that will not be justified by the use-cases. A blind prediction, yes. One based on many years of seeing gleam in geek eyes only to have reality kill the elegant solution due to overwhelming administrative overhead and complexity. (I worked on the project that digitally signed the original USA e-Sign act back in 2000) -- as one can imagine, stopping this with a prediction is neither possible or good. Yes, you can have many signatures in the blob, but they each must be a full signature including the exclusions. each with a who/what/when/why that can standalone.
Eric Haas (Sep 27 2021 at 18:34):
I’m just saying use the Smart vaccine passport model for any FHIR payload as envelope anything that needs to be signed…you want it signed? Fine, here it is but you get it as a docref reference binary where the payload is the FHIR object. I’m no authority but signing something that contains the signature is hard to get my head around.
Lloyd McKenzie (Sep 27 2021 at 18:47):
Signing something that contains the signature is straight-forward. All that matters is that the canonicalization for the signature excludes the signature element. You don't want to turn the data into a binary because that makes it difficult/impossible to use with search. It also locks it into a single syntax, and there are times when you might need to share the content in alternative syntaxes.
Grahame Grieve (Sep 27 2021 at 19:05):
the problem with all this is that if you're signing subsets of data you assembled from elsewhere, then you might have to fiddle the ids for integrity, and the integrity of the links is exactly what you're trying to convey onwards
Grahame Grieve (Sep 27 2021 at 19:05):
signing linked pieces means you must hash the ids.
John Moehrke (Sep 27 2021 at 19:28):
correct. If you are signing individual Resources, you likely need to exclude other things like the .id and .meta.. once you start excluding these things you are getting less and less value out of the signature.
Josh Mandel (Sep 27 2021 at 19:36):
My initial question was about the ergonomics of Signature to convey a JWS over a single Resource version in real-world usage. This might be a non-goal for Signature
Josh Mandel (Sep 27 2021 at 19:40):
I'll probably proceed with prototyping based on JWS in meta.security; will continue to share experience here.
John Moehrke (Sep 27 2021 at 19:41):
anything is possible. There is certainly a theory where all Create/Update will have a calculated signature added to the Provenance for that version. In this case I would expect the signature would cover THAT instance. In that case it does not need to exclude anything.
John Moehrke (Sep 27 2021 at 19:43):
so you are looking to add a signature element as an extension on .meta.security that covers the rest of the resource?
John Moehrke (Sep 27 2021 at 19:43):
I am still not clear on what it is you are trying to achieve. i think I understand how you are achieving it, but I don't know what "it" is that you are accomplishing.
Josh Mandel (Sep 27 2021 at 20:19):
"it" is providing a JWS to authenticate an individual FHIR resource. And yes, I'm looking at one approach which is to provide it in-line, so the approach can work with any method of sharing a FHIR resource (without depending on any specific envelope or package context).
John Moehrke (Sep 27 2021 at 20:20):
as long as it is retrieved in json
John Moehrke (Sep 27 2021 at 20:21):
but what do you think the signature is conveying? if all you want is a hash, that is different than a signature. A signature needs to have a WHO signed it, WHY did they sign it, WHEN did they sign it...etc... all have a purpose. Hence why signature is not just a cryptographic hash, hence why I ask what you are trying to achieve.
John Moehrke (Sep 27 2021 at 20:22):
I fear, you are a kid with a tool, and you want to hit everything you can see with this tool (aka hammer).
John Moehrke (Sep 27 2021 at 20:26):
I am not saying I object to a signature being in the header of every resource. But I am unclear on why it should be there, who would put it there, when would it be put there, who is expected to validate it, what should be allowed to change without breaking the signature... etc... all things that a use-case analysis would define.
Josh Mandel (Sep 27 2021 at 20:27):
Thanks :-) I want to convey information according to the JWT data model -- minimally the ability for a consuming application to pass along a non-repudiable authenticated resource such that a receiving party knows that it hasn't been altered since the intermediary received it.
John Moehrke (Sep 27 2021 at 20:27):
note if you had this use-case analysis, it would be good to assess this on a general Proveance use... then, I think you are just looking for contained Provenance with signature.
Josh Mandel (Sep 27 2021 at 20:27):
Not saying this is "in every resource" -- just saying that it's a common need and convenient to have an approach for.
Josh Mandel (Sep 27 2021 at 20:28):
I tried the contained Provenance with signature; that's what the majority of my write-up was focused on.
John Moehrke (Sep 27 2021 at 20:28):
well, this broad set of use-cases are why Provenance.signature exists
Josh Mandel (Sep 27 2021 at 20:29):
I was concerned with the ergonomics and the risk of conveying unauthenticated copies of signature metadata that are already in the JWS (it creates an opportunity for confusion if the values inside and outside are discordant).
John Moehrke (Sep 27 2021 at 20:30):
are you refering to the Signature elements?
Josh Mandel (Sep 27 2021 at 20:30):
Correct
John Moehrke (Sep 27 2021 at 20:31):
they (.type, .when, .who, .onBehalfOf) are there for the convienence of the app that understands FHIR... and doesn't want to have to call upon a signature processing system. BUT they are not to be held as trusted, if you need the trustable who/what/where/why, then you must look inside the signature.
John Moehrke (Sep 27 2021 at 20:32):
these elements are useful to apps, especially those that will use a signature service to give a YES/NO on the signature.
Josh Mandel (Sep 27 2021 at 20:32):
I'm just saying I wish they were optional
Josh Mandel (Sep 27 2021 at 20:33):
Because I'd like to be able to profile them out
John Moehrke (Sep 27 2021 at 20:33):
well, put in a CR.
Josh Mandel (Sep 27 2021 at 20:33):
I will; it'll also cover Provenance.agent
John Moehrke (Sep 27 2021 at 20:33):
this is exactly why Signature is STU.
John Moehrke (Sep 27 2021 at 20:34):
how do you have any useful Provenance without an agent?
John Moehrke (Sep 27 2021 at 20:35):
in your CR, please explain. as so far we struggle with any useful Provenance without a "WHO".
John Moehrke (Sep 27 2021 at 20:36):
similarly, a signature without a reason for the signature, a timestamp, and a signer.... without these you just have a checksum
John Moehrke (Sep 27 2021 at 20:37):
remember, some apps still use XML... so forcing them to have json capability just to read your JWS is not helpful.
John Moehrke (Sep 27 2021 at 20:37):
that is why these elements exist in Signature
John Moehrke (Sep 27 2021 at 20:40):
I am not discouraging you, just trying to get the 'persuasive' argument in the CR rather than not.
Josh Mandel (Sep 27 2021 at 20:41):
I'll explain in the CR -- essentially all the semantics are already covered in the JWS including the who.
John Moehrke (Sep 27 2021 at 20:41):
but not if I ask for XML FHIR
John Moehrke (Sep 27 2021 at 20:41):
or CSV FHIR
John Moehrke (Sep 27 2021 at 20:43):
the replication is for the convenience of the preferred mime-type of the requester. JWS is only friendly to those that like json. Those that like JWS can ignore the values in these elements, and go right to the JWS.
Josh Mandel (Sep 27 2021 at 21:20):
The point is that in this scheme, the other properties would be unreliable. It's not a question of what you like or what you don't, but a question of what you can count on as authentic. Absolutely within this kind of scheme there is a design choice that limits scope of usage. But it also provides a simplified developer experience, or at least it should. That's the nature of the trade-off.
Josh Mandel (Sep 28 2021 at 15:39):
Submitted FHIR-34021
Last updated: Apr 12 2022 at 19:14 UTC