This application uses Nest to create an Attribute Base Access Control system for your applications. It's inspired by the Policies system that AWS uses
The policies and users are stored in database, in this case in a MongoDB database. You can assign policies to users to give ability to access to resources or create them
In this application you have users which have policies that tell us what kind of actions they can do
The policies are permissions for the API endpoints
Let's assume that we have this user:
{
"email": "foo@example.com",
"policies": [
{
"name": "FooPolicy",
"effect": "Allow",
"actions": ["User:ListUsers"],
"resources": ["*"]
}
]
}
This user can ListUsers and that permission is neccesary to call the GET /users endpoint
You can restrict which resources the users can see:
{
"email": "foo@example.com",
"policies": [
{
"name": "FooPolicy",
"effect": "Allow",
"actions": ["User:UpdateUser"],
"resources": ["000000000001"]
}
]
}
In this case the user can only update the user with id equals to 000000000001
You can use conditions on the policies:
{
"email": "foo@example.com",
"policies": [
{
"name": "FooPolicy",
"effect": "Allow",
"actions": ["User:GetUser"],
"resources": ["*"],
"conditions": { "StringEquals": { "email": "foo@example.com" } }
}
]
}
This user only can call GET /user/:id if the email of the user with that id is foo@example.com
The user can belongs to zero or more groups. If the user belongs to a group it will inherit the policies from that group and will be added to the policies of the user
A role is a way to give users permissions without the need of changing the policies assign to that user. A user can assume a role and the user assumes that role the user can perform the actions that the role has in its policies
When you create a organization a new unit is created with it. One organization can have more than one unit but need to have at least one unit. Every unit can have other units creating the organization tree
Every entity of the application needs to belong to a unit. For example, users or policies belongs to an unit
When you do a query with an user you can only see entities that belongs to the unit of that user
You can use events to implement the observer pattern in the application. For example, when a new user is created you may want to send an email. injecting the EventsService class in your service you can fire events
You can see more about this in the NestJS documentation
To enable 2FA the user must have User:Activate2FA policy
Use the endpoint POST /iam/2FA/generate to generate a QR code to use with some 2FA application like https://github.com/google/google-authenticator o https://authy.com
After setting the application with the QR code the user needs to validate it using the endpoint POST /iam/2FA/validate sending the code of the application
If everything is ok, every time the user wants to login to use the API needs to do it in 2 steps:
- Use the endpoint
POST /auth/loginto login to get the JWT Token - Use the JWT token to call the
POST /auth/validate2FAendpoint sending the token. This endpoint will generate a new JWT token valid to call the endpoints of the API
You can crete your own modules following the principles described in Nestjs. Then you need to implement the ABAC security in the controller
- Create a list of actions like the one you can find in user.actions that described the operations that your users can do
- Create the handler for that actions that te one you can find in user.handler
- Update your controller with the
@CheckPoliciesdecorator to check your policies. You can find an example in the user.controller
First you have to compile the generator tool
npm run build:generator
Now you can use it to generate a new module with all the code neccesary (controller, service, tests, ...)
npm run generate
The schema will be generated without any properties so you have to do it for yourself. As well, you have to create the tests that check the schema and the conditions. You can find these tests searching for TODO in your module tests
$ npm install# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:covThis project has a CLI to do some actions. If you want to use it you have to compile the CLI tool
npm run build:cli
Then you can use with the command npm run cli follow by the command of the CLI you want to use
The CLI has a command called organizations that you can use to do things related with organizations
You can create an organization using the CLI tool. Just use the sub command creat and pass the name that you want to give to the organization. Here is an example:
npm run cli organizations create Foo
This will generate an organization with name Foo. An unit called Main will be created under the organization
The CLI has a command called users that you can use to do things related with users
You can create an admin user using the CLI tool. Just use the sub command create-admin and pass the unit id, email and the password you want. Here is an example:
npm run cli users create-admin 123456789012 foo@example.com bar
This will generate an user with email foo@example.com with password bar. First, it will check if a policy called Administrator is in the database. If there is no policy it will create it with all the permissions. The policy Administrator will be assign to the user created
- Cache JWT lookups
- Prompt and generate only files selected, i.e. controller, service, e2e-test, ...
- Generate entities files based on a JSON schema