Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/rubenjgarcia/nestjs-abac-app

Attribute Base Access Control Application in Nestjs
https://github.com/rubenjgarcia/nestjs-abac-app

abac nestjs scaffold

Last synced: 1 day ago
JSON representation

Attribute Base Access Control Application in Nestjs

Awesome Lists containing this project

README

        

# Attribute Base Access Control Application in Nestjs

## Description

This application uses [Nest](https://github.com/nestjs/nest) to create an Attribute Base Access Control system for your applications. It's inspired by the [Policies system that AWS uses](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_controlling.html)

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

## How it works

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": "[email protected]",
"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": "[email protected]",
"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`

### Conditions

You can use `conditions` on the `policies`:

```
{
"email": "[email protected]",
"policies": [
{
"name": "FooPolicy",
"effect": "Allow",
"actions": ["User:GetUser"],
"resources": ["*"],
"conditions": { "StringEquals": { "email": "[email protected]" } }
}
]
}
```

This `user` only can call `GET /user/:id` if the `email` of the `user` with that `id` is `[email protected]`

### Groups

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`

### Roles

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`

### Organizations and units

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`

## Events

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](https://docs.nestjs.com/techniques/events)

## Two Factor Authentication

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

## Extending the Application

You can crete your own modules following [the principles described in Nestjs](https://docs.nestjs.com/modules). 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](src/auth/actions/user.actions.ts) that described the operations that your users can do
- Create the handler for that actions that te one you can find in [user.handler](src/auth/handlers/user.handler.ts)
- Update your controller with the `@CheckPolicies` decorator to check your policies. You can find an example in the [user.controller](src/auth/controllers/user.controller.ts)

### Auto generating new modules

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

## Installation

```bash
$ npm install
```

## Running the app

```bash
# development
$ npm run start

# watch mode
$ npm run start:dev

# production mode
$ npm run start:prod
```

## Test

```bash
# unit tests
$ npm run test

# e2e tests
$ npm run test:e2e

# test coverage
$ npm run test:cov
```

## CLI Utils

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

### Organizations command

The CLI has a command called `organizations` that you can use to do things related with organizations

#### Create an organization

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`

### Users command

The CLI has a command called `users` that you can use to do things related with users

#### Create admin user

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 [email protected] bar
```

This will generate an user with email `[email protected]` 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

## TODOs and improvements
- [ ] Cache JWT lookups
- [ ] Prompt and generate only files selected, i.e. controller, service, e2e-test, ...
- [ ] Generate entities files based on a JSON schema