Skip to main content
Version: 2.0.0

Healthcare Demo Application

Galactic Health Corporation

Galactic Health Corporation (GHC) is a sample application set in the universe of "Rick and Morty," that demonstrates all the common application permission models, in a single healthcare application:

note

A highly detailed explanation and walkthrough of this application is available in this blog. The Git repository for this demo application is available here.

GHC App Key Features:

  • User Roles: GHC accommodates various user types, each assigned with a corresponding role. These include doctors, patients, caretakers, and administrators. Each user type has distinct responsibilities and access levels tailored to their role.

  • Patient Management: Patients can access their own health records, medical history, and treatment plans. They can also grant limited access to caregivers or family members as needed.

  • Doctor-Patient Relationships: Doctors can view and manage the medical records of patients under their care. Patient data is only accessible to authorized medical professionals.

  • Attribute-Based Access: Access to certain resources within the application is restricted by using attributes like geographic location, patient age, date scoping, or treatment status - making sure they are only accessible under the right conditions.

  • Feature testing pilot Group: GHC allows the management of user feature testing pilot groups, which allows them to test new application features based on users fitting specific criteria.

  • Delegated Permissions: Users can delegate limited access to their health information to others, such as caregivers, with specific limitations.

Getting Started

Prerequisites

  1. Node.js Environment - You'll need a working Node.js environment installed on your local machine.

  2. Docker Environment - GHC relies on Docker for running the decision point container locally. Make sure you have Docker installed and configured.

  3. Clerk Account - GHC uses Clerk to authenticate users, allowing them to log into the app.

  4. Permit.io Account - GHC leverages Permit.io for managing user permissions. You'll need a Permit.io account to configure and manage access control.

Setting up the application

  1. Clone the repository to your local machine.
git clone https://github.com/permitio/Galactic-Health-Corporation.git
  1. In the root folder, create a file named .env.local and copy the content of .env.example to it.
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="<your clerk publishable key>"
CLERK_SECRET_KEY="<your clerk secret key>"
PERMIT_SDK_KEY="<your permit sdk key>"
PERMIT_PDP_URL=http://localhost:7766
  1. From the Clerk dashboard, go to API Keys, choose Next.js example, and copy the NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY values to the .env.local file.

  2. In the Permit dashboard, go to Connect, and copy the token variable to the PERMIT_SDK_KEY value into the .env.local file.

  3. Run npm install to install the application dependencies.

  4. At this point, we have all the required setup to run the application locally. We have configured the runtime and the keys we need to authenticate and authorize the users.

Configuration Setup

We’ll have to configure the relevant data in Clerk.com and Permit to experiment with authorization and permissions. To do that -

  • Open the terminal in the repository's root folder and run npm run config. This will seed the permissions data into Permit.

  • At this step, have all the relevant resources, actions, and roles configured in Permit.io.

Running the Application

To authorize our users to use the data we configured in Permit, we should run the policy decision point (PDP) locally and run the following docker command to spin up the decision point container:

docker run -it \
-e PDP_API_KEY=<YOUR_PERMIT_API_KEY> \
-p 7766:7000 \
-p 8081:8081 \
permitio/pdp-v2:latest

As the decision point is up and running, open a new terminal window in the repository's root folder and run npm run dev. This will start the application locally, and you can access it at http://localhost:3000.

Permission Models - RBAC and ReBAC

With the application running, let’s take a look at the entities defined within our app:

Entities

  • Resources - A resource is the object we want to manage access to. Each resource can have multiple instances.

  • Actions - The various actions that users can perform on a resource. Each action can be either allowed or denied for each user as defined in the permission model.

  • Role Derevations - ReBAC allows us to derive authorization policies based on existing application-level relationships. Put in the simplest way, permissions can be derived from the Member Profile to the Medical Record.

  • Relationships - These define the link between different resources, allowing us to derive permissions from one resource to another.

  • Resource Roles - Roles that can be assigned to specific resource instances.

The combination of roles, resources, actions, and relationships allows us to define our application’s policy. Let’s go over all of the permissions we want to set up:

Requirements

  • Users can view their own profile details, health plans, and medical records.

  • Users can view the profiles of other users they have a relationship with (for example, family members).

  • Users can delegate permissions to other users to view their health plan and medical records; this delegation is limited to a specific date range.

  • Users can view particular features in the application based on their pilot groups.

Here’s a list of all of the Resources, Actions, Relationships, etc. we set up in this model:

ResourceActionsRelationshipsResource RolesDerived RolesDescription
MemberWrite, ReadParent of: Medical Records, Health Plan, Profile- Owner (read, write) resources.- Caregiver (read)A root entity for all member-related
ProfileWrite, ReadChild of Member,- Owner (read, write)Member:Caregiver, Member Group:Org MemberA member profile.
Health PlanWrite, ReadChild of Member- Owner (read, write)Member:CaregiverA member’s health plan.
Medical RecordsWrite, ReadChild of Member- Owner (read, write)Member:CaregiverA member’s medical records.
Member GroupList, Assign- Admin (list, assign), - Org member (list)A member group.
New feature pilot groupViewPilot group member (general role)A member group that has access to beta features.

API Endpoints

To demonstrate the permissions in the application, we implemented the following API endpoints:

EndpointDescriptionRolesDerived Roles
GET /account/dashboard/profile/{user}Get the (current) user's details.Profile:CaregiverMember:Owner#Profile
Member Group:Org Member#Profile
GET /account/dashboard/health-plan/{user}Get the (current) user's health plan.Health Plan:CaregiverMember:Owner#Health Plan
Member:Caregiver#Health Plan
GET /account/dashboard/medical-records/{user}Get the (current) user's medical records.Medical Records:CaregiverMember:Owner#Medical Records
Member:Caregiver#Medical Records
GET /account/memberGet all the members from all the member groupsMember Group:Org Member
GET /account/caregiverGet all the user's caregiversMember:Owner
POST /account/caregiverAdd a new caregiver to the userMember:Owner
DELETE /account/caregiverRemove a caregiver from the userMember:Owner

Testing the application flow

If you want to run a cloud version of this application, feel free to open Rick and Morty accounts and play with permissions at https://ghc.up.railway.app/ To test the simplest application flow, let's perform the following steps:

  1. Rick and Morty both need to sign up for GHC accounts using their respective email addresses: rick@sanchez.app, and morty@smith.app. We’ll also add another account for bird@person.app.
note

You can use any email you’d like. To do that, edit the user keys in Permit.io’s dashboard.

  1. Log in to the app as rick@sanchez.app, you will notice that Rick’s dashboard only allows him to see his own data. This is because, in GHC, users are granted access to their own information by default.

  2. GHC offers a "Delegate Permissions Wizard," a tool that allows users like Rick to share specific healthcare data with others. Use the wizard to share all the data, and assign Morty as a caregiver.

  3. As you can see, Rick can give access only to their member groups members Morty and Bird Person.

  4. Rick can give Morty access limited to a specific date range, ensuring that Morty can view Rick's data only within that timeframe.

  5. With Morty assigned as a caregiver to Rick, let’s log in to Morty’s account. In the "Shared Access" section, you can see that Morty can now access Rick's health plan and medical records as permitted by Rick. This access is derived from the Member:Caregiver role. Log into Bird Person's account. You will see that he can only access his own healthcare data and doesn't have any caregiving relationships with other users.

Using this simple usage flow, we demonstrate the following ReBAC permissions:

  • Rick's Access: Rick, as a member of GHC, can view all of his own healthcare data, as the Owner role is assigned to him.

  • Morty's Access: Morty, as Rick's caregiver, can see Rick's health plan and medical records, thanks to the Member:Caregiver role assigned to him by Rick.

  • Bird Person's Access: Bird Person can only view his own healthcare data, as he doesn't have any specific relationships with other users.

  • Feature testing pilot group: In Rick's dashboard, there's a special box only visible to the "Feature testing pilot group". This is an example of Role-Based Access Control (RBAC), where Rick, as a member of the Feature testing pilot group role, can access this specific feature. Other users can't see this box.

Now that we have covered the RBAC and ReBAC sections of this GHC’s authorization layer, let’s see how ABAC works in this context.

Permission Models - ABAC

Requirements

The ABAC requirement for our app is to limit the delegation of permissions to a specific date range. For example, Rick can give access to his health plan and medical records to Morty, but only for the next 30 days.

Model

Rick and Morty's relationship determines Morty's instance-level role, so we can't limit the delegation based on the relationship itself. This means we need to add attributes. To implement the ABAC, we will use a date attribute that can define the boundaries to each role assignment. For example, if we assign the Member:Caregiver role to Morty with start_date set to 2024-01-01 and end_date set to 2024-01-31, Morty will be able to view Rick's health plan and medical records only between 2024-01-01 and 2024-01-31.

The result will be an object that looks like this:

{
"{user}": {
"Member:Caregiver:${instance}": {
"start_date": "2024-01-01",
"end_date": "2024-01-31"
}
}
}

The query will be something similar to this:

if (user[permission].start_date <= today && user[permission].end_date >= today) {
return true;
}

Implementation

To implement the ABAC permissions using Permit:

  • Configure a Resource Set based on the condition we defined, and configure it within the Permit UI.

  • Write a custom Rego code that will be combined together with the permissions we already configured in Permit, and will be analyzed by Permit in the PDP.

For the sake of this demo, we will use the second option, as we want to demonstrate the flexibility of the Permit as a solution.

note

You can find the the generated and custom policy code in the following repository - https://github.com/permitio/ghc-demo-policy

Configure GitOps

The way that Permit.io lets you write your own custom policy code is by using the GitOps feature. This feature allows you to use Git-based features such as pull requests, branches, and merge requests to manage your policy configuration. To configure GitOps, follow this guide.

Configure the Policy

In the relevant branch, replace the content of custom/root.rego with the content of the scripts/custom.rego file in the repository.

In the relevant branch, edit the root.rego file so all the conditions will sit on the same allow rule, like this (remember to remove the second allow rule):

allow {
policies.allow
custom.allow
}

Application Flow

To test the ABAC permissions, run the same caregiver delegation flow we did in the ReBAC and RBAC Permissions section, but this time, limit the delegation to a specific date range.

The permissions should be now limited to the defined date range.

Hosted App

If you'd only like to view the application running, login with one of the following users here and customize the permissions any way you see fit.

UserPasswordGroups
rick@sanchez.appAa123456!ricks_org, smith_family
morty@smith.appAa123456!smith_family
bird@person.appAa123456!ricks_org
homer@simpson.appAa123456!