Skip to content

Latest commit

 

History

History

anubis-management-api

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Access Control Policy Management

This API provides functionalities to manage Role Base Access Control policies. The policy management part is complemented by Tenant and Service management as supported by FIWARE APIs.

While policies are expressed in a generic way, and as such this means that policies works also for other APIs beyond FIWARE, FIWARE introduced a specific way to support multi-tenancy, and this API complies with FIWARE multi-tenancy model.

A tenant, also named as Fiware-Service, is further segmented into ServicePaths, i.e. hierarchical scoping of the resources part of a given tenant. For a more detailed discussion, you can read the related discussion in FIWARE Orion Context Broker documentation.

This API in short provides a PAP (Policy Administration Point), it does not provide PEP or PDP, it only stores the policies. PEP is provided by Envoy and PDP is provided by OPA.

Currently the policy models is based on W3C web access control spec.

Obviously, compared to other languages, expressive power may be quite limited. This may be extended in the future with some custom functionalities (for example to support ABAC). This feature could leverage a json query languages such as:

Short overview

The API is composed by three main paths:

  • /v1/tenants supporting definition of tenants (FIWARE Services) and paths (FIWARE Service Paths). NOTE: FIWARE Service Paths may be gone with NGSI-LD.

  • /v1/policies supporting definition of web access policies (linked to tenants and service paths). Under the hood, this path also creates and stores information linked to policies:

    • Agents (i.e. user or user groups definitions);

    • Modes (i.e. type of action requested on the resource);

  • /v1/audits providing audit logs, i.e. reports of policies' evaluations.

Current status

Supported features:

  • The codebase allows the creation of tenants (related service paths) and policies.

  • The codebase allows to generate a base translation of policies in acl and rego compatible format (i.e. a data structure that is used as input data for policy evaluation by OPA).

Next steps

The following activities need to be implemented as next steps:

  • Push data for policy evaluation into OPA when a policy is updated (rather that OPA pulling them as it happens now). This client could help: https://pypi.org/project/OPA-python-client/

  • Investigate if we need to provide to OPA access to knowledge available in the IDM provider or define token standard information to be included into the token (which may become quite big so better to think about that).

  • Support any service_path policies (e.g. /* or /#). NOTE: this may be more complex in acl than in rego, since as a matter of fact, notion of service and tenant is hidden to acl itself. While tenant can characterised as acl:Group, service_path is a dimension of the resource.

  • Support any resource policies (e.g. /v2/* ), this in acl may look like: acl:accessToClass [ acl:regex "https://bblfish.solid.example/.*" ];

  • Decide wether using only acl defined access modes, e.g. acl:Write, acl:Read, or allowing also custom ones, e.g. entity:read.

  • Support PATCH for the policy management API (may be complicate for the service paths, in case you change the path since this affects all children path).

  • Allow configuration of db, OPA endpoint, ect.

  • Handle ownership.

  • Support disabling multi-tenancy.

Requirements

  • Python 3.9
  • pipenv
  • A database supported by sqlalchemy

Starts the API (dev mode)

$ pipenv install --dev
$ pipenv shell
$ export DEFAULT_POLICIES_CONFIG_FILE=../config/opa-service/default_policies.ttl
$ uvicorn anubis.main:app --reload

Test the API

$ pytest -rP

Generate UML diagram for data models

$ python generate_uml.py

API documentation

Once the API is running, you can check it at: http://127.0.0.1:8000/docs

API testing

Here are few curl calls that exemplify how the API works:

  1. Let's create a tenant:

    $curl -i -X 'POST' \
      'http://127.0.0.1:8000/v1/tenants/' \
      -H 'accept: */*' \
      -H 'Content-Type: application/json' \
      -d '{
      "name": "EKZ"
    }'
    
    HTTP/1.1 201 Created
    date: Sat, 28 Aug 2021 11:50:51 GMT
    server: uvicorn
    tenant-id: c8a056f9-4c8a-4961-a5f5-2bd61346c4f6
    Transfer-Encoding: chunked

    As you can see the response headers include the id of the newly created tenant.

  2. Let's get the tenant info:

    $curl -X 'GET' \
    'http://127.0.0.1:8000/v1/tenants/4385a69f-6d3d-49ed-b342-848f30297a05' \
    -H 'accept: application/json'
    
    {
      "name":"EKZ",
      "id":"4385a69f-6d3d-49ed-b342-848f30297a05",
      "service_paths":[
        {
          "path":"/",
          "id":"02f071c7-82b4-41ab-895e-2bd28e7386a9",
          "tenant_id":"4385a69f-6d3d-49ed-b342-848f30297a05",
          "parent_id":null,
          "scope":null,
          "children":[]
        }
      ]
    }

    A default service path / is always created.

  3. Let's create a policy for this service path and tenant. We define the permission type using acl modes, in this case we authorise reading the resource /v2/entities/urn:myentity, in tenant EKZ, service path /

    $curl -i -X 'POST' \
    'http://127.0.0.1:8000/v1/policies/' \
    -H 'accept: */*' \
    -H 'fiware-service: EKZ' \
    -H 'fiware-servicepath: /' \
    -H 'Content-Type: application/json' \
    -d '{
    "access_to": "urn:myentity",
    "resource_type": "entity",
    "mode": ["acl:Read"],
    "agent": ["acl:AuthenticatedAgent"]
    }'
    
    HTTP/1.1 201 Created
    date: Sat, 28 Aug 2021 11:59:43 GMT
    server: uvicorn
    policy-id: 5c3ac3b2-ad98-4358-8525-a3f7947170af
    Transfer-Encoding: chunked

    Also in this case the id of the newly create policy is returned.

  4. Let's retrieve the policy:

    $curl -i -X 'GET' \
    'http://127.0.0.1:8000/v1/policies/5c3ac3b2-ad98-4358-8525-a3f7947170af?skip=0&limit=100' \
    -H 'accept: application/json' \
    -H 'fiware-service: EKZ' \
    -H 'fiware-servicepath: /'
    
    HTTP/1.1 200 OK
    date: Sat, 28 Aug 2021 12:01:40 GMT
    server: uvicorn
    content-length: 140
    content-type: application/json
    
    {
      "access_to":"urn:myentity",
      "resource_type":"entity",
      "mode":["acl:Read"],
      "agent":["acl:AuthenticatedAgent"],
      "id":"5c3ac3b2-ad98-4358-8525-a3f7947170af"
    }
  5. Let's retrieve the policy as acl:

    $curl -i -X 'GET' \
    'http://127.0.0.1:8000/v1/policies/5c3ac3b2-ad98-4358-8525-a3f7947170af?skip=0&limit=100' \
    -H 'accept: text/turtle' \
    -H 'fiware-service: EKZ' \
    -H 'fiware-servicepath: /'
    
    HTTP/1.1 200 OK
    date: Sat, 28 Aug 2021 12:02:52 GMT
    server: uvicorn
    content-length: 229
    content-type: text/turtle; charset=utf-8
    
    @prefix acl: <http://www.w3.org/ns/auth/acl#> .
    
    <http:/www.w3.org/ns/auth/5c3ac3b2-ad98-4358-8525-a3f7947170af> acl:accessTo </v2/entities/urn:myentity> ;
        acl:agentClass <acl:AuthenticatedAgent> ;
        acl:mode <acl:Read> .
  6. Let's retrieve the policy as rego data:

    $curl -i -X 'GET' \
    'http://127.0.0.1:8000/v1/policies/5c3ac3b2-ad98-4358-8525-a3f7947170af?skip=0&limit=100' \
    -H 'accept: text/rego' \
    -H 'fiware-service: EKZ' \
    -H 'fiware-servicepath: /'
    
    HTTP/1.1 200 OK
    date: Sat, 28 Aug 2021 12:03:57 GMT
    server: uvicorn
    content-length: 1289
    content-type: text/rego; charset=utf-8
    
    {
    "role_permissions": {
        "AuthenticatedAgent": [
          {
            "action": "acl:Read",
            "resource": "urn:myentity",
            "resource_type": "entity",
            "tenant": "EKZ",
            "service_path": "/"
          }
        ]
      }
    }