Working with Privacy

Keeping health information secure is at the core of what we at Orion Health design our products to do, and our Open APIs are no exception.

All health information is considered sensitive, and some even more sensitive than the rest, so health information must be handled with utmost care to ensure that only the right people have access to the information that they need in order to deliver healthcare effectively.

The Orion Health Privacy Service, which backs all our user interactions, is used to determine what health information a given user is allowed to access. It does so by evaluating a number of factors such as the user's role, relationship with the record, the patient's consent status, the type of information being accessed, as well as other relevant information in order to come up with an access level for the user.

In order for a user to be allowed to perform a particular operation both of the following must be true:

  1. An appropriate access level is returned from the Privacy Service
  2. The user must have functional permission to perform the specific operation.

Part of working with the Orion Health Open APIs is having to understand how the APIs respond in situations where the user might not have full access to the data they are requesting, or operation they are attempting to carry out.

All responses to API calls will include information about the resolved privacy of the requested resource.

Access to a Patient Record

Access to the patient record has four levels:

Access Level Description
NO_ACCESS The patient is not returned in any API calls.
LOCKED Basic identifying information is returned. This includes the patient's name, gender, date of birth, address, and identifier. Additional patient demographics and health information cannot be accessed. A redacted security tag is included to denote the missing data.
SEALED Basic identifying information is returned. This includes the patient's name, gender, date of birth, address, and identifier. Additional patient demographics can be accessed by breaking the privacy seal. A redacted security tag is included to denote the missing data.
FULL_ACCESS / SEAL_OPEN All patient demographics are returned

Access to Patient Health Information

Access to the patient health information has five levels:

Access Level Description
NO_ACCESS The patient health information is not returned in any API calls.
LOCKED Basic information is returned. For example, the title of a document in the patient's record. Additional information cannot be accessed. A redacted security tag is included to denote the missing data.
LIST_MORE Certain patient health information is hidden. The user needs to request access to view this information.
SEALED Basic information is returned. For example, the title of a document in the patient's record. Additional information can be accessed by breaking the privacy seal. A redacted security tag is included to denote the missing data.
FULL_ACCESS / SEAL_OPEN The patient health information is returned.

Access to patient health information is dependent on the resolved access level for a patient record. Only when the resolved access level to the patient record is FULL_ACCESS or SEAL_OPEN, will the access level to the patient's health information be resolved or returned. Health information for patients with NO_ACCESS, LOCKED, or SEALED access levels cannot be retrieved.

Orion Health APIs evaluate the access level for each resource being requested and return an appropriate indication in the response using HATEOAS links. A list of health information for a single patient may have different access levels for each resource in the list.

Privacy information is conveyed in the API responses using Hypermedia As The Engine Of Application State (HATEOAS) links. HATEOAS provides links that are used to find your way through the API. Depending on the access level evaluated for the user making the request, different links are returned as part of the response from a call to Orion Health APIs.

The links can serve multiple purposes. The main use cases are as follows:

  • The application consuming the APIs can detect the links and display UI hints to indicate the privacy status of the resource.
  • The user can follow the links to act on them (e.g. break the privacy seal), or to know more about the privacy status of the resource that they are trying to access.

FHIR APIs include HATEOAS links in the responses in accordance with the HL7 FHIR specification.

A read request for an instance of a resource (e.g. request for a patient's demographic information) will return HATEOAS links in the header of the response. An example of HATEOS link in the HTTP response header:

GET https://example.com/fhir/1.0/Patient/205a6756-7f36-4410-823e-d6fbd48ea490
HTTP/1.1 200 OK
Content-Type : application/json;charset=UTF-8
Link : </privacy/v1/describe-redacted>;rel="describe-redacted" , </patient/8765-4321@OHCP/break-the-seal/patient>;rel="request-access"

{
    "resourceType": "Patient",
    "id": "205a6756-7f36-4410-823e-d6fbd48ea490",
    "identifier": [
        {
            "system": "OHCP",
            "value": "8765-4321"
        }
    ],
    "name": [
        {
            "use": "usual",
            "family": [
                "Cardinal"
            ],
            "given": [
                "John",
                "My Middle Name"
            ],
            "suffix": [
                "suffix"
            ]
        }
    ],
    "gender": "male",
    "birthDate": "1949-12-11"
} 

A request that will produce a list of results being returned in a bundle, such as a search interaction, will include HATEOAS links for each result entry. An example of HATEOAS link in Bundle.entry.link:

GET https://example.com/fhir/1.0/Patient?family=Perry&given=Matthew
HTTP/1.1 200 OK
Content-Type : application/json;charset=UTF-8

{
    "resourceType": "Bundle",
    "total": 1,
    "link": [
        {
            "relation": "self",
            "url": "/fhir/1.0/Patient?family=Perry&given=Matthew"
        }
    ],
    "entry": [
        {
            "link": [
                {
                    "relation": "describe-redacted",
                    "url": "/privacy/v1/describe-redacted"
                },
                {
                    "relation": "request-access",
                    "url": "/patient/5555-5557@OHCP/break-the-seal/patient"
                }
            ],
            "fullUrl": "/fhir/1.0/Patient/GU2TKNJNGU2TKN2AJ5EEGUA",
            "resource": {
                "resourceType": "Patient",
                "id": "GU2TKNJNGU2TKN2AJ5EEGUA",
                "identifier": [
                    {
                        "system": "OHCP",
                        "value": "5555-5557"
                    }
                ],
                "name": [
                    {
                        "use": "usual",
                        "family": [
                            "Perry"
                        ],
                        "given": [
                            "Matthew",
                            "L."
                        ]
                    }
                ],
                "birthDate": "1981-12-03"
            }
        }
    ]
} 

A request that will produce a list of results being returned in a bundle, such as a search interaction, but one or more of the results belong to a patient who is sealed or locked will include an HATEOAS link in the bundle. An example of HATEOAS link in Bundle.link

GET https://example.com/fhir/1.0/AllergyIntolerance?patient.identifier=OHCP|4321-8765
HTTP/1.1 200 OK
Content-Type : application/json;charset=UTF-8

{
    "resourceType": "Bundle",
    "id": "42a6a1d5-ea4e-41b6-ac09-0e7401f27f5f",
    "meta": {
        "lastUpdated": "2017-12-14T16:26:30.969+13:00"
    },
    "type": "searchset",
    "total": 0,
    "link": [
        {
            "relation": "self",
            "url": "/fhir/1.0/TestAllergyIntolerance?patient.identifier=OHCP%7C4321-8765"
        },
        {
            "relation": "request-additional-access",
            "url": "/patient/4321-8765@OHCP/break-the-seal/information?informationTypesToken=1234"
        },
        {
            "relation": "describe-redacted",
            "url": "/privacy/v1/describe-redacted"
        }
    ]
} 

The following sections outline the links that will be returned for each of the access levels described above for both access to the patient record and access to the patient's health information.

Patient Record Privacy

The following tables outline the behavior of the APIs when searching for, or accessing, a patient record e.g. calling the FHIR Patient API

Search Operations

A search operation is where an API is queried with one or more search parameters expecting a list of results to be returned.

Patient Access Level rel (relationship type) URI Link Location HTTP Response Code
FULL_ACCESS N/A N/A N/A 200
SEALED describe-redacted /privacy/v1/describe-redacted Bundle.entry.link 200
request-access /patient/<identifier>@<namespace>/break-the-seal/patient Bundle.entry.link 200
SEAL_OPEN describe-unredacted /privacy/v1/describe-unredacted Bundle.entry.link 200
LOCKED describe-redacted /privacy/v1/describe-redacted Bundle.entry.link 200
NO_ACCESS N/A N/A N/A 200

Read Operations

A read operation is where a single record is requested.

Patient Access Level rel (relationship type) URI Link Location HTTP Response Code
FULL_ACCESS N/A N/A N/A 200
SEALED describe-redacted /privacy/v1/describe-redacted HTTP response header 200
request-access /patient//patient/<identifier>@<namespace>/break-the-seal/patient HTTP response header 200
SEAL_OPEN describe-unredacted /privacy/v1/describe-unredacted HTTP response header 200
LOCKED describe-redacted /privacy/v1/describe-redacted HTTP response header 200
NO_ACCESS N/A N/A N/A 404

Patient Health Information Privacy

The following tables outline the behaviour of the APIs when searching for, accessing, or writing patient health information e.g. calling the FHIR Observation API

Search Operations

A search operation is where an API is queried with one or more search parameters expecting a list of results to be returned.

When the Patient Access Level is FULL_ACCESS the following behavior can be expected for each of the patient health information (resource) access levels:

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
FULL_ACCESS N/A N/A N/A 200
SEALED describe-redacted /privacy/v1/describe-redacted Bundle.entry.link 200
request-access /patient/<identifier>@<namespace>/break-the-seal/information?informationTypesToken=<secure_token> Bundle.entry.link 200
LIST_MORE describe-redacted /privacy/v1/describe-redacted Bundle.link 200
request-access /patient/<identifier>@<namespace>/break-the-seal/information?informationTypesToken=<secure_token> Bundle.link 200
SEAL_OPEN describe-unredacted /privacy/v1/describe-unredacted Bundle.entry.link 200
LOCKED describe-redacted /privacy/v1/describe-redacted Bundle.entry.link 200
NO_ACCESS N/A N/A N/A 200

When the Patient Access Level is SEAL_OPEN the following additional HATEOAS links will be returned

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
Any describe-unredacted /privacy/v1/describe-unredacted Bundle.link 200

When the Patient Access Level is SEALED only the following HATEOAS links will be returned

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
Any describe-redacted /privacy/v1/describe-redacted Bundle.link 200
Any request-access \about:blank\ Bundle.link 200

When the Patient Access Level is LOCKED only the following HATEOAS link will be returned

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
Any describe-redacted /privacy/v1/describe-redacted Bundle.link 200

When the Patient Access Level is NO_ACCESS no HATEOAS links will be returned

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
Any N/A N/A N/A 200

Read or Write Operations

A read operation is where a single resource is requested, and a write operation is where a resource is created or updated.

When the Patient Access Level is FULL_ACCESS the following behavior can be expected for each of the patient health information (resource) access levels:

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code - Read HTTP Response Code - Write
FULL_ACCESS N/A N/A N/A 200 201
SEALED describe-redacted /privacy/v1/describe-redacted HTTP response header 200 403
request-access /patient/<identifier>@<namespace>/break-the-seal/information?informationTypesToken=<secure_token> HTTP response header 200 403
LIST_MORE describe-redacted /privacy/v1/describe-redacted HTTP response header 403 403
request-access /patient/<identifier>@<namespace>/break-the-seal/information?informationTypesToken=<secure_token> HTTP response header 403 403
SEAL_OPEN describe-unredacted /privacy/v1/describe-unredacted HTTP response header 200 200
LOCKED describe-redacted /privacy/v1/describe-redacted HTTP response header 403 403
NO_ACCESS N/A N/A N/A 404 404

When the Patient Access Level is SEAL_OPEN the following additional HATEOAS link will be returned

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
Any describe-unredacted /privacy/v1/describe-unredacted HTTP response header As above

When the Patient Access Level is SEALED only the following HATEOAS links will be returned

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
Any describe-redacted /privacy/v1/describe-redacted HTTP response header 403
Any request-access \about:blank\ HTTP response header 403

When the Patient Access Level is LOCKED only the following HATEOAS link will be returned

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
Any describe-redacted /privacy/v1/describe-redacted HTTP response header 403

When the Patient Access Level is NO_ACCESS no HATEOAS links will be returned

Resource Access Level rel (relationship type) URI Link Location HTTP Response Code
Any N/A N/A N/A 404

Privacy Restricted Security Tag

When FHIR resources are privacy evaluated as LOCKED or SEALED , a "REDACTED" security tag is added to the metadata of the resource. This is done to indicate that some portion of data has been filtered out due to the privacy evaluation of the resource.

Redacted Security Tag Example

"resource": {
        "resourceType": "DocumentReference",
        "id": "9b5a73a5-5222-4083-8c78-e673868caf09",
        "meta": {
          "security": [
            {
              "system": "http://hl7.org/fhir/ValueSet/v3-SecurityIntegrityObservationValue",
              "code": "REDACTED"
            }
          ]
}