Skip to main content

Roles & Permissions (ABAC)

Roles

Roles are sets of permissions grouped together to represent all the actions a user belonging to that role can perform. By creating a role with a specific set of permissions, you can easily assign this role to users, enabling them to perform all the associated actions. This approach simplifies the management of user permissions, allowing you to assign a role once instead of repeatedly assigning individual permissions to each user.

Permissions

By default, if you are the one who generated the application, you will be an admin user (a user having the admin role), so you have the permissions to perform any actions when it comes to the admin panel, other users can access the admin panel, but the actions that they are able to perform is limited to the permissions that they have.

Permissions include:

  • create
  • read
  • update
  • delete

Non-admin users

As a non-admin user, your interactions with available entities are governed by the roles and permissions assigned to you by an admin. By default, non-admin users do not have any roles or permissions assigned to them. It is the responsibility of the admin to assign the appropriate roles and permissions to each user.

Admins have full control over the assignment of roles and permissions, ensuring that non-admin users can only access the entities they are authorized to interact with.

Permission Creation

In Appasap generated apps, a robust Attribute-Based Access Control System (ABAC) is utilized, offering advanced control over user access and actions. Here's how it works:

Permission Format

Permissions are structured in the following format:

  • To grant full access to an entity, use the wildcard '*':
<action>:<entity_name>:*

This wildcard grants unrestricted access for all actions (read, create, update, and delete) on the specified entity. It simplifies permission management by providing comprehensive access without any restrictions.

  • For more advanced control use a Policy:
<action>:<entity_name>:<policy>
  • <action>: Represents the action that can be performed (e.g., read, create, update, delete).
  • <entity_name>: Denotes the entity on which the action can be performed (e.g., user, post, comment).
  • <policy>: Specifies the policy associated with the permission, defined as a JSON object.

Example

Let's consider an example permission:

read:user:{ "where": { "emailVerified": false }, "select": { "firstName": true, "phoneNumber": true } }
  • Action: read
  • Entity Name: user
  • Policy:
    • where: Specifies conditions that must be met for the permission to apply (e.g., emailVerified: false).
    • select: Determines which fields can be accessed (e.g., firstName, phoneNumber).

Policy Definition

The policy portion of the permission consists of a JSON object where you can define specific criteria or conditions that must be met for the permission to be granted. This allows for fine-grained control over access to resources based on various attributes or properties.

Policies Based on Dynamic Attribute Values

A notable feature allows you to use attribute values dynamically within policies.

Example:

Consider the following example:

read:product:{ "where": { "merchant": "user.id" } }

In this example, the policy dynamically retrieves the id attribute of the current user (user.id) and uses it to filter the products. This means that the user is only allowed to read products associated with their own merchant ID.

Benefits:

  1. Dynamic Filtering: Policies can dynamically adjust based on the attributes of the current user or context.
  2. Fine-Grained Access Control: Allows for precise control over access to resources based on dynamic attributes.
  3. Enhanced Security: Ensures that users only have access to resources that are relevant to them, based on their attributes or roles.

By leveraging dynamic attribute values within policies, you can tailor access control to match the specific requirements and context of your application.

Notes:

  1. Ensure that the policy is not empty and that it is a valid JSON object. Syntax errors are handled but may still impact the intended behavior.
  2. Policies may include only where and select clauses, or both.
  3. where and select clauses can not be empty.
  4. For create and update actions, include all required fields in the select clause.
  5. The where clause is not relevant for create actions and can be ignored.
  6. The select clause is not relevant for delete actions and can be ignored.
  7. By default, users have access to all fields of entities they can access, unless a select clause is specified in permissions.
  8. Multiple permissions on the same entity for the same role are combined. To preserve a specific policy, ensure it is consistent across all permissions of the same action and entity for the same role.

These notes provide important considerations for defining permissions and ensuring proper access control within your application. Paying attention to these details will help maintain security and data integrity across your system.

Where Clause

The where clause in permissions uses Prisma syntax to define conditions for filtering data. This powerful feature allows you to specify precise criteria for accessing entities.

Basic Usage

The where clause is used to filter records based on specific conditions. Here's the basic structure:

"where": {
"field": "value"
}

Examples

  • View Users with Verified Emails

To grant permission to view users who have verified their email addresses:

read:user:{ "where": { "emailVerified": true } }
  • View Users Who Have Orders

To grant permission to view users who have at least one order:

read:user:{ "where": { "orders": { "some": {} } } }
  • View Products Created by the Current User

To grant permission to view products created by the current user, you can use dynamic attribute values:

read:product:{ "where": { "creatorId": "user.id" } }

  • View Posts in a Specific Category

To grant permission to view posts in a specific category (e.g., "technology"):

read:post:{ "where": { "category": "technology" } }
  • View Active Users

To grant permission to view users who are active:

read:user:{ "where": { "status": "active" } }
  • View Orders Placed in the Last 30 Days

To grant permission to view orders placed within the last 30 days:

read:order:{ "where": { "createdAt": { "gte": "2023-04-01T00:00:00.000Z" } } }

Combining Conditions

You can combine multiple conditions using logical operators like AND, OR, and NOT.

View Users Who Are Active and Have Verified Emails

read:user:{ "where": { "AND": [ { "status": "active" }, { "emailVerified": true } ] } }

View Users Who Are Active or Have Verified Emails

read:user:{ "where": { "OR": [ { "status": "active" }, { "emailVerified": true } ] } }

Using Relationships

You can also filter based on related entities.

View Products Belonging to a Specific Merchant

To grant permission to view products belonging to a specific merchant (e.g., with merchantId "123"):

read:product:{ "where": { "merchantId": "123" } }

View Users with Specific Order Details

To grant permission to view users with orders that meet specific criteria (e.g., orders with total greater than $100):

read:user:{ "where": { "orders": { "some": { "total": { "gte": 100 } } } } }

By leveraging the where clause with Prisma syntax, you can create highly specific and dynamic permissions that cater to a wide range of scenarios, enhancing the security and flexibility of your application’s access control system. Refer to Prisma documentation for more details.

Filtering and Sorting (Concepts) | Prisma Documentation

Benefits of ABAC

  • Granular Control: ABAC enables precise control over what users can see and do based on attributes or properties.
  • Flexible Policies: Policies can be dynamically adjusted to accommodate different scenarios or requirements.
  • Enhanced Security: By specifying detailed conditions, sensitive data can be protected and access restricted appropriately.

By leveraging the power of ABAC and defining permissions with detailed policies, you can ensure that your application's access control aligns closely with your security and business requirements.

Continue this documentation to provide more examples and explanations of how permissions can be defined and utilized within your application.

Requesting Permissions

To obtain permissions to create, read, update, or delete resources, follow these steps:

  1. Request Permissions from an Admin:
    • As a user, you need to request the necessary permissions from an admin user.
  2. Admin Assigns Permissions:
    • If the user needs permissions based on a role, the admin should follow these steps:

      Creating a New Role and Assigning Permissions:

      1. Navigate to the Role entity.
      2. Create a new role by entering the desired role name and description.
      3. Navigate to the RolePermission entity.
      4. Assign the necessary permissions to the newly created role.

      Assigning Permissions to a Role:

      1. Navigate to the RolePermission entity.
      2. Create a new entry connecting the desired permissions to the specific role.

      Assigning Role to a User:

      1. Navigate to the RoleUser entity.
      2. Link the user to the newly created role by creating a new entry.

Following these steps ensures that users receive the appropriate permissions in an organized and efficient manner.