A Developer's Guide to Security Labels in FHIR

- 11 mins

(This post will be updated to incrementally add more details.)

Purpose

There are a lot of resources on data tagging and security labels, discussing use cases, policy and legal background, high-level business cases, and conceptual structures. The goal of this post, however, is to provide a lean, concise, and hands-on guide for software developers to get acquainted with the idea and get started on the implementation. I refer to other resources for further reading and deeper dives.

Security Labels

Similar to stamps on a paper document, security labels are markers or tags on a FHIR resource (or in some cases, a portion of a resource) that record and convey privacy and security metadata. These labels can be used for different purposes such as access control, workflow navigation, or shaping user experience. For more on security labels see [1], [2], and [7].

Some of the most common types of security labels are:

For a deep dive into these and other types of security labels see [2].

Security labels often come from standard terminologies and vocabularies. A security label is an object with the following attributes:

For a deeper dive into other attributes that may appear in a label see the FHIR Coding data structure.

Examples

A confidentiality label denoting restricted information:

{
  "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
  "code": "R",
  "display": "restricted"
}

A sensitivity label denoting information from or related to psychotherapy notes:

{
  "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
  "code": "PSYTHPN",
  "display": "psychotherapy note information sensitivity"
}

A provenance label denoting that the information originated from a device:

{
  "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationValue",
  "code": "DEVRPT",
  "display": "device reported"
}

An obligation label denoting handling instructions to delete the data after use:

{
  "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
  "code": "DELAU",
  "display": "delete after use"
}

Labeling a FHIR Resource

Conceptually, security labels are metadata, so, they are placed in the meta attribute of a FHIR resource under security. This attribute is an array and can contain multiple security labels, as shown in the following example:

{
  "resourceType": "Observation",
  "meta": {
    "security": [
     {
       "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
       "code": "R",
       "display": "restricted"
     },
     {
       "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
       "code": "SUD",
       "display": "substance use disorder information sensitivity"
     },
     {
       "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
       "code": "DELAU",
       "display": "delete after use"
     }
    ]
  },
  //...
}

Even though labels can be assigned to FHIR resources manually, they are often assigned automatically by a Security Labeling Service (SLS) based on rules and policies. For a deep dive into SLS functionality and implementation see [3] and [6].

Labeling a Portion of a FHIR Resource

Some use cases call for a more granular assignment of security labels to convey that a label only applies to an element or portion of a resource. For example, for a patient whose safety is at risk, the residential address (but not the mailing address) may be confidential, and in order to correctly handle these data items, this distinction must be accurately recorded.

Security labels that apply only to a portion of a resource are called inline labels and are assigned as the following:

For example, the following resource contains a confidentiality label on the first identifier to denote that it is restricted, and another inline provenance label on the second identifier to denote that the identifier was asserted by the patient and may be unverified.

{
  "resourceType": "Patient",
  "meta": {
    "security": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PROCESSINLINELABEL"
      }
    ]
  },
  "identifier": [
    {
      "extension": [
        {
          "url": "http://hl7.org/fhir/uv/security-label-ds4p/StructureDefinition/extension-inline-sec-label",
          "valueCoding": {
            "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
            "code": "R",
            "display": "restricted"
          }
        }
      ],
      "use": "official",
      "system": "http://hl7.org/fhir/sid/us-ssn",
      "value": "111-22-3333"
    },
    {
      "extension": [
        {
          "url": "http://hl7.org/fhir/uv/security-label-ds4p/StructureDefinition/extension-inline-sec-label",
          "valueCoding": {
            "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationValue",
            "code": "PATAST",
            "display": "patient asserted"
          }
        }
      ],
      "use": "usual",
      "type": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "DL"
          }
        ]
      },
      "system": "urn:oid:2.16.840.1.113883.4.3.2",
      "value": "1234567"
    }
  ]
  ///...
}

A resource may contain both inline and resource-level labels, for example, a resource-wide confidentiality label and a provenance label on an identifier. For more on inline labels refer to [5].

Adding More Metadata

Some use cases call for recording additional information about the labels or the circumstances of labeling. This metadata can be recorded using FHIR extensions some of which will be discussed here. For a deep dive into these and other extensions see [4]. To learn more about FHIR extensions see the FHIR core module on extensions.

Recording the “Why”

To record the policy or law based on which a label has been assigned, you can use the extension-sec-label-basis extension on a label. The value should come from a standard terminology. Some example codes (mostly for US laws and policies) are included here.

The following example shows a label that has been assigned based on a particular US federal law about the confidentiality of substance use information:

{
  "extension": [
   {
     "url": "http://hl7.org/fhir/uv/security-label-ds4p/StructureDefinition/extension-sec-label-basis",
     "valueCoding": {
       "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
       "code": "42CFRPart2",
       "display": "42 CFR Part2"
    }
   }
  ],
  "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
  "code": "R",
  "display": "restricted"
}

Recording the “Who”

To record the actor that assigns a label you can use the extension-sec-label-classifier. This can be an identifier of, or a direct link to the security labeling software service, an individual, an organization, or other actors. The extension can be repeated to record more than one actor, for example, an organization and an individual.

The extension value is based on the FHIR Reference data type that supports linking to an internal entity such as a FHIR Patient resource, referencing an external entity such as a user ID, or a plain string in the display attribute as shown in the following example:

{
  "extension": [
    {
      "url": "http://hl7.org/fhir/uv/security-label-ds4p/StructureDefinition/extension-sec-label-classifier",
      "valueReference": {
       "display": "XYZ Security Labeling Service v1.0.2"
      }
    }
  ],
  "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
  "code": "R",
  "display": "Restricted"
}

Processing Labels

In most use cases, two labels are identical if both the code and system attributes match – the display attribute is optional for human readability and is not an identifier.

Internally, you can use a shorthand to represent a label as a simple string by concatenating the code to the system delimited by a #, for example:

http://terminology.hl7.org/CodeSystem/v3-ActCode#DELAU

This is a convenient way to enable using basic string comparisons (rather than deep object comparisons) in functions where you need to determine if two labels are the same.

When preparing the final form of a labeled resource (for sending over the wire, or persisting) it is often important to merge duplicate labels. Duplicate labels may result from applying different labeling rules at different stages of processing, or manual labelling.

Note that if additional information is recorded on a label in the form of extensions, the extensions should be taken into account in removing duplicates. For example, if the same confidentiality label is assigned twice, each based on a different policy, the extension-sec-label-basis values should be preserved by combining them in the extension array of the final confidentiality label.

Confidentiality: Ordered Labels

The standard confidentiality labels defined by FHIR are in a hierarchy with the following order (from high to low): very restricted (V), restricted (R), normal (N), moderate (M), low (L), and unrestricted (U).

Many use cases hinge on the implications of this hierarchy. For example, a very common use case is to decide what information a user can receive based on the top-most level of confidentiality they are authorized to access (i.e. clearance). A user with the clearance of restricted is authorized to receive restricted, normal, or unrestricted information but not very restricted information.

To implement this order, it is often helpful (and leads to cleaner and more readable code) if you internally map these labels to integer values and use integer comparison (i.e. >= or <=) for determining whether a confidentiality label subsumes the other.

Further Reading

[1] FHIR Core, Security Labels Module

[2] FHIR Data Segmentation for Privacy (DS4P) Implementation Guide (IG), Value Sets Summary

[3] FHIR DS4P IG, Implementation Notes

[4] FHIR DS4P IG, Extensions Summary

[5]FHIR DS4P IG, Inline Security Labels

[6] M. Jafari et. al., Security Labeling Service: Notes on Implementation, Mar. 18, 2021.

[7] John Moehrke, Segmenting Sensitive Health Topics, Feb. 20, 2019.

rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora