Using FHIR Search _filter to Express and Enforce Redaction Obligations

(also posted here).

Summary: FHIR search _fitler provides a powerful mechanism for imposing additional restrictions on a query, and therefore, is a reliable mechanism for implementing a redaction service. Moreover, search filter defines a flexible language for encoding query restrictions which can be directly leveraged in encoding redaction obligations in policies, e.g. patient consents. Such expressions can also be encoded as OAuth 2.0 scopes, so that the authorization server can directly tell the FHIR server to run a client’s queries through specific filters. Overall, search filter expressions seem to provide a suitable mechanism for both expressing and enforcing redaction obligations.

The Case for Redaction

The main function of an authorization service is to ensure that a client has the rights to receive the information it requests. In the simplest case, this is a binary decision, and the result is either to permit the client to receive the information or to deny access.

A binary decision, however, is not desirable in many cases both from a privacy and usability perspective. For example, consider the case that Alice, a patient, has a consent that grants a client access to all of her non-restricted immunization records and assume that she has one restricted immunization which must not be shared with this client. When this client requests Alice’s immunization records, a binary decision by the FHIR server to flatly deny this request can lead to the risk of inference that Alice must have some restricted immunizations that caused the denial. Furthermore, if the client is not fully aware of the details of its access rights based on various applicable policies including Alice’s consent, it has to potentially go through a lengthy back and forth with the server and refine the query until it can receive the information. This can be frustrating and potentially impossible without sufficient clues about what may have caused the denial. Note that, should the client be successful in this process, the eventual refined query is inherently revealing of the authorization policies including Alice’s consent.

Thus, the more desirable behaviour for the server is often to alter the results of the client’s query to remove the portions of the response which the client is not authorized to access, and ultimately permit the client’s access to a more limited view of the requested data. In the above example, the FHIR server responds successfully with a bundle of all Alice’s immunizations except the restricted one, i.e. the restricted immunization resource will be redacted.

Note that redaction most commonly applies to the case where the response contains a collection of resources, such as a bundle resulting from a search or a compartment query. When a client requests a specific resource by its direct URL, redaction essentially boils down to sending either a Not Found or Unauthorized response, depending on the use-case and the privacy risks involved.

Initial Implementation

Redaction requirements are usually modelled as obligations in the authorization decisions returned from the authorization service. After examining the policies, the authorization server returns any requirements for redaction as an obligation alongside the decision to permit access.

After receiving the authorization decision from the authorization service, the FHIR server calls the redaction service. The client’s request, the raw outgoing response, and the redaction obligations determined by the authorization service are passed on to the redaction service. The redaction service applies the necessary redactions and returns a modified version of the initial outgoing response which the FHIR server eventually sends to the client.

A common approach to implementing the redaction service is to implement it as a post-processing service inside the FHIR server which examines the outgoing response and makes the necessary changes based on the obligations invoked by the authorization service. Such post-processing services are common in server applications and have many other applications such as response-based logging and authorization. For some examples, see the Interceptor package in HAPI FHIR.

Issues and Considerations

Inspecting the outgoing response from the server requires the redaction service to be tightly coupled to the FHIR server. This makes it very difficult to implement this as a service orthogonal to and independent from the FHIR server.

In Pauldron Hearth, I have tried to separate the authorization service, including the enforcement of redaction obligations (a future feature), from the FHIR server, using an HTTP reverse proxy with the goal of having this service completely uncoupled from the backend FHIR server. My initial impulse was to follow the above approach for implementing redaction by having a redaction module which inspects the outgoing response and modifies it as necessary. I realized, however, there are a lot of nuanced issues such as the bundle size, links to a redacted resource from other (unredacted) resources or inline resources.

Another important case raised by Brian Postlethwaite on FHIR chat is the case of paginated response where a naive redaction of individual resources can potentially lead to sending some empty pages to the client which could reveal to the client that some sensitive information had existed in the response. The empty page may sound like an edge case but even when there are no empty pages, since the page size is usually fixed in pagination, a page shorter than the normal page size can also be indicative of a redaction. Handling such cases requires either close interaction with the internal state of the FHIR server which means the redaction service cannot be separated from the FHIR server, or repaginating the response inside the redaction service which requires buffering a potentially large volume of data and re-implementing the pagination logic which is not ideal.

Using Search Filters

FHIR Search _fitler provides a powerful language to express filtering restrictions to narrow down the results of a broad query. FHIR already supports search queries based on security labels, and the search filter language provides the flexible tools for combining and composing such queries. For example, the obligation to redact restricted resources can directly be translated into a search filter such as “not _security eq R”.

In this model, the redaction service intervenes when there is an incoming request from a client. The redaction obligations are determined after communicating with the authorization service. The redaction service, then, rewrites the client’s query by adding necessary search filters (or AND-ing it to the existing filters if the query already includes search filters). The FHIR server’s own search filter capabilities is leveraged to provide a reliable redaction service which will automatically handle issues like pagination.

Since HAPI does not seem to support search filters at the time of writing, I have not had a chance to test or implement this in Pauldron yet, but it certainly seems that the search filter language is sufficiently expressive to support all the existing redaction use-cases of which I am aware.

Filters in OAuth Scopes and FHIR Consent

The concept of search filter as a mechanism to narrow down the view of the data has a close semantic proximity to the concept of scopes in OAuth 2.0. Thus, it is possible for an OAuth 2.0 authorization server to specify the extent to which access has been granted by directly encoding search filter expressions as granted scopes.

As an even further step, search filter expressions can also be used in the authorization policies, particularly patient consents. The policy formulated in a consent can allow setting a filter to be applied for particular requesters or particular type of requests. The best way to model this seems to be via an extension to the Provision element of the Consent resource to allow adding a filter expression.

Essentially, search filter expressions, can be the language for specifying redaction obligations across the board from the consent policy, all the way to the enforcement point at the FHIR server. From an implementation perspective, this provides an unambiguous interpretation and semantics for redaction obligations and also eliminates some of the implementation burden for translating different representations of the same obligation.