10.5.1Smile CDR Tutorial - Use the Consent Module to Manage Patient Consent

 

In this tutorial, we'll configure Smile CDR to comply with the CMS-0057-F Consent Requirements for Provider Access.

We'll create two patients "Ollie Open" and "Patty Private" and four providers "Dr. Goody", "Dr. Nicey", "Dr. Baddy", and "Dr. Evil".

Ollie Open has no Consent resources.

Patty Private has four Consent resources:

  • Deny access to all data by default
  • Permit access to data by the organization "Good Org"
  • Permit access to data by the practitioner "Dr. Goody" even if they are not requesting from "Good Org"
  • Deny access to data by the practitioner "Dr. Evil" even though they are requesting from "Good Org"

Here are the outcomes we expect from this configuration:

PatientProviderOrganizationConsent Outcome
OllieanyanyAllowed
PattyDr. NiceyGood OrgAllowed
PattyDr. BaddyBad OrgDenied
PattyDr. GoodyBad OrgAllowed
PattyDr. EvilGood OrgDenied

1. Install Smile CDR

Install Smile CDR either from a tarball or using Docker.

2. Build and Install the Demo Consent Interceptor

Download and unzip the cdr-consent-demoproject using one of the links below.

Now build the project and install the interceptor jar file in your smilecdr/customerlib directory.

cd cdr-consent-demoproject
mvn clean install
target/cdr-consent-demoproject-*.jar path/to/smilecdr/customerlib

3. Enable Consent Logging

Edit smilecdr/customerlib/logback-smile-custom.xml and uncomment the last line to enable consent logging.

	<!-- Consent Troubleshooting Log -->
	<logger name="ca.cdr.log.consent_troubleshooting" level="DEBUG"/>

This will help us see how consent is being evaluated.

4. Start Smile CDR

Start Smile CDR by running the following command:

$ bin/smilecdr run

5. Access the Web Admin Console

Access the Web Admin Console by navigating to the following URL in your web browser: http://localhost:9100

Log in with the default credentials "admin", "password".

6. Install an OpenID Connect Client

Save the following JSON to a file called oidc-client.json:

{
  "nodeId" : "Master",
  "moduleId" : "smart_auth",
  "clientId" : "consentdemo",
  "clientName" : "Consent Demo",
  "enabled" : true,
  "accessTokenValiditySeconds" : 3600,
  "allowedGrantTypes" : [ "AUTHORIZATION_CODE", "IMPLICIT", "REFRESH_TOKEN", "CLIENT_CREDENTIALS", "PASSWORD", "JWT_BEARER" ],
  "alwaysRequireApproval" : false,
  "attestationAccepted" : true,
  "canIntrospectAnyTokens" : false,
  "canIntrospectOwnTokens" : false,
  "canReissueTokens" : true,
  "clientSecrets" : [ ],
  "createdByAppSphere" : false,
  "fixedScope" : false,
  "jwksUrl" : "",
  "publicJwks" : "",
  "refreshTokenValiditySeconds" : 86400,
  "registeredRedirectUris" : [ "http://localhost:3000/callback", "http://localhost:3001/callback" ],
  "rememberApprovedScopes" : false,
  "scopes" : [ "online_access", "openid", "patient/*.read", "patient/*.write", "cdr_fhir_delete" ],
  "secretClientCanChange" : false,
  "secretRequired" : false
}

Navigate to Users & Authorization OpenID Connect Clients.

Click Choose File and select the oidc-client.json file you created.

Click Import.

7. Give the ANONYMOUS user FHIR_CAPABILITIES permissions

Navigate to Users & Authorization User Management.

Beside the ANONYMOUS user, click on Edit.

Search for the FHIR_CAPABILITIES permission and enable it.

Click Save User.

8. Create 3 demo Users

We will create 3 users to test the consent module.

Navigate to Users & Authorization User Management.

Click Add User.

Create users with the following details:

UsernameFamily NameGiven NamePasswordLocation Launch ContextPractitioner Launch Context
drgoodyGoodyDrPassword123Organization/bad-orgPractitioner/dr-goody
drniceyNiceyDrPassword123Organization/good-orgPractitioner/dr-nicey
drevilEvilDrPassword123Organization/good-orgPractitioner/dr-evil
drbaddyBaddyDrPassword123Organization/bad-orgPractitioner/dr-baddy

Give all three users both ROLE_FHIR_CLIENT and FHIR_ALL_READ permissions.

Note in a real system, the launch context would be set by the IDP (Identity Provider). But to simplify things for this demo, we'll set the launch context directly on the user.

9. Add a Consent Module

Navigate to Configuration Module Config.

Select Consent from the dropdown menu and click Add.

In the FHIR Interceptors section, set Interceptor Bean Types to com.smilecdr.consent.DemoHooks. This is the name of the class that we built and installed in step 2 above.

In the Consent section, set Bucket Definition (Text) to the following:

{
	"canSeeResource": {
		"consentServiceFactory": "smileDefaultConsentServiceR4",
		"consentRules": [
			{ "name": "PRACTITIONER", "matching": [  { "matchUrl": "Consent?category=INFA" } ]},
			{ "name": "ORGANIZATION", "matching": [  { "matchUrl": "Consent?category=IDSCL" } ] },
			{ "name": "ALL", "matching": [  { "matchUrl": "Consent?category=59284-0" } ] }
		],
		"fallbackConsentRule": "AUTHORIZED"
	}
}

This demo uses 3 types of Consent resource categories to manage the 3 different levels of consent: all, organization, practitioner. For the demo, we arbitrarily chose 3 category codes from the list of R4 Consent Category Codes so to distinguish between these three kinds of Consent resources. Your system may choose a different approach to differentiate between these different kinds of Consent resources. Note the order of these rules is important, since ORGANIZATION consent needs to override ALL consent, and PRACTITIONER consent needs to override ORGANIZATION consent.

In the Dependencies section, set FHIR Storage Module (any FHIR version) to persistence (FHIR Storage (R4 RDBMS)).

Click Create Module.

Click Start to start the Consent Module.

10. Enable OIDC Authentication and Consent on the FHIR Endpoint

Navigate to Configuration Module Config.

Click on fhir_endpont on the left-hand side.

In the Auth: OpenID Connect section, enable OpenID Connect Security.

In the Dependencies section at the bottom:

  • Set the The Consent Module dependency to consent (Consent).
  • Set the OpenID Connect Authentication dependency to smart_auth (SMART Outbound Security).

Click Save Config.

Click Restart to restart the FHIR Endpoint.

11. Enable New Session for Each Flow and CORS on the SMART Outbound Security Endpoint

Navigate to Configuration Module Config.

Click on smart_auth on the left-hand side.

In the OpenID Connect (OIDD) section, enable New Session for Each Flow.

In the Cross-Origin Resource Sharing (CORS) section, enable CORS Enabled.

Click Save Config.

Click Restart to restart the SMART Outbound Security Endpoint.

12. Load the test data

Using a REST client such as Bruno or Postman, POST a transaction to the FHIR Endpoint. Use Basic Auth with credentials 'admin', 'password'. http://localhost:8000/

Use this Consent Test Bundle as the body of the POST.

It should return a 200 OK HTTP response code with a copy of the Bundle you posted.

This bundle contains the following resources:

  • 2 Organization resources: good-org, bad-org
  • 4 Practitioner resources: Dr. Goody, Dr. Nicey, Dr. Baddy, Dr. Evil
  • 2 Patient resources: ollie-open, patty-private
  • 8 Observation resources: 4 for each patient

**13. Try accessing data without any Consent resources **

This demo ships with two applications: a Patient View app and a Consent Management app both located in the zip file you downloaded in the folder src/main/frontend.

Start the Patient View app.

cd cdr-consent-demoproject-*/src/main/frontend/patient-viewer-demo
npm install
npm run dev

It should return with a message that includes something like the following:

   - Local:        http://localhost:3001

 ✓ Starting...
 ✓ Ready in 718ms

Navigate to the Patient View application at http://localhost:3001.

Click Login with SMART

Use "drevil" "Password123" as the credentials. If you run into a problem at this point, see "Troubleshooting" below.

  • In the search box, type pat and click Search Patients.
  • Click on Patty Private.
  • You should see a list of Observations for Patty Private.
  • Click Logout.
  • Stop the Patient View app. (Ctrl-C)

Now we know what it looks like when Dr Evil can see Patty's data, let's add some Consent resources to block that access.

14. Create some Consent Resources

Start the Consent Management app.

cd cdr-consent-demoproject-*/src/main/frontend/consent-management-demo
npm install
npm run dev

It should return with a message that includes something like the following:

   - Local:        http://localhost:3000

 ✓ Starting...
 ✓ Ready in 718ms

Navigate to the Consent Demo application at http://localhost:3000.

Click Login with SMART

Use "admin" "password" as the credentials.

Click Authorize to allow the Consent Demo application to access data on the FHIR Endpoint.

We will now create the 4 consent resources for Patty Private described at the beginning of this tutorial.

Type patty in the search box and click Search Patients.

Click on Patty Private.

  • Select Deny All Access and click Create Consent. This will create a consent that denis access to all of Patty Private's data.
  • Select Organization-specific and select Good Org from the dropdown. This will create a consent to permit Good Org to access Patty Private's data.
  • Select Practitioner-specific and select Dr. Goody from the dropdown. This will create a consent to permit Dr. Goody's access to Patty Private's data.
  • Select Practitioner-specific and select Dr. Evil from the dropdown. This will create a consent to permit Dr. Evil access to Patty Private's data.
  • Click Edit beside Dr. Evil's Practitioner-specific consent and change the Access Type to Deny Access.

You should now see 4 Consent resources displayed for Patty Private.

Click Logout.

Shut down the Consent Management app. (Ctrl-C)

**15. Try accessing data with Consent resources **

Start the Patient View app.

cd cdr-consent-demoproject-*/src/main/frontend/patient-viewer-demo
npm run dev

Navigate to the Patient View application at http://localhost:3001.

Click Login with SMART

Use "drevil" "Password123" as the credentials.

  • In the search box, type pat and click Search Patients.
  • Click on Patty Private.
  • You will no longer see the Observations for Patty Private.

Click Logout.

Click Login with SMART

Use "drgoody" "Password123" as the credentials.

  • In the search box, type pat and click Search Patients.
  • Click on Patty Private.
  • You should see a list of Observations for Patty Private.

Try the other combinations of Patient and Provider to see the different outcomes.

16. Troubleshooting

The most likely root cause of a login problem is that you missed a step in the FHIR Endpoint or SMART Outbound Security Endpoint configuration above. Double-check those configurations first.

You can enable security troubleshooting logging on the server as follows:

  • Stop Smilecdr (Ctrl-C)
  • edit customerlib/logback-smile-custom.xml
  • uncomment the security_troubleshooting log as follows:
	<!-- Security Troubleshooting Log : Authentication and Authorization -->
	 <logger name="ca.cdr.log.security_troubleshooting" level="DEBUG"/>
  • Start Smile
  • Try logging in again.