The Consent Module contributes a Consent Service to FHIR Endpoints or Persistence modules.
A Consent Service can remove or alter the resource(s) in a response to enforce privacy rules, or to remove proprietary data during a data transfer between organizations.
The Consent Service created by a Consent Module is configured dynamically for each request. This can be done in 2 ways:
These partial Consent Services are then combined using the ordered rules to determine the verdict from the startOperation
, canSeeResource
, and willSeeResource
consent hooks.
A Consent Service can use the startOperation
hook to block requests, and thecanSeeResource
, and willSeeResource
hooks remove or alter the resource(s) in a response.
For background on the Consent Service, and the capabilities of startOperation
, canSeeResource
, and willSeeResource
, see the introduction and API documentation below:
Each method in this interface represents a consent method. Consent logic can be applied to resources in a clinical repository however, there is no integration with
Consent
resources in a consent repository.
The Consent Module has the same consent methods, but instead of code, implementers use JSON configuration to define rules. These rules are:
Consent
resources 2. Evaluated in the order they are defined 3. Flexible and can allow fixed logic to be executed if required (i.e. Bypass for Superusers, handling fallback scenarios where a Consent verdict was not reached)The sample JSON below will be used to show how the Consent Module is configured:
{
"willSeeResource": {
"consentRules": [
{ "name": "ALLOW_USER_NAMES_RULE", "fixedPolicy": "myAllowUserNamesConsentService"},
{ "name": "BREAK_THE_GLASS_RULE", "matching": [ { "matchUrl": "Consent?purpose=BTG"} ], "consentResourcePolicy": "myConsentService"},
{ "name": "PATIENT_GRANT_RULE", "matching": [ { "matchUrl": "Consent?category=patient-grant-code" } ], "consentResourcePolicy": "myConsentService" },
{ "name": "ALLOW_NON_PATIENT_COMPARTMENT_RULE", "fixedPolicy": "ALLOW_NON_PATIENT_COMPARTMENT_RESOURCES" },
{ "name": "FALLBACK_RULE", "fixedPolicy": "REJECT" }
]
}
}
The first thing implementers must decide is which consent method the consent rules should apply to.
The Consent Module supports the startOperation
, canSeeResource
, and willSeeResource
consent methods.
The sample JSON configuration above uses the willSeeResource
consent method.
Implementers are required to create and register an interceptor that has at least one of the pointcuts below (both pointcuts may also be implemented):
JavaDoc: CONSENT_FETCH_QUERIES
A fetch query will typically define a Consent patient and a Consent actor.
The fetch query callback for the resource-specific methods (i.e. canSeeResource
and willSeeResource
)
will include the Patient id for resources in a Patient Compartment.
Implementors should extract the Consent Actor from the request. This can be done using custom headers, custom OIDC/SMART claims, or user information, however other methods may be used.
For example, if a request was being made by Organization/organization-1
to view Observation/observation-1
with
Observation.subject=Patient/patient-1
, a sensible fetch query might be:
Consent?status=active&actor=Organization/organization-1&patient=Patient/patient-1
Other common queries are:
Consent?status=active&actor:missing=true&patient=Patient/patient-1
Consent?status=active&actor=Organization/organization-1&patient:missing=true
JavaDoc: CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE
This pointcut is similar to the CONSENT_FETCH_QUERIES
pointcut, however instead of providing String-based Consent fetch queries,
implementers can provide Consent resource objects (IDomainResource
) that will be applied to an incoming request.
This pointcut offers a large range of flexibility and allows implementers to:
IGenenericClient
)@Autowire
in a resource DAO that can be used to perform more complex queries (or multiple queries)SUPERUSER
)The code snippet below shows a sample interceptor that implements the CONSENT_FETCH_QUERIES
and the CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE
pointcuts.
/*-
* #%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.CompartmentUtil;
import ca.cdr.api.consent.ConsentActiveResourceResolutionRequest;
import ca.cdr.api.consent.ConsentFetchQueries;
import ca.cdr.api.consent.ConsentLookupContext;
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.context.FhirContext;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IDomainResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Consent;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* A sample interceptor that demonstrates how to provide a list of Consent fetch queries by
* implementing the CONSENT_FETCH_QUERIES and CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE pointcut.
*/
@SuppressWarnings({"unused"})
public class DetermineApplicableConsentInterceptor {
private static final String SERVER_BASE = "http://some-server-base";
private final FhirContext myFhirContext;
private final IGenericClient myFhirClient;
public DetermineApplicableConsentInterceptor() {
myFhirContext = FhirContext.forR4Cached();
myFhirClient = myFhirContext.newRestfulGenericClient(SERVER_BASE);
}
/**
* Uses the CONSENT_FETCH_QUERIES pointcut to provide a list of fetch queries.
* @param theConsentFetchQueries - the object that consent queries should be added to
* @param theRequestDetails - the details of the request
* @param theConsentLookupContext - the consent lookup context
* @param theResource - the resource that consent rules should apply to
* @param theUserSessionDetails - the user session details
*/
@CdrHook(CdrPointcut.CONSENT_FETCH_QUERIES)
public void getConsentFetchQueries(
ConsentFetchQueries theConsentFetchQueries,
RequestDetails theRequestDetails,
ConsentLookupContext theConsentLookupContext,
IBaseResource theResource,
UserSessionDetailsJson theUserSessionDetails) {
Optional<IIdType> consentPatient = getConsentPatient(theResource);
if (consentPatient.isEmpty()) {
// This will happen if the resource is not in the patient compartment (i.e. Organization, Location, etc.)
// In this case, there will be no applicable Consent resource
return;
}
UriComponentsBuilder query = UriComponentsBuilder.fromPath("Consent")
.queryParam("status", "active")
.queryParam("patient.identifier", consentPatient.get().getValue())
.queryParam("actor:missing", "true");
theConsentFetchQueries.addQuery(query.toUriString());
}
/**
* Uses the CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE pointcut to provide consent resources.
* @param theResolutionRequest - the object that consent resources should be added to
* @param theRequestDetails - the details of the request
* @param theConsentLookupContext - the consent lookup context
* @param theResource - the resource that consent rules should apply to
* @param theUserSessionDetails - the user session details
*/
@CdrHook(CdrPointcut.CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE)
public void getConsentResolutionRequest(
ConsentActiveResourceResolutionRequest theResolutionRequest,
RequestDetails theRequestDetails,
ConsentLookupContext theConsentLookupContext,
IBaseResource theResource,
UserSessionDetailsJson theUserSessionDetails) {
Optional<IIdType> consentPatient = getConsentPatient(theResource);
if (consentPatient.isEmpty()) {
// This will happen if the resource is not in the patient compartment (i.e. Organization, Location, etc.)
// In this case, there will be no applicable Consent resource
return;
}
IIdType consentActor = getConsentActor(theUserSessionDetails);
UriComponentsBuilder query = UriComponentsBuilder.fromPath("Consent")
.queryParam("status", "active")
.queryParam("patient.identifier", consentPatient.get().getValue())
.queryParam("actor.identifier", consentActor.getValue());
Bundle bundle = myFhirClient
.search()
.byUrl(query.toUriString())
.returnBundle(Bundle.class)
.execute();
List<IDomainResource> consents = bundle.getEntry().stream()
.map(entry -> (Consent) entry.getResource())
.collect(Collectors.toList());
theResolutionRequest.addActiveConsents(consents);
}
/**
* Determines the Organization of the requester that will be used as <code>Consent.actor</code>
* @param theUserSessionDetails - the user session details
* @return IdDt of the Organization that will be used as the <code>Consent.actor</code>
*/
private IIdType getConsentActor(UserSessionDetailsJson theUserSessionDetails) {
// UserSessionDetailsJson contains all the user session and OIDC information for the incoming request
// so implementers can determine the consent actor.
String username = theUserSessionDetails.getUsername();
if ("ADMIN".equals(theUserSessionDetails.getUsername())) {
return myFhirContext.getVersion().newIdType("Organization", "1");
} else {
throw new IllegalArgumentException("Could not determine actor from UserSessionDetailsJson");
}
}
/**
* Finds the Patient compartment of the provided resource which is used to determine the <code>Consent.patient</code>
* @param theResource - the resource that consent rules should apply to
* @return Optional IIdType of the Patient that will be used as the <code>Consent.patient</code> if the resource is in the Patient compartment
*/
private Optional<IIdType> getConsentPatient(IBaseResource theResource) {
return CompartmentUtil.getPatientCompartmentForResource(myFhirContext, theResource);
}
}
The consentRules
are used create a list of policies which will be evaluated in the order that they are defined.
Each consent rule must have a name
and a single policy type.
There are two kinds of policies:
Note: Implementers may define Consent Resource policies for different Consent actors (i.e. Patient vs Organization).
A rule with a Consent Resource Policy must have the following properties:
matching
property with one or more matchUrl
elements 2. A consentResourcePolicy
propertyA Consent Resource Policy creates a list of Consent buckets that Consent
resources will be put into. These are defined by a name
and matchUrl
. After Consent
resources are obtained from Step 2 they will be placed into the "bucket" with the specified name
if they meet the matchUrl
criteria.
A new instance of an IConsentService
will be created for each Consent
resource. The actual implementation of the IConsentService
will be mapped using the Consent Resource Policy
(consentResourcePolicy
property).
If any of the IConsentService
instances in a bucket produce a REJECT
verdict, the verdict for the entire rule will be REJECT
. If the bucket does not produce any REJECT
verdicts and an AUTHORIZED
verdict,
the verdict for the entire rule will be AUTHORIZED
. If the bucket only produces PROCEED
verdicts,
the verdict for the entire rule will be PROCEED
.
A rule with a Fixed Policy must have a fixedPolicy
property.
Unlike a Consent Resource Policy, a Fixed Policy is not dependent on a Consent resource.
Fixed Policies can help implementers create rules to:
SUPERUSER
)A Fixed Policy will create a new instance of an IConsentService
for each resource in the incoming request. The actual implementation of the IConsentService
will be mapped using the Fixed Policy
(fixedPolicy
property).
As soon as there is a decisive verdict (i.e. AUTHORIZED
or REJECT
) from a consent rule, it will be used and none of the remaining consent rules will be evaluated. However, if the verdict from a rule is indecisive (i.e. PROCEED
)
the subsequent rules(s) will be evaluated.
ALLOW_USER_NAMES_RULE
- Creates an IConsentService
using the myAllowUserNamesConsentService
key that will be used to render a Consent Verdict for the incoming resource.
{ "name": "ALLOW_USER_NAMES_RULE", "fixedPolicy": "myAllowUserNamesConsentService" }
BREAK_THE_GLASS_RULE
- Contains a bucket for all Consent resources from Step 2 that have a purpose
of BTG
.
These Consent resources, along with the IConsentService
created using the myConsentService
key, will be used to render a Consent Verdict for the incoming resource.
{ "name": "BREAK_THE_GLASS_RULE", "matching": [ { "matchUrl": "Consent?purpose=BTG"} ], "consentResourcePolicy": "myConsentService"}
PATIENT_GRANT_RULE
- Contains a bucket for all Consent resources from Step 2 that have category
of patient-grant-code
.
These Consent resources, along with the IConsentService
created using the myConsentService
key, will be used to render a Consent Verdict for the incoming resource.
{ "name": "PATIENT_GRANT_RULE", "matching": [ { "matchUrl": "Consent?category=patient-grant-code" } ], "consentResourcePolicy": "myConsentService" }
ALLOW_NON_PATIENT_COMPARTMENT_RULE
- Creates an IConsentService
using the ALLOW_NON_PATIENT_COMPARTMENT_RESOURCES
key.
This is a Smile provided IConsentService
that will be produce a verdict of AUTHORIZED
for any non-Patient compartment resource.
If a resource is in the Patient compartment, it will produce a verdict of PROCEED
.
{ "name": "ALLOW_NON_PATIENT_COMPARTMENT_RULE", "fixedPolicy": "ALLOW_NON_PATIENT_COMPARTMENT_RESOURCES" }
FALLBACK_RULE
- Creates an IConsentService
using the REJECT
key. This is a Smile provided IConsentService
that will always render a REJECT
verdict. If an incoming resource does not reach a decisive verdict by the time it reaches the FALLBACK_RULE
, it will be rejected.
{ "name": "FALLBACK_RULE", "fixedPolicy": "REJECT" }
A Consent Policy is a name that maps to a Smile provided IConsentService or a custom IConsentService
.
To create a custom consentResourcePolicy
, an IConsentService
should be implemented that takes Consent
resource as a constructor argument. An interceptor should also be created and registered with a CONSENT_BUILD_CONSENT_RESOURCE_POLICY_CONSENT_SERVICE pointcut that maps a String
name to a new instance of the implemented IConsentService
.
The code snippet below shows a sample Interceptor that implements that CONSENT_BUILD_CONSENT_RESOURCE_POLICY_CONSENT_SERVICE
pointcut to create a custom consentResourcePolicy
:
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2025 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;
import org.hl7.fhir.r4.model.Consent;
/**
* A sample interceptor that demonstrates how to use the CONSENT_BUILD_CONSENT_RESOURCE_POLICY_CONSENT_SERVICE pointcut
*/
@SuppressWarnings({"unused"})
public class BuildConsentResourcePolicyConsentServiceInterceptor {
public static final String MY_CONSENT_SERVICE_NAME = "myConsentService";
/**
* Uses the CONSENT_BUILD_CONSENT_RESOURCE_POLICY_CONSENT_SERVICE pointcut to map the <code>consentResourcePolicy</code> property
* to a custom <code>IConsentService</code> implementations.
* @param theConsentServiceName - the name of the consent service that should be mapped (from <code>consentResourcePolicy</code>)
* @param theConsent - the Consent resource.
* @return an IConsentService that will be used to supply a <code>consentResourcePolicy</code>
*/
@CdrHook(CdrPointcut.CONSENT_BUILD_CONSENT_RESOURCE_POLICY_CONSENT_SERVICE)
public IConsentService buildConsentService(String theConsentServiceName, IBaseResource theConsent) {
if (MY_CONSENT_SERVICE_NAME.equals(theConsentServiceName)) {
return new MyConsentService(theConsent);
}
return null;
}
/**
* The implementation of IConsentService that will be used for the <code>consentResourcePolicy</code>
*/
static class MyConsentService implements IConsentService {
private final Consent myConsent;
public MyConsentService(IBaseResource theConsent) {
if (!(theConsent instanceof Consent)) {
throw new IllegalArgumentException(
"Invalid Consent resource: " + theConsent.getIdElement().getIdPart());
}
myConsent = (Consent) theConsent;
}
@Override
public ConsentOutcome canSeeResource(
RequestDetails theRequestDetails,
IBaseResource theResource,
IConsentContextServices theContextServices) {
if (isSpecialConsent(myConsent) && isSpecialResource(theResource)) {
return ConsentOutcome.AUTHORIZED;
}
return ConsentOutcome.PROCEED;
}
private boolean isSpecialConsent(Consent theConsent) {
return "some-special-consent".equals(theConsent.getId());
}
private boolean isSpecialResource(IBaseResource theResource) {
return "some-special-resource".equals(theResource.getIdElement().getIdPart());
}
}
}
To create a custom fixedPolicy
, an IConsentService
should be implemented. An interceptor should then be created and registered with a CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE pointcut that maps a String
name to a new instance of the implemented IConsentService
.
The code snippet below shows a sample Interceptor that implements that CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE
pointcut to create a custom fixedPolicy
:
/*-
* #%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;
import java.util.List;
/**
* A sample interceptor that demonstrates how to use the CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE pointcut
*/
@SuppressWarnings({"unused"})
public class BuildFixedPolicyConsentServiceInterceptor {
public static final String MY_ALLOW_USER_NAME_CONSENT_SERVICE_NAME = "myAllowUserNamesConsentService";
/**
* Uses the CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE pointcut to map the <code>fixedPolicy</code> property
* to a custom <code>IConsentService</code> implementations.
* @param theFixedPolicyRequest {@link ConsentFixedPolicyRequest#getPolicyName()} contains the name of the consent
* service that should be mapped (<code>myDefaultAllowConsentService</code>)
* @param theUserSessionDetails - the user session details.
* @return an IConsentService that will be used to supply a <code>fixedPolicy</code>
*/
@CdrHook(CdrPointcut.CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE)
public IConsentService buildConsentService(
ConsentFixedPolicyRequest theFixedPolicyRequest, UserSessionDetailsJson theUserSessionDetails) {
if (MY_ALLOW_USER_NAME_CONSENT_SERVICE_NAME.equals(theFixedPolicyRequest.getPolicyName())) {
return new MyAllowUserNamesConsentService(theUserSessionDetails);
}
return null;
}
/**
* The implementation of IConsentService that will be used for the <code>fixedPolicy</code>
*/
static class MyAllowUserNamesConsentService implements IConsentService {
private static final List<String> SPECIAL_ADMINS = List.of("ADMIN_1", "ADMIN_2", "ADMIN_3");
private final UserSessionDetailsJson myUserSessionDetailsJson;
public MyAllowUserNamesConsentService(UserSessionDetailsJson theUserSessionDetailsJson) {
myUserSessionDetailsJson = theUserSessionDetailsJson;
}
@Override
public ConsentOutcome canSeeResource(
RequestDetails theRequestDetails,
IBaseResource theResource,
IConsentContextServices theContextServices) {
if (isSpecialAdmin()) {
return ConsentOutcome.AUTHORIZED;
}
return ConsentOutcome.PROCEED;
}
private boolean isSpecialAdmin() {
return SPECIAL_ADMINS.contains(myUserSessionDetailsJson.getUsername());
}
}
}
The diagram below shows what a request could look like using the sample JSON configuration:
In order to apply the rules configured in the Consent Module to bulk export requests (/$export
) the register_with_persistence property must be enabled, and a persistence dependency must be selected.
NOTE: When the register_with_persistence
property is enabled, the rules configured in the Consent Module configuration will apply to all FHIR Endpoints that use the specified persistence dependency.
The resources used to configure the Consent Service for a single request. These are the search results for the Consent Fetch Queries.
A FHIR repository that contains clinical data (e.g. Observation, Condition, etc.) to be protected by Consent resources.
The Patient compartment(s) implicated by the query or Resource.
For example, the query Observation?patient=Patient/1
would implicate the Patient/1
compartment.
Note: Chained queries may implicate many compartments. For example, if patient-1-mdm-id
is a golden resource, then the query
Observation?patient.identifier:mdm=patient-1-mdm-id
may match several patients. In this case, each matched Patient
resource will have its' own compartment.
The id of a resource in the Clinical Repository that will identify the actor of a request for purposes of Consent resolution. Each request should be mapped to an effective Consent.actor (i.e. Organization, Patient, Practitioner, etc.).
Implementers can use the UserSessionDetailsJson
object provided by the CONSENT_FETCH_QUERIES
pointcut to determine the Consent Actor. For example, a custom claim could be added to an OIDC client Access Token
(i.e. Organization/1
) which is mapped to the Consent Actor. Alternatively, the username of the Local Inbound Security User could be used to determine an effective Consent Actor.
Consent buckets are defined by consentRules
that have a consentResourcePolicy
. They consist of a name
and matchUrl
.
After Consent
resources are obtained from the Consent fetch query they will be placed into the
"bucket" with the specified name
if they meet the matchUrl
criteria.
The individual responsible for creating and managing Consent
resources.
The queries used to search for active Consent resources in the Consent Repository for a single request.
For example, this query would find Consent resources for a request on behalf of actor Organization/org-1
that apply to Patient/patient-1
(i.e. Consent?status=active&actor=Organization/org-1&patient=Patient/patient-1
).
Depending on your use of Consent resources, you may need to combine queries:
Consent?status=active&actor:missing=true&patient=Patient/patient-1
will find Consent resources for patient-1 that are not specific to a single actor. E.g. a blanket withdrawal of Consent.Consent?status=active&actor=Organization/org-1&patient:missing=true
will find Consent resources that apply to that actor regardless of the subject Patient.The methods subject to Consent evaluation. The following Consent methods are supported by the Consent Module:
Consent Module | JavaScript API Equivalent | Java API Equivalent |
---|---|---|
startOperation |
consentStartOperation | startOperation |
canSeeResource |
consentCanSeeResource | canSeeResource |
willSeeResource |
consentWillSeeResource | willSeeResource |
The patient id (e.g. Patient/patient-1
) used to search for Consent resources in the Consent Repository (i.e. Consent.patient
).
This may be the Clinical Patient compartment of the resource which Consent rules should apply, or might come from a header, or via some MDM Service. Actual Patient compartments may have a many-to-one relationship to a Consent Patient compartment.
For example, in the query Observation?category=imaging&patient=Patient/patient-1
if Patient/patient-1
is a golden resource,
then there may be multiple Consent Patient compartments (i.e. for each matching Patient).
The FHIR repository that contains Consent resources which mediate access to the Clinical Repository. This may be the same as the Clinical Repository.
Specified by the consentResourcePolicy
property of a Consent Rule. It is the name of the IConsentService
instance that will be created for each of the Consent
resources in a Consent Bucket which will be used to determine a Consent Verdict of a request.
Consent adjudications which may be one of three results: AUTHORIZED
(i.e. allow), PROCEED
(i.e. abstain), and REJECT
(i.e. deny).
These verdicts are defined by the ConsentOperationStatusEnum.
Of the three verdicts, AUTHORIZED
and REJECT
are considered decisive. A PROCEED
verdict is considered indecisive.
Specified by the fixedPolicy
property of a Consent Rule. It is the name of the IConsentService
instance that will be created for each resource in an incoming request which will be used to determine a Consent Verdict.
This is done inside the CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE
pointcut, and gives implementers the flexibility to provide Consent resource objects (IDomainResource
) instead of a String-based Consent Fetch Query that will be applied to an incoming request.