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/login
to login to get the JWT Token - Use the JWT token to call the
POST /auth/validate2FA
endpoint 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
@CheckPolicies
decorator 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:cov
This 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