Skip to content

bento-platform/bento_authorization_service

Repository files navigation

Bento Authorization Service

Permissions and authorization service for the Bento platform.

Development

TODO

To see interactive documentation while in development mode in a Bento context, go to, e.g., https://bentov2.local/api/authorization/docs.

Testing

To run the tests locally with Docker (highly recommended), execute the provided test Bash script:

./test-docker.bash

This will spin up a containerized instance of Postgres, build a service image, and run the tests. It will also determine coverage and generate an HTML coverage report.

Deployment

The service can be deployed as a container. See the container listing for how this container can be pulled.

See the following example Docker Compose file:

services:
  authorization:
    image: ghcr.io/bento-platform/bento_authorization_service:latest
    depends_on:
      - authorization-db
    environment:
      - DATABASE_URI=postgres://auth_user:auth_password@authorization-db:5432/auth_db
      - OPENID_CONFIG_URL=https://bentov2auth.local/realms/bentov2/.well-known/openid-configuration
    ports:
      - "80:5000"
  authorization-db:
    image: postgres:15
    environment:
      - POSTGRES_USER=auth_user
      - POSTGRES_PASSWORD=auth_password
      - POSTGRES_DB=auth_db
    expose:
      - 5432
    volumes:
      - $PWD/data:/var/lib/postgresql

For more environment variable configuration options see the Config object in config.py.

Usage and API

All permissions endpoint

GET /all_permissions/ - See all Bento permissions

[
  {
    "id": "view:private_portal",
    "verb": "view",
    "noun": "private_portal",
    "min_level_required": "instance",
    "gives": []
  },
  {
    "id": "query:project_level_boolean",
    "verb": "query",
    "noun": "project_level_boolean",
    "min_level_required": "project",
    "gives": []
  },
  {
    "id": "query:dataset_level_boolean",
    "verb": "query",
    "noun": "dataset_level_boolean",
    "min_level_required": "dataset",
    "gives": []
  },
  {
    "id": "query:project_level_counts",
    "verb": "query",
    "noun": "project_level_counts",
    "min_level_required": "project",
    "gives": [
      "query:project_level_boolean"
    ]
  },
  // ...
]

Policy evaluation endpoints

Bearer token Authorization headers should be forwarded alongside a request to the endpoints here. The service will then use the token as the subject for the particular request. If no token is included, the user will be treated as {"anonymous": true}.

POST /policy/evaluate - The main evaluation endpoint

Implementers MUST use either this or the scalar version of this endpoint when making binary authorization decisions, e.g., does User A have the query:data permission for Resource B.

Implementers SHOULD use this when making graceful-fallback policy decisions, via the matrix-based approach and additional logic in the implementers' own code, e.g.:

  • "does User A have the query:data permission for Resource B"?
  • If not, "do they have the query:dataset_level_counts permission for Resource B?"
  • et cetera.
Request example
Headers
Authorization: Bearer ...
Body (JSON)
{
  "resources": [{"project": "project-1"}, {"project": "project-2"}, {"project": "project-3"}],
  "permissions": ["query:data", "query:dataset_level_counts"]
}
Response (JSON)
{
  "result": [
    [false, true],
    [false, false],
    [true, true]
  ]
}

Here, result is a matrix of evaluation results, with rows being resources and columns being permissions.

In this case, the response can be interpreted as:

  • For the provided bearer token:
    • They have the query:dataset_level_counts permission for project-1, but NOT query:data
    • They have none of the queried permissions for project-2
    • They have both of the queried permissions for project-3

POST /policy/evaluate_one - The evaluation endpoint for one resource and one

Equivalent to the above endpoint, but with a request body that looks like:

{
  "resource": {"project": "project-1"},
  "permission": "query:data"
}

... and a response that looks like:

{
  "result": false
}

We added this endpoint to prevent slip-ups when checking just one permission, since if the implementer accidentally checks the falsiness of a list, they'll accidentally grant access incorrectly, since the following holds:

if [[False]]:
    print("this will print")

POST /policy/permissions - a secondary evaluation endpoint

This endpoint lists permissions that apply to a particular token/resource pair.

Implementers MAY use this for graceful-fallback policy decisions (although a multiple-requests approach to the above evaluate endpoint is preferable, since it will log decisions made).

Implementers SHOULD use this endpoint when rendering a user interface in order to selectively disable/hide components which the user does not have the permissions to use.

Request body example (JSON)
{
  "resources": [{"everything": true}]
}
Response (JSON)
{
  "result": [["query:data"]]
}

The result value is returned as a list of lists of permissions; one list of permissions for each resource queried.

Group endpoints

TODO

  • GET /groups
  • POST /groups
  • GET /groups/<id>
  • PUT /groups/<id>
  • DELETE /groups/<id>

Grant endpoints

TODO

  • GET /grants
  • POST /grants
  • GET /grants/<id>
  • DELETE /grants/<id>

Resource permissions cascade

Resource permissions cascade diagram

Copyright & License

© McGill University 2023.

The Bento authorization service is licensed under the terms of the Lesser GNU General Public License, v3.0.

About

Permissions and authorization service for the Bento platform.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages