Skip to content

Commit

Permalink
Merge pull request #245 from permitio/daniel/healthcare.revamp
Browse files Browse the repository at this point in the history
New detailed version of GHC
  • Loading branch information
danielbass37 authored Feb 23, 2024
2 parents 675c345 + 4784755 commit 9de0f60
Showing 1 changed file with 257 additions and 10 deletions.
267 changes: 257 additions & 10 deletions docs/modeling/rebac-GHC.mdx
Original file line number Diff line number Diff line change
@@ -1,19 +1,266 @@
---
sidebar_position: 2
title: ReBAC - Health records Example
title: ReBAC - Demo Healthcare App
---

:::info Early Access Feature
**[ReBAC](https://en.wikipedia.org/wiki/Relationship-based_access_control)** (relationship based access control) is now in early access.   this is a production ready feature, but API's are still subject to change, and performance upgrades will be added. **[Contact us](https://bit.ly/permit-slack)** for more information.
## 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:

- **[RBAC](https://docs.permit.io/category/rbac)**
- **[ABAC](https://docs.permit.io/category/abac)**
- **[ReBAC](https://docs.permit.io/category/rebac)**

:::note
A highly detailed explanation and walkthrough of this application is available in [this blog](https://www.permit.io/blog/building-healthcare-authorization-nextjs).
The Git repository for this demo application [is available here](https://github.com/permitio/Galactic-Health-Corporation).
:::

### 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](https://nodejs.org/en/download) 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](https://docs.docker.com/engine/install/).

3. Clerk Account -
GHC uses [Clerk](http://clerk.com/) 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](http://app.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
```

2. 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
```
3. 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.

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

5. Run `npm install` to install the application dependencies.

6. 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:

| Resource | Actions | Relationships | Resource Roles | Derived Roles | Description |
| ----------------------- | ------------ | ------------------------------------------------ | ------------------------------------------- | ----------------------------------------- | ------------------------------------------------ |
| Member | Write, Read | Parent of: Medical Records, Health Plan, Profile | - Owner (read, write) resources. | - Caregiver (read) | A root entity for all member-related |
| Profile | Write, Read | Child of Member, | - Owner (read, write) | Member:Caregiver, Member Group:Org Member | A member profile. |
| Health Plan | Write, Read | Child of Member | - Owner (read, write) | Member:Caregiver | A member’s health plan. |
| Medical Records | Write, Read | Child of Member | - Owner (read, write) | Member:Caregiver | A member’s medical records. |
| Member Group | List, Assign | | - Admin (list, assign), - Org member (list) | | A member group. |
| New feature pilot group | View | | Pilot 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:

| Endpoint | Description | Roles | Derived Roles |
| ----------------------------------------------- | ---------------------------------------------- | --------------------------- | --------------------------------------------------------------------- |
| `GET /account/dashboard/profile/{user}` | Get the (current) user's details. | `Profile:Caregiver` | `Member:Owner#Profile`<br/>`Member Group:Org Member#Profile` |
| `GET /account/dashboard/health-plan/{user}` | Get the (current) user's health plan. | `Health Plan:Caregiver` | `Member:Owner#Health Plan`<br/>`Member:Caregiver#Health Plan` |
| `GET /account/dashboard/medical-records/{user}` | Get the (current) user's medical records. | `Medical Records:Caregiver` | `Member:Owner#Medical Records`<br/>`Member:Caregiver#Medical Records` |
| `GET /account/member` | Get all the members from all the member groups | `Member Group:Org Member` | |
| `GET /account/caregiver` | Get all the user's caregivers | `Member:Owner` | |
| `POST /account/caregiver` | Add a new caregiver to the user | `Member:Owner` | |
| `DELETE /account/caregiver` | Remove a caregiver from the user | `Member: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: `[email protected]`, and `[email protected]`. We’ll also add another account for `[email protected]`.

:::note
You can use any email you’d like. To do that, edit the user keys in [Permit.io’s dashboard](https://app.permit.io/user-management).
:::

## Modeling Health Record Policies with ReBAC
2. Log in to the app as `[email protected]`, 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.

3. 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.

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

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

6. 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:

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

The query will be something similar to this:

```js
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.

### 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](https://docs.permit.io/integrations/gitops/github).

### 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.

The [Galactic-Health-Corporation](https://github.com/permitio/Galactic-Health-Corporation) app demonstrates various policy modeling capabilities within Permit.io ; but with the greatest emphasis on ReBAC modeling.
ReBAC is used to assign users roles to their own records, and selectively assign other users a caregiver role on all or some of the records of other users.
The app demonstrates dynamic use of the ReBAC API and UI combined with different combinations of role derivation.
Read the [app's repository Readme](https://github.com/permitio/Galactic-Health-Corporation) to get started.
## Hosted App

### Slide deck
If you'd only like to view the application running, [login with one of the following users here](https://ghc.up.railway.app/) and customize the permissions any way you see fit.

Additional details and highlights are found in this [slide-deck](https://docs.google.com/presentation/d/1eFgxnGw5m8aB71LOUcgv3h6E6IJ-YWRZBqdqfdkagTs/edit?usp=sharing)
| User | Password | Groups |
| ----------------- | --------- | ----------------------- |
| [email protected] | Aa123456! | ricks_org, smith_family |
| [email protected] | Aa123456! | smith_family |
| [email protected] | Aa123456! | ricks_org |
| [email protected] | Aa123456! | |

0 comments on commit 9de0f60

Please sign in to comment.