HarperDB comes with built-in Basic and JWT authentication, and Role-Based Access-Control (RBAC) model for authorization. The granular permission model allows for a higher degree of security as permissions can be assigned to different users either at the table or attribute level.
In this two-part series, we will see how to secure access to HarperDB by creating custom users and roles. In the first article, we will do a deep dive into HarperDB’s RBAC model. We will then integrate with an external provider in Part II via Custom Functions to create a full authentication and authorization system.
HarperDB Setup
Before we begin, we need to provision a HarperDB instance. The easiest way to get started is to deploy a managed AWS instance via HarperDB Studio. Follow the instructions on “Deploying HarperDB on AWS and GCP” to create a free instance.
NOTE: local instance of HarperDB has limitations that restrict the number of roles to two (super_user and cluster_user). Deleting any of these roles to create a custom role causes issues. If you wish to use a local instance, make sure to register the database via HarperDB Studio.
Once you have a running instance, let’s create a `dev` schema and a `dog` table:
HarperDB Roles
HarperDB ships with three built-in roles:
- Super_user: admin role with full access to all operations
- Cluster_user: internal role to allow clustering of databases
- Structure_user: role that allows for the creation and deletion of data (e.g., creation of schemas and tables)
In addition to these built-in roles, we can create custom roles. Role permissions for CRUD operations can be defined at table-level or at the attribute-level. If the permissions for attributes are not set, table-level permissions will be assumed.
Creating a Custom Role
So without further ado, let’s create some custom roles. We will create a `developer` role with read and write access to the dog table. We will also create a `restricted` role with only insert permissions for the owner_name attribute.
First, here’s the command to create the `developer` role:
Note that the `attribute_permissions` is an empty array, meaning that it will inherit table-level permissions. Here the developer role has access to read, insert, and update in the dog table, but cannot delete.
Next, we have the `restricted` role:
Associating Roles to Users
Now that we have our custom roles defined, we need to create custom users. We can invoke the `add_user` operation with username, password define as well as the associated role.
Let’s create a `developer` user that assumes the `developer` role:
Likewise, create the restricted_user:
Testing Roles
Now we can test if our roles are working. Let’s insert a record to the `dog` table as `developer` user:
We should see a successful message:
{"message":"inserted 1 of 1 records","inserted_hashes":[1],"skipped_hashes":[]}
We can also read from the table:
We should see a JSON output with the same data that we inserted.
Now, if we try to insert as the restricted user, we will see failures:
{
"error": "This operation is not authorized due to role restrictions and/or invalid schema items",
"unauthorized_access": [],
"invalid_schema_items": [
"Attribute 'dog_name' does not exist on 'dev.dog'",
"Attribute 'breed_id' does not exist on 'dev.dog'",
"Attribute 'age' does not exist on 'dev.dog'",
"Attribute 'weight_lbs' does not exist on 'dev.dog'"
]
}
The error message shows that we are not authorized to insert. This is because we only have insert permissions to the `owner_name` attribute and not the others. HarperDB’s RBAC model, when defined at the attribute-level, is useful for granular permissions either for security or compliance measures.
Next Steps
In Part I of this series, we saw how the RBAC model works in HarperDB. We created some custom roles and tied it to custom users. In the next article, we will extend this to integrate with external auth providers to offload authentication and restrict various endpoints per role.