FHIR Connectathon

http://www.hl7.tv/fhirco20142.html

Kai has done a neat video of the latest FHIR connectathon. Kinda weird to see yourself on camera though!

FHIR Questionnaires and exchanging information

I had an interesting conversation on the skype ‘Implementers chat’ last week.

Like many others who are attending the FHIR connectathon in a couple of weeks, I’ve been working on scenarios involving  the Questionnaire resource (I’m writing a ‘template designer’ as well as a ‘form renderer’), and it occurred to me that it would be good to be able to share completed Questionnaires with others. I saw a similarity with sharing documents, and so asked the question whether the DocumentReference resource should be extended to permit the discovery and sharing on questionnaires as well.

Lloyd commented that his view was that the Questionnaire should not be a primary means of data exchange – that other resources are intended for that purpose, and that the Questionnaire doesn’t have ‘primacy’ over other resources. Grahame also commented that if you did wish to share a completed Questionnaire, then do so as you would any other resource.

That got me thinking.

A few years ago in New Zealand we developed a standard called the ‘Forms Server’ standard. The basic idea was that we would have a standardized way of representing a form template that could be shared between those needing to complete a form, and those needing the structured data within the completed form. A good example of this (and the one we were working with at the time) was a referral: in most cases when referring a patient to a specialist, there is data that is specific to that specialty that needs to be collected – a referral to a cardiologist will have different elements than one to a dermatologist.

We envisaged a central server that held these templates, and a standard that described their structure, plus the completion and transmission of the completed form. Potential referral recipients would upload templates containing the information they needed, and people making referrals would select the appropriate template to make the referral with. (We weren’t thinking of service discovery – just the templates and forms, and the manner that they could be shared). There was an associated standard way of getting data from referring systems (in our case primary care system), and another standard way of representing the actual referral, so in summary 3 major components:

  • Template structure and discovery (local standard)
  • Template pre-population (local standard)
  • Referral form and workflow (based on HL7 v2).

In the end, although the standards were implemented, it didn’t go the way we hoped. It was more of an implementation architecture than a standard, and because they were local to New Zealand, they were only ever implemented by one vendor (though the primary care vendors who were creating the referrals hosted the components and made a local pre-population service available), and so the only way of creating and updating templates was through that vendors system – as was the dissemination of the referrals.

We had achieved the goals of a particular project, but not in a way that encouraged other vendors to join the market, nor established any kind of re-use for other purposes.

So, fast forward to FHIR.

With the Questionnaire resource (and the Referral resource that is being worked on at the moment), there are now the pieces need to fulfil our vision in a truly standardized way. (In the following discussion, do remember that the Questionnaire resource fills the purpose of both template and completed form, using the status property to distinguish between them).

Template Structure and discovery is, of course, the Questionnaire resource and the standard FHIR query mechanisms. I think that there need to be a couple of extra fields to support discoverability – so you can categorize Questionnaire templates and search for specific ‘types’ of template. There are some proposals that we’ll discuss in Phoenix, but we can always use extensions if we need to.

Pre-population needs a couple of things. First the template needs a coded way of describing what information is needed, and the ‘filling’ system needs to be able to locate that data within it’s own data stores.

Well, each question in the Questionnaire has a ‘name’ property of type CodeableConcept, so all that’s needed for that is a standardized terminology like SNOMED, and possibly agreement between users about which codes to use – SNOMED is vast, and not that easy to navigate after all. So, a ValueSet containing the common terms (like usual medications, conditions, allergies etc.) to use might make sense.

In fact, the Questionnaire also allows us to use ValueSets to directly define the options for a question.

We might also want to describe the relationship between entries in a Questionnaire, and other FHIR resources or CDA documents to make it easier for implementers to convert between the two.

And the Referral resource is the final piece for this particular use case.

So we can imagine a workflow like this:

  1. The user locates the Questionnaire Template they wish to use
  2. The system downloads the Questionnaire and pre-populates it from the local data store based on the individual question.name entries.
  3. The user enters the remainder of the data described in the Questionnaire.
  4. When complete, the system constructs a Referral resource, and likely a number of other resources (like MedicationStatement, Observation, Condition) which are placed in a bundle and sent to the recipient using any of the described paradigms of exchange.

This workflow (and the implementing systems) is completely generic, and can be re-used in any other scenario where there is some standardized form of data collection and exchange – like routine assessments, progress notes, discharge summaries etc.

It’s important to appreciate that we’re using the Questionnaire as the interface between the user and the local system – not as the unit of exchange between systems, which would use resources specific to each purpose. In this case a Referral resource, but another example could be a Discharge Summary, which is a document. (I’ve glossed over some of the details of this exchange, which actually uses other resources like Order and OrderResponse, and of course there are security /privacy considerations as well.)

In fact, if we were half way clever we’d also re-use any appropriate FHIR server. For example, we’re currently looking at creating a ‘Record Locator Service’ (which could be a FHIR server hosting DocumentReference resources) – why not use the same infrastructure to store the Questionnaire templates?

So I’m starting to think that the Questionnaire could replace the List as my favourite FHIR resource.

Let’s see what happens in Phoenix…

 

 

 

 

FHIR Questionnaire: Connectathon 6

Note that since this post was written, the Questionnaire resource got split in 2 with the Questionnaire being just a template, and the QuestionnaireResponse holding the data. More on that here.

The theme for the next FHIR Connectathon has just been decided by the FHIR Management Group, and this time round we’re going to explore the Questionnaire resource. The reason for choosing this is that there is interest in this resource from a number of significant organizations in the healthcare space, and because it supports one of the core requirements in healthcare – the ability to collect information using a form, and to extract information from that form to populate or update a medical record, while always keeping a ‘copy’ of the form.

It’s important to appreciate that the purpose of the Questionnaire is in the collection of information – not to act as a ‘repository’ of that data for later searching. In other words, if the Questionnaire collects something that needs to be recorded outside of that form – like a Condition – then the correct thing to do is to create a formal Condition resource and store that. Searching for data within the Questionnaire is certainly technically feasible, but is discouraged – the spec doesn’t even define any standard search parameters for this.

It is still possible to refer to a Resource from the Questionnaire  – you might want to do this if sending a completed Questionnaire to someone else  and wish to include the created resources in a bundle – but to do that you must have already extracted the data, created the resource, and then placed a reference to it within the Questionnaire. In some ways, this is like a FHIR Document – where the Questionnaire is analogous to the Composition resource – although the purpose is quite different. And, like a document, you can include all the resources in a bundle and sign it. (We talked about signing in the post on tamper proof auditing)

If you want to be able to record that the resource was created from data in a questionnaire, then the Provenance resource should be used. Provenance.target would refer to the resource, and Provenance.agent would refer to the Questionnaire.

At a high level, there are at 2 ways to use the Questionnaire:

  • As a ‘template’, containing only the questions – and potentially layout. (Template is a really overloaded term unfortunately).
  • As a ‘form instance’, containing the questions and the answers to those questions, or with the answers only (in which you would need to refer to something else to render it).

The Questionnaire.status property is used to distinguish a specific resource – the diagram below shows how this works.

questionnaire workflow

When it comes to using a Questionnaire to create a form, a common workflow might be:

  1. Select a blank Questionnaire from a set established as templates. These would be Questionnaire resources with a code of ‘published’.
  2. Prepopulate the Questionnaire from data sources if available. For example, you might want to include the current medication list or conditions.
  3. Render the Questionnaire as a form for the user to complete
  4. Save the completed Questionnaire as an interim Questionnaire.
  5. Complete the Questionnaire.
  6. Construct any other resources from the Questionnaire, and place a reference to them in the Questionnaire.
  7. Save the Questionnaire resource

To store a Questionnaire, you save the resource in the data store in the same way as any other resource. As described above, there may be other resources that were created on the basis of data entered in the Questionnaire that can be referred to from the Questionnaire.

To display a completed Questionnaire (form) to an end user, the simplest way is to store that rendition in the text property of the resource. In that way, any system with minimal FHIR compliance can retrieve and display it. This also gives the creator of the form control over the display format, which senders often require. Of course, as the resource contains structured data it can be rendered in a different way if required – e.g. on a mobile device. If storage space is an issue, then an alternative is to store the answers only in the Questionnaire – with a minimal text property – and require the consumer to retrieve a display template and render locally. The same applies to the a template: you could include the layout in the text element, or require that the recipient render it.

Well that’s an overview of the Questionnaire resource. In the next post we’ll dig a bit more into its structure, and go over this workflow in more detail.

Tamper resistant auditing in FHIR

Had an interesting chat with a colleague here at Orion (Richard) about audit events and signing them, and how to be sure that they haven’t been tampered with (which is apparently a Meaningful Use requirement) so have made a note here for when I forget, as this is an area that I’m not that familiar with. I should also say that there are doubtless other ways of doing this and real life implementations really need to be done by those who are experts – it’s been said that poor security is worse than no security at all…

FHIR provides a specific resource – the SecurityEvent resource – which records some event of importance. This could be anything from creating, reading, deleting or updating other resources, and can serve as the basis for an audit log to answer questions like ‘who has accessed my record’. The resource is based on the IHE ATNA profile, and indicates ‘who‘ did ‘what’ and ‘when’.

The spec states that a server that stores SecurityEvents should not allow them to be updated or deleted – which makes sense for something related to audit – but for the truly paranoid, how can you know this? How can you know that a SecurityEvent resource has not been deleted or modified?

To answer this question, we need a bit of background on some security terminology.

  • A cryptographic hash is a string (sometimes called a digest) that is generated from a source (like a FHIR resource) using some hash function. SHA-256 is an example. The digest that is generated by the function will always be the same when the input is the same, but it is not possible (or more accurately is unfeasible) to regenerate the original from the digest. So, if you have a digest and the original, then you can be sure that the digest ‘matches’ the original by creating a digest yourself and checking that they are the same – kind of like a fingerprint identifies an individual person.
  • Public Key cryptography is a system where there are 2 ‘keys’ that are linked mathematically. It’s possible to encrypt something (producing a signature) with one of the keys, and then to re-generate the original using the other key (So this is ‘two-way’ – unlike the hash which is ‘one-way’). One of the keys is kept secret (the private key) and the other one is shared (a public key). Assuming that you have my public key, then I can encrypt a message with my private key and send it to you. You can use my public key to decode it – and you know that it came from me. The public key is often called a certificate.
  • Of course, for the above to work, you need to be able to trust that you have got my public key – and not that of someone else. This is where a certificate authority (CA) comes in. This is an organization that we both trust which asserts that a particular key pair (public and private) actually belongs to a given person (or organization / thing). You prove to the CA that you are who you say you are, and the CA signs your public certificate with their own one. So – if you get a message encrypted with my private key, and you have my public key (certificate), then you can check that the CA has validated that certificate, and then use it to decode the message. Provide you trust the Certificate Authority, then all is well. The infrastructure that supports all this is referred to as Public Key Infrastructure – or PKI.

Just a couple more things before we move on:

  • The computations required to sign and decode messages using public & private keys can take a long time to run with large input files. What people commonly do is to take a message, produce a hash from that and then sign the hash.
  • This discussion is all about proving who (or what) created a resource – the integrity of that resource. The actual encryption of the contents is a separate discussion.
  • It can get a lot more complicated than this! This is not a simple area…

So with the basics behind us, how can we be sure that our SecurityEvent resources have not been tampered with? One way is to use a signed Provenance resource that refers to the SecurityEvent. This would be created by the same application that created the SecurityEvent.

A key assumption to make is where do we get the signers public key (certificate) from? There are a number of options for this, and the details will vary for each particular implementation (as far as I am aware there is no intention for FHIR to move into this space).

One possibility is to actually store the certificate in the signature itself! This sounds silly, but the idea is that the certificate is signed by a Certificate Authority. So, if we trust that Authority, then we trust that they assigned it to the right person. We’ll use that for the example below.

This process would go something like this.

  1. The application creates and saves the SecurityEvent resource.
  2. Next, it creates a Provenance resource. The provenance resource will refer back to the SecurityEvent resource (Provenance.target).
  3. Next generate a Hash of the SecurityEvent resource.
  4. Create a signature by encrypting the Hash using the systems private key, and include the public key (certificate) in the signature, which is then saved in the Provenance resource. (Provenance.integritySignature).
  5. Save the Provenance resource.

All of the above steps would need to be executed on the server in a single transaction.

So, with that in place how can I check that a particular resource hasn’t been altered? Well:

  1. Retrieve the SecurityEvent resource I want to check
  2. Generate a Hash of the resource using the same hash function as before.
  3. Retrieve the Provenance resource that refers to that SecurityEvent. (This would be a query against Provenance – /Provenance?target={ SecurityEvent.ID} ). The element Provenance.integritySignature has the signature generated by the system that signed it.
  4. Extract the signers Certificate from the signature, and make sure that the issuing CA (in the Certificate) is one that I trust. (Actually, there can be a whole chain of CA’s – but let’s not go there…)
  5. Using that Certificate, decode the rest of the signature. This will produce the original Hash, which should be the same as the one generated in step 2. If they match, then you can be sure that the SecurityEvent is the same as when it was signed. If not, you have a problem.

So what stops the bad guy from altering the signature in the Provenance? Well, they don’t have the private key of the signing system, so can’t encode the hash in a way that can be decoded by the public key (certificate) of the signing system. If they do put their own certificate in, then the CA to which it refers (and that I trust) tells me it was someone else.

The whole thing depends on being able to keep the private key of the signing system secret, and having certificates – maybe from a CA – that we both trust.

Couple of questions that come to mind.

Why not just sign the SecurityEvent resource and add the signature to it directly? Well, the problem with that is that the signature is ‘signing’ the whole SecurityEvent resource. If the digest is a part of that resource, then you have to generate the digest and then add it to the resource and then… oh wait … we’re just modified the resource and therefore the digest is invalid…

How do you know if a SecurityEvent has been deleted? After all, the bad guy could delete both SecurityEvent and Provenance? One way around this is for each SecurityEvent to refer to the previously created SecurityEvent in a chain (You’d need an extension for this in FHIR). That way you can ‘walk the chain’ to make sure there are none missing – and provided you check each SecurityEvent as you go, you know that the bad guy hasn’t changed any of the links.

Security is a complex topic, and this merely scratches the surface of what is required to implement correctly – it’s a high level overview and not an implementation guide.  To understand more – John Moehrke is one of the acknowledged experts in this space in healthcare.

Decomposing a FHIR document

Scenario 2.3 of Connectathon talks about a server ‘decomposing’ a FHIR document. This is another of those huge topics, as it is all about using the document as a ‘carrier’ for information that is used by a recipient to update their own data stores, rather than simply storing it as a ‘blob’ to be displayed to a user on request.

The issue is not so much a technical one – that’s relatively straightforward (though one of the more complex in FHIR) – but rather relates to the purpose of a document as a ‘summary at a point in time’ – or as a ‘snapshot’, rather than a mechanism to ‘transfer state’.

Read more of this post

Retrieving and rendering a FHIR document

This post is going to be a bit of an anticlimax.

Once we’ve created the FHIR document and saved it via the /mailbox entry point, then we probably want to be able to find it again at some stage (assuming that the reason we saved it was to make it available to others of course). Well, because the server created DocumentReference resources during processing, then we just need to follow the same process that we used when discussing how to retrieve CDA documents using XDS principles – i.e. query the DocumentReference end point, and then get the document using the location property of the individual DocumentReference resource.

Read more of this post

Server processing of FHIR documents: Connectathon

In this post we’re going to think a bit about how the server might process a document that it receives. This is a massive topic, and certainly not one that can be covered in a single post – or by any one individual! Apart from anything else, there are lots of different possibilities – all legitimate in specific circumstances.

This is an important concept for FHIR – it doesn’t seek to drive any particular design or architecture – rather it attempts to support how data is moved around now, and how it may be done the future. It’s up to individual implementations to decide the details, but using common ‘building blocks’.

Read more of this post

Creating a FHIR document for the January Connectathon

I had intended to talk in some detail about the Composition resource next, as this is one of the key resources for a FHIR document, but because the January connectathon is getting close I’m going to do a series of posts to directly support people attending connectathon, and wanting to experiment with the document track. I’m planning 4 posts in this series:

  • How a client would create a FHIR document (incidentally for the remainder of this series, I’m going to refer to a FHIR document just as  ‘document’, so when you see this, I’m NOT talking about CDA. Later posts will talk more about the relationship between the two).
  • How a server could process a document. There are a few possibilities…
  • How to find the document on the server later, and render it to the client.
  • A wrap up on the Composition resource and anything else left over.

I do intend to spend a lot more time on FHIR & CDA, but this should at least cover the basics.
Read more of this post

FHIR Connectathon: Sample data

As part of the planning for the next FHIR connectathon, we want to make better sample data available for participants to build applications against – and, of course, to continue to exercise the specification. For the last event, I wrote an application using one of the open-source clients that has been developed (in this case the c# client by Ewout Kramer of Furore) and suggested that I could enhance that with more data.

It was suggested that I take the data on this page to use as the clinical scenarios.

I was blown away by this for a couple of reasons:

  • First the amount of work that my colleagues have put in to creating it
  • And secondly – just how far FHIR has come in being able to represent real-world clinical data.

If anyone still has lingering doubts about whether FHIR is going to be ‘fit for purpose’, then these scenarios should remove all doubt…

It’s going to be a reasonable amount of work to do properly – especially as we want to use this to test the FHIR document architecture, but should be do-able, and I’ll keep you appraised on progress…

(btw – I stuck a # in front of the FHIR so it shows up as a hashtag in twitter – if anyone knows how to get wordpress to automatically add the # when sending a notification then let me know)….

FHIR Connectathon: The conformance resource for a client

The planning for the 5th FHIR connectathon is underway, with an announcement yesterday on the FHIR list server encouraging people to review the registration site, and to register as soon as the registration is open (which I absolutely encourage you to do). This will be the first connectathon that I won’t be at – which is kind of sad, but had to happen at some point.

Although I’m in the middle of a series of posts on FHIR & XDS (and a bit behind to tell the truth – work has got in the way of the fun stuff), I thought that it might be of interest to discuss some ‘connectathon-related’ topics – starting with the conformance resource. We’ve talked about this before in the context of a server using it to indicate to a potential consumer what it’s capabilities are (and been quite good in actually producing examples in our discussions), but it has also been designed for use by a client to indicates what it requires of a server.

In the case of connectathon, we encourage clients to create a Conformance resource to indicate what they need of a server as they fulfill the scenarios.

The conformance resource itself has some ‘header’ information (eg description, FHIR version and so forth) and then entries for REST, Document and Messaging. We will focus on the REST entry. There are entries that indicate:

  • Whether the conformance resource is describing a client or a server
  • Which resources the server supports or a client requires
  • Which profiles are supported/required
  • Security considerations
  • For each resource:
    • what operations are supported/required – CRUD
    • whether history is supported/required
    • the search parameters supported/required

A client will set the Conformance/rest/mode/@value  value to ‘client’ to indicate that it is specifying a requirement rather than a capability – and the other parts of the resource mean the same thing that they to for a server.

As an example, suppose that I want to complete scenario 1.4 of connectathon (search for a patient on name)  – the following conformance resource would indicate my requirements to a prospective server:


<Conformance xmlns="http://hl7.org/fhir">
     <text>
         <status value="generated"/>
         <div xmlns="http://www.w3.org/1999/xhtml">
             <p>A conformance statement detailing the client requirements for a sever in implementing scenario
             1.4 on connectathon#5 - search for a patient by name. Note that this only for 1.4 - we'd need
             to update if we were supporting any other scenario</p>
         </div>
     </text>
     <identifier value="68D043B5-9ECF-4559-A57A-396E0D452311"/>
     <version value="20130510"/>
     <name value="Connectathon Conformance requirements"/>
     <publisher value="HayCorp"/>
     <telecom>
         <system value="email"/>
         <value value="user@haycorp.com"/>
     </telecom>
     <description value="This is the FHIR conformance statement for the haycorp team at connectathon #5"/>
     <date value="2013-11-12"/>
     <software>
         <name value="HC-Client"/>
         <version value=".01"/>
     </software>
     <fhirVersion value="0.12-1911"/>

     <!--   doesn't really apply for a client, but is required   -->
     <acceptUnknown value="false"/>

     <!--   we only do XML -->
     <format value="xml"/>

     <rest>
         <mode value="client"/>
         <resource>
             <type value="Patient"/>
             <operation>
                 <code value="read"/>
             </operation>
             <searchParam>
                 <name value='name'/>
                 <type value="string"/>
                 <documentation value="Search by patient name"/>
             </searchParam>
         </resource>
         <operation>
             <code value="search-system"/>
         </operation>
     </rest>

 </Conformance>

A couple of notes:

  • The conformance resource is not – necessarily – used for machine processing, but rather as a uniform way that servers and clients can indicate and match capability & requirements. For example, they are very useful in the planning stages of a project when clients and servers are being located and/or designed.
  • As a FHIR resource, a conformance statement can be stored in a FHIR server, and has the same versioning capabilities as any other FHIR resource. This makes an excellent choice for locatable documentation once the systems are in operation.
  • And its resource nature also supports the concept of a searchable registry. This is more applicable to a server than a client, but does support the idea of providing UDDI like functionality…