This package provides a factory function that returns a type-safe hasPermission
function for implementing Attribute-Based Access Control (ABAC) in your applications. By defining roles, resources, and actions, you can use this library to enforce precise access control policies.
Install the package using npm:
npm install @anakin-gbit/abac
To integrate ABAC into your application, you must create a configuration file to define your roles, resources, and permissions, then call the factory function createHasPermission
to generate a type-safe hasPermission
function.
Create a configuration file, for example src/lib/abac/index.ts
. In this example, we define an article
resource with two actions, and assign permissions to two roles: user
and admin
.
import { AppliedPermissionsConfig, createHasPermission } from '@anakin-gbit/abac'
// Define the article resource
type Article = { id: string; title: string }
// Define application roles
type ApplicationRoles = 'user' | 'admin'
// Define the authorization subject (e.g., a user object)
type AuthorizationSubject = { id: string; roles: ApplicationRoles[] }
// Define available permissions
type AvailablePermissions = {
article: {
action: 'view' | 'delete'
dataType: Article
}
}
// Define the applied permissions
const APPLIED_PERMISSIONS: AppliedPermissionsConfig<
ApplicationRoles,
AvailablePermissions,
AuthorizationSubject
> = {
admin: {
article: {
view: true,
delete: true,
},
},
user: {
article: {
view: true,
delete: false,
},
},
}
// Generate the hasPermission function
const hasPermission = createHasPermission<
ApplicationRoles,
AvailablePermissions,
AuthorizationSubject
>(APPLIED_PERMISSIONS)
// Export the function for use in your app
export { hasPermission }
Now you can use the hasPermission
function to enforce permissions in your application.
import { hasPermission } from '@/lib/abac'
const appUser = { id: 'abc123', roles: ['user'] }
const article = { id: 'cba321', title: 'My Article' }
console.log('Access:', {
canView: hasPermission(appUser, 'article', 'view', article), // true
canDelete: hasPermission(appUser, 'article', 'delete', article), // false
})
The function ensures type safety by validating the resource
, action
, and data
parameters according to your configuration.
The hasPermission
function is type-safe. If you try to use an invalid resource, action, or data type, TypeScript will produce a compile-time error. For example:
// Compile-time error: 'edit' is not a valid action for 'article'
hasPermission(appUser, 'article', 'edit', article)
// Compile-time error: 'appUser' is not a valid resource
hasPermission(appUser, 'appUser', 'view', appUser)
// Compile-time error: Invalid data type for 'article'
hasPermission(appUser, 'article', 'view', { name: 'Invalid Data' })
The APPLIED_PERMISSIONS
object supports defining dynamic permissions by using functions instead of boolean values for specific actions. These functions are evaluated at runtime and receive two arguments:
subject
: The object representing the entity attempting the action (e.g., a user).data
: The resource being acted upon (e.g., an article, app user, or other entity).This flexibility allows you to implement complex access control logic. Here’s an example:
const APPLIED_PERMISSIONS: AppliedPermissionsConfig<
ApplicationRoles,
AvailablePermissions,
AuthorizationSubject
> = {
user: {
article: {
// Allow users to view articles only if their ID matches a specific condition
view: (user, article) => {
return article.id === user.id // User can view their own articles
},
// Disallow users from deleting any articles
delete: false,
},
},
admin: {
article: {
// Admins have blanket permissions to view and delete
view: true,
delete: true,
},
},
}
In this example, the view
action for the article
resource is evaluated dynamically for the user
role. The function checks if the user is allowed to view the article based on the user’s ID and the article’s ID.
You can define more complex logic using any fields or properties available in the subject
or data
objects, making this library highly adaptable to various business rules.
The package exports the following:
createHasPermission
: A factory function to generate a hasPermission
function.AppliedPermissionsConfig
: A helper type for defining your permissions object.