Skip to content

Commit

Permalink
udpate authorization specs with fidning from this past week's research
Browse files Browse the repository at this point in the history
  • Loading branch information
dpgraham4401 committed Jul 10, 2024
1 parent b8add81 commit 6c25e1a
Showing 1 changed file with 28 additions and 41 deletions.
69 changes: 28 additions & 41 deletions docs/guide/src/design/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,63 +6,50 @@ see the [Django documentation](https://docs.djangoproject.com/en/5.0/topics/auth

## Authentication

This open source project tries to keep the authentication system simple.
This project uses what's provided Django's built-in authentication system, as well as the Django Rest Framework.
This project makes use of Django's built-in authentication system `django.contrib.auth` and the
packages in the Django ecosystem (e.g., `django-allauth`) to authenticate users.

We do not rely on external authentication services for this project to keep the project focused,
avoid condoning a third-party service (as the U.S. government). This also provides an
opportunity to demonstrate how systems can implement auth to use features of the e-Manifest system
such as the Remote Signer policy and generally allowing their internal users electronically manifest
without having an account in the US EPA's RCRAInfo/e-Manifest system.

## Authorization

Authorization, for this project, requires a complex set of permissions to be implemented.
The requirements for granting access to a resources (e.g., a manifest) are determined on
a per-user, per-role, per-object, per-object status basis.
Authorization is relatively complex for this project. Access to a resources (e.g., a manifest)
is a dynamic process and needs to be determined on a per-user + per-role +
per-object + per-object status basis.

As an example scenario, a user wants to edit a manifest. The following applies:

1. The user must be authenticated.
2. The user must have access to a site listed on the manifest.
3. The user must have the appropriate role to edit the manifest, for the site.
3. The user must have the appropriate role/permission to edit the manifest.
4. The manifest must be in a status that allows editing.
5. The specific edits must be allowed by e-Manifest.

Therefore, determining whether a user has access is a dynamic process. In addition, the permissions

## Specification

The system must:

1. Define a `Site` model that represents one of the client's sites/locations.
The site has a one-to-one relationship with a `RcraSite` model.
2. Define an `Organization` model that represents a client's organization. The organization
has a one-to-many relationship with the `Site` model.
3. Define a `User` model that represents a user.
4. Define a `UserRole` model that represents a role that a user can have for a site or organization.
A user can have multiple user roles. A user role has a one-to-one relationship with a `Role` model.
5. Define a `Role` model that represents the function/job/actions that a user has. A role has a one-to-many
relationship with a `Permission` model.
6. Define a `Permission` model that represents the actions that a user can perform for resources
(e.g., a manifest) associated with a site or organization.

### Django Implementation Notes

The requirements for this system's authorization systems are relatively complex, they require
object-level permissions, knowledge of a resource hierarchy (a site has manifests, you cannot
edit another site's manifest), and dynamic permissions (e.g., a manifest can only be edited
depending on the status)
### Python/Django Implementation Notes

Here's where things get tricky. The Django framework ships with a built-in authentication
and authorization system. The components of this built in system are found
The Django framework ships with a built-in authentication and authorization system.
The components of this built in system are found
under the `django.contrib.auth` package. Leveraging the built-in system would allow us to
take advantage of the many features that Django (such as the admin interface) provides and would
ensure that we are using a well-tested, battle-hardened system.

### Multi-Tenancy
However, to quote
[Customizing Django Authentication docs](https://docs.djangoproject.com/en/stable/topics/auth/customizing/#handling-object-permissions),

Pros:
> Django’s permission framework has a foundation for object permissions, though there is no implementation for it in the
> core. That means that checking for object permissions will always return False or an empty list (depending on the
> check performed). An authentication backend will receive the keyword parameters obj and user_obj for each object
> related authorization method and can return the object level permission as appropriate.
1. efficiency: the system would be able to handle multiple clients from a limited number of deployments
2. scalability: the system would be able to scale in and out to handle increase load from multiple clients
3. cost: the system would be able to handle multiple clients from a single deployment, reducing costs
Object level permissions is a required feature for this project. There are 2 noteworthy packages
that aim to provide object level permissions:

Cons:
1. [django-guardian](https://django-guardian.readthedocs.io/en/stable/)
2. [django-rules](https://github.com/dfunckt/django-rules)

1. Security: the system would need to be designed to ensure that one client's data is not accessible by another client
2. Complexity: the system would need to be designed to handle multiple clients, which would
increase the complexity of the system, in particular the authorization system.
As of this writing, the django-guardian package is mature, and widely used. However, it is not actively maintained.
The django-rules package is actively maintained, but it is not as widely used as django-guardian.

0 comments on commit 6c25e1a

Please sign in to comment.