This page shows how to use the consentResourcePolicy
classes (that implement IConsentService
) which are provided by Smile.
Note: The sections below assume that an interceptor with the CONSENT_FETCH_QUERIES
or CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE
pointcuts have already been registered so the module can determine the applicable Consent resources for a request.
The following IConsentService
implementations can be used as a consentResourcePolicy in the consentRules
as a:
The smileSecurityLabelConsentServiceR4
is based on FHIR Security Labels and applicable CodeSystems (i.e. http://terminology.hl7.org/CodeSystem/v3-ActCode
).
When using this consentResourcePolicy
, 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 an 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.
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": {
"consentRules": [
{ "name": "PATIENT_GRANT_RULE", "matching": [ { "matchUrl": "Consent?scope=patient-privacy" } ], "consentResourcePolicy": "smileSecurityLabelConsentServiceR4"},
{ "name": "FALLBACK_RULE", "fixedPolicy": "REJECT"}
]
}
}
This JSON configuration has two rules:
PATIENT_GRANT_RULE
- This rule will match all Consent resources that have a scope of patient-privacy
(i.e. Consent?scope=patient-privacy
)
that were determined to be applicable for the incoming request. The smileSecurityLabelConsentServiceR4
will look for security labels which are present on both a Consent resource and the 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.FALLBACK_RULE
- If none of the Consent resources contain a security label which is also present on the clinical resource, this rule 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 a decisive consent verdict is not reached. Some privacy systems have a Default Reject Consent Policy.
Others may have default opt-out rules that grant access to some actors. These default rules, or fallback rules, should be added as the last rule in the consentRules
array.
This example uses a rule called DEFAULT_ALLOW_RULE
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": {
"consentRules": [
{ "name": "PATIENT_GRANT_RULE", "matching": [ { "matchUrl": "Consent?category=patient-grant-code" } ], "consentResourcePolicy": "smileSecurityLabelConsentServiceR4"},
{ "name": "DEFAULT_ALLOW_RULE", "fixedPolicy": "myDefaultAllowConsentService"}
]
}
}
This configuration requires implementers to create and register an interceptor with the CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE
pointcut and define an implementation of an IConsentService
that will be mapped to the myDefaultAllowConsentService
fixed policy.
The interceptor below shows what the CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE
pointcut will look like in this example:
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2025 Smile CDR, Inc.
* %%
* All rights reserved.
* #L%
*/
package com.smilecdr.demo.consentmodule;
import ca.cdr.api.consent.ConsentFixedPolicyRequest;
import ca.cdr.api.fhir.interceptor.CdrHook;
import ca.cdr.api.fhir.interceptor.CdrPointcut;
import ca.cdr.api.model.json.UserSessionDetailsJson;
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_FIXED_POLICY_CONSENT_SERVICE pointcut with a
* default allow consent resource policy.
*/
@SuppressWarnings({"unused"})
public class DefaultAllowConsentServiceInterceptor {
public static final String DEFAULT_ALLOW_CONSENT_SERVICE_NAME = "myDefaultAllowConsentService";
/**
* Uses the CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE pointcut to map <code>myDefaultAllowConsentService</code>
* to a custom <code>IConsentService</code> implementation.
* @param theFixedPolicyRequest {@link ConsentFixedPolicyRequest#getPolicyName()} contains the name of the consent
* service that should be mapped (<code>myDefaultAllowConsentService</code>)
* @param theUserSessionDetailsJson the user session details
* @return an IConsentService that will be used to supply the specified <code>fixedPolicy</code> name
*/
@CdrHook(CdrPointcut.CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE)
public IConsentService buildConsentService(
ConsentFixedPolicyRequest theFixedPolicyRequest, UserSessionDetailsJson theUserSessionDetailsJson) {
if (DEFAULT_ALLOW_CONSENT_SERVICE_NAME.equals(theFixedPolicyRequest.getPolicyName())) {
return new MyDefaultAllowConsentService();
}
return null;
}
/**
* The implementation of the IConsentService that will be used for <code>myDefaultAllowConsentService</code>
*/
static class MyDefaultAllowConsentService 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 where 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 multiple Consent resources for Patient/patient-1
were determined to be applicable for the request, that the BTG Consents will be evaluated first:
{
"willSeeResource": {
"consentRules": [
{ "name": "BREAK_THE_GLASS_RULE", "matching": [ { "matchUrl": "Consent?scope=Consent?purpose=BTG" } ], "consentResourcePolicy": "smileSecurityLabelConsentServiceR4"},
{ "name": "PATIENT_GRANT_RULE", "matching": [ { "matchUrl": "Consent?scope=patient-privacy" } ], "consentResourcePolicy": "smileSecurityLabelConsentServiceR4"},
{ "name": "FALLBACK_RULE", "fixedPolicy": "REJECT"}
]
}
}
Now when Organization/organization-1
requests access to substance abuse related clinical resources for Patient/patient-1
(i.e. Observation/observation-eth
), the consents determined to be applicable for the request 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
).
The following IConsentService
implementations can be used as fixedPolicy in the consentRules
:
Returns AUTHORIZED
for all non-Patient compartment resources (i.e. Binary, Organization, etc.)
or PROCEED
if the resource is in the Patient compartment.
Sample usage:
{
"canSeeResource": {
"consentRules": [
...
{ "name": "ALLOW_NON_PATIENT_COMPARTMENT_RULE", "fixedPolicy": "ALLOW_NON_PATIENT_COMPARTMENT_RESOURCES" },
...
]
}
}
Returns AUTHORIZED
if the requesting user has the SUPERUSER
permission, or PROCEED
if they do not.
Sample usage:
{
"canSeeResource": {
"consentRules": [
...
{ "name": "ALLOW_SUPERUSER_RULE", "fixedPolicy": "ALLOW_SUPERUSER" },
...
]
}
}
Returns AUTHORIZED
if a resource has an unrestricted security label (http://terminology.hl7.org/CodeSystem/v3-Confidentiality|U
)
or PROCEED
if it does not.
Sample usage:
{
"canSeeResource": {
"consentRules": [
...
{ "name": "ALLOW_UNRESTRICTED_RULE", "fixedPolicy": "UNRESTRICTED_V3_CONFIDENTIALITY" },
...
]
}
}