This page shows how to use the consentServiceFactory
classes that are provided by Smile.
Note: The sections below assume that an interceptor with the CONSENT_FETCH_QUERIES
pointcut has already been registered to provide the module with Consent Fetch Queries.
The smileSecurityLabelConsentServiceR4
is based on FHIR Security Labels and applicable CodeSystems (i.e. http://terminology.hl7.org/CodeSystem/v3-ActCode
).
When using this consentServiceFactory
, clinical resources which fall under a particular category of confidentiality should have the appropriate security labels added.
Consent resources can then be created by the Consent custodian to determine who (Organization, Practitioner, etc) can access Patient records based on the security labels that were added.
The Consent.provision.type
field is used by the smileSecurityLabelConsentServiceR4
to determine a consent verdict.
In particular, permit
results in a AUTHORIZED
verdict, meaning that the Consent.provision.actor
will be able to access any clinical records for Consent.patient
with the specified securityLabel
s.
Conversely, deny
results in a REJECT
verdict, meaning that the Consent.provision.actor
will not be able to access any records for Consent.patient
with the specified securityLabel
s.
Note: The smileSecurityLabelConsentServiceR4
only examines the provision type, and the security labels that are present on the Consent resource and the clinical resource. It is assumed that the implementer has configured Consent Fetch Queries to fetch active Consents with the appropriate Consent.provision.actor
and Consent.patient
.
For example, the Observation below belongs to Patient/patient-1
and has the http://terminology.hl7.org/CodeSystem/v3-ActCode|PSY security label.
{
"resourceType": "Observation",
"meta": {
"security": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "PSY"
}
]
},
"subject": {
"reference": "Patient/patient-1"
}
}
The Consent Custodian can then create a Consent resource to grant
Organization/organization-1
access to all of Patient/patient-1
records that are tagged with http://terminology.hl7.org/CodeSystem/v3-ActCode|PSY
:
{
"resourceType": "Consent",
"status": "active",
"scope": {
"coding": [ {
"system": "http://terminology.hl7.org/CodeSystem/consentscope",
"code": "patient-privacy"
} ]
},
"patient": {
"reference": "Patient/patient-1"
},
"dateTime": "2024-01-01",
"provision": {
"type": "permit",
"actor": [ {
"reference": {
"reference": "Organization/organization-1"
}
} ],
"securityLabel": [ {
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "PSY"
} ]
}
}
The JSON configuration below shows a simple Default Reject Consent Policy:
{
"willSeeResource": {
"consentServiceFactory": "smileSecurityLabelConsentServiceR4",
"consentRules": [
{ "name": "PATIENT_GRANT_RULE", "matching": [ { "matchUrl": "Consent?scope=patient-privacy" } ]}
],
"fallbackConsentRule": "REJECT"
}
}
This JSON configuration only has one rule (i.e. PATIENT_GRANT_RULE
) which will match all Consent resources that have a scope of
patient-privacy
(i.e. Consent?scope=patient-privacy
) that were found by the consent fetch queries.
The smileSecurityLabelConsentServiceR4
will look for security labels which are present on both a Consent resource and a clinical resource.
If there are matching security labels, a verdict of AUTHORIZED
will be given and the requester will be able to access the clinical resource.
If none of the Consent resources contain a security label which is also present on the clinical resource, the fallbackConsentRule
will give a verdict of REJECT
and the requester will not be able to access to the clinical resource.
All privacy systems have a default verdict if no explicit consent is recorded. Some privacy systems have a Default Reject Consent Policy.
Others may have default opt-out rules that grant access to some actors. These different defaults are configured by the fallbackConsentRule
policy.
This example uses the fallbackConsentRule
to implement a system where clinical resources with an "unrestricted" security label
(i.e. http://terminology.hl7.org/CodeSystem/v3-Confidentiality|U
) are accessible to all users. This might be used to implement practitioner access to a regional EHR.
Note: This example assumes that the endpoint is limited to eligible practitioners. A single endpoint serving different audiences (patients, care providers, researchers, etc.) will require additional rules.
The JSON configuration below shows how the Consent Module can be configured with a Default Allow Consent Policy:
{
"willSeeResource": {
"consentServiceFactory": "smileSecurityLabelConsentServiceR4",
"consentRules": [
{ "name": "PATIENT_GRANT_RULE", "matching": [ { "matchUrl": "Consent?category=patient-grant-code" } ]}
],
"fallbackConsentRule": "myDefaultAllowFallbackConsentService"
}
}
This configuration requires implementers to create and register an interceptor with the CONSENT_BUILD_CONSENT_SERVICE
pointcut to configure a custom fallback consent rule(i.e. myDefaultAllowFallbackConsentService
).
The interceptor below shows what the CONSENT_BUILD_CONSENT_SERVICE
pointcut will look like in this example:
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2024 Smile CDR, Inc.
* %%
* All rights reserved.
* #L%
*/
package com.smilecdr.demo.consentmodule;
import ca.cdr.api.fhir.interceptor.CdrHook;
import ca.cdr.api.fhir.interceptor.CdrPointcut;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOutcome;
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices;
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentService;
import org.hl7.fhir.instance.model.api.IBaseResource;
/**
* A sample interceptor that demonstrates how to use the CONSENT_BUILD_CONSENT_SERVICE pointcut with a
* default allow consent policy.
*/
@SuppressWarnings({"unused"})
public class DefaultAllowFallbackConsentServiceInterceptor {
public static final String FALLBACK_CONSENT_SERVICE_NAME = "myDefaultAllowFallbackConsentService";
/**
* Uses the CONSENT_BUILD_CONSENT_SERVICE pointcut to map <code>myDefaultAllowFallbackConsentService</code>
* to a custom <code>IConsentService</code> implementation.
* @param theConsentServiceName - the name of the consent service that should be mapped (<code>myDefaultAllowFallbackConsentService</code>)
* @param theOptionalConsent - the Consent resource. This will be null for all <code>fallbackConsentRules</code>
* @return an IConsentService that will be used to supply the <code>fallbackConsentRule</code>
*/
@CdrHook(CdrPointcut.CONSENT_BUILD_CONSENT_SERVICE)
public IConsentService buildConsentService(String theConsentServiceName, IBaseResource theOptionalConsent) {
if (FALLBACK_CONSENT_SERVICE_NAME.equals(theConsentServiceName)) {
return new MyDefaultAllowFallbackConsentService();
}
throw new IllegalArgumentException("No IConsentService registered for: " + theConsentServiceName);
}
/**
* The implementation of the IConsentService that will be used for <code>myDefaultAllowFallbackConsentService</code>
*/
static class MyDefaultAllowFallbackConsentService implements IConsentService {
private static final String CONSENT_SECURITY_SYSTEM = "http://terminology.hl7.org/CodeSystem/v3-Confidentiality";
private static final String UNRESTRICTED_CODE = "U";
@Override
public ConsentOutcome willSeeResource(
RequestDetails theRequestDetails, IBaseResource theResource, IConsentContextServices theContextServices) {
if (theResource == null) {
return ConsentOutcome.PROCEED;
}
if (theResource.getMeta().getSecurity(CONSENT_SECURITY_SYSTEM, UNRESTRICTED_CODE) != null) {
return ConsentOutcome.PROCEED;
}
return ConsentOutcome.REJECT;
}
}
}
The configuration above will be able to accommodate the two scenarios below.
Consider the clinical resource below:
{
"resourceType": "Observation",
"id": "observation-u",
"meta": {
"security": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
"code": "U"
}
]
},
"subject": {
"reference": "Patient/patient-1"
}
}
If Organization/organization-1
wanted to access Observation/observation-u
and no Consent resource was present,
they would be able to because it has the unrestricted security label (http://terminology.hl7.org/CodeSystem/v3-Confidentiality|U
).
Now consider the clinical resource below:
{
"resourceType": "Observation",
"id": "observation-r",
"meta": {
"security": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
"code": "R"
}
]
},
"subject": {
"reference": "Patient/patient-1"
}
}
If Organization/organization-1
wanted to access Observation/observation-r
and no Consent resource was present,
they would not be able to because it has a restricted security label (http://terminology.hl7.org/CodeSystem/v3-Confidentiality|R
).
The Consent Custodian would need to create the Consent resource below in order for Organization/organization-1
to access Observation/observation-r
:
{
"resourceType": "Consent",
"status": "active",
"category": [ {
"coding": [ {
"system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
"code": "patient-grant-code"
} ]
} ],
"patient": {
"reference": "Patient/patient-1"
},
"dateTime": "2024-01-01",
"provision": {
"type": "permit",
"actor": [ {
"reference": {
"reference": "Organization/organization-1"
}
} ],
"securityLabel": [ {
"system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
"code": "R"
} ]
}
}
In some cases it may be necessary to define consent rules which are evaluated in a defined order.
The example below describes a Break-The-Glass (BTG) consent policy which uses rule precedence to allow emergency access to clinical resources:
Imagine that a Patient/patient-1
provided access to Organization/organization-1
to view all of their psychiatric related
(http://terminology.hl7.org/CodeSystem/v3-ActCode|PSY
) clinical resources using the Consent resource below:
{
"resourceType": "Consent",
"id": "consent-psy",
"status": "active",
"scope": {
"coding": [ {
"system": "http://terminology.hl7.org/CodeSystem/consentscope",
"code": "patient-privacy"
} ]
},
"patient": {
"reference": "Patient/patient-1"
},
"dateTime": "2024-01-01",
"provision": {
"type": "permit",
"actor": [ {
"reference": {
"reference": "Organization/organization-1"
}
} ],
"securityLabel": [ {
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "PSY"
} ]
}
}
With this Consent resource created, Organization/organization-1
would not have access to the Patient/patient-1
record below because it is a substance abuse related clinical resource (http://terminology.hl7.org/CodeSystem/v3-ActCode|ETH
):
{
"resourceType": "Observation",
"id": "observation-eth",
"meta": {
"security": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "ETH"
}
]
},
"subject": {
"reference": "Patient/patient-1"
}
}
Now imagine that Patient/patient-1
has overdosed and is rushed into the emergency room. They are unconscious and the doctor needs to administer an emergency medication.
In this situation, it would be important for the doctor to be able to access all clinical resources that have information about interactions with the medication that needs to be administered. The current Consent resource
(i.e. Consent/consent-psy
) would not allow Organization/organization-1
to view substance abuse related resources
(i.e. Observation/observation-eth
).
This would be considered a Break-The-Glass (BTG) scenario in which Patient/patient-1
cannot give consent for their substance abuse related records to be accessed, but the doctor needs to access these records to provide lifesaving treatment.
In order for Organization/organization-1
to view the substance abuse related record, the Consent Custodian must create the Consent resource below:
{
"resourceType": "Consent",
"id": "consent-btg",
"status": "active",
"scope": {
"coding": [ {
"system": "http://terminology.hl7.org/CodeSystem/consentscope",
"code": "patient-privacy"
} ]
},
"patient": {
"reference": "Patient/patient-1"
},
"dateTime": "2024-01-01",
"provision": {
"type": "permit",
"actor": [ {
"reference": {
"reference": "Organization/organization-1"
}
} ],
"securityLabel": [ {
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "ETH"
} ],
"purpose": [ {
"system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
"code": "BTG"
} ]
}
}
This Consent resource has the substance abuse related security label (http://terminology.hl7.org/CodeSystem/v3-ActCode|ETH
)
however, it also has a Consent.purpose
of http://terminology.hl7.org/CodeSystem/v3-ActReason|BTG
.
With Consent/consent-btg
created, the Consent module can use the JSON configuration below to ensure that if the consent fetch queries return multiple Consent resources for Patient/patient-1
, that the BTG Consents will be evaluated first:
{
"willSeeResource": {
"consentServiceFactory": "smileSecurityLabelConsentServiceR4",
"consentRules": [
{ "name": "BREAK_THE_GLASS_RULE", "matching": [ { "matchUrl": "Consent?scope=Consent?purpose=BTG" } ]},
{ "name": "PATIENT_GRANT_RULE", "matching": [ { "matchUrl": "Consent?scope=patient-privacy" } ]}
],
"fallbackConsentRule": "REJECT"
}
}
Now when Organization/organization-1
requests access to substance abuse related clinical resources for Patient/patient-1
(i.e. Observation/observation-eth
), the consent fetch queries will return
Consent/consent-psy
(no substance abuse security label) and Consent/consent-btg
(substance abuse security label).
Because we defined BREAK_THE_GLASS_RULE
before PATIENT_GRANT_RULE
, and Consent/consent-btg
has a purpose of BTG
,
the requesting organization (Organization/organization-1
) will be able to access the necessary substance abuse clinical resource (Observation/observation-eth
).