This document summarizes how access control works in FOCA, and how it can be configured for your needs.
This feature is designed to allow you to create more secure applications. You may need to restrict the API usage on the basis of specific users or perhaps create user groups with access to specific functionalities. For example, user A should be allowed to read a resources, while user B should also be able to modify/write to that resource. User C, on the other hand, should not be able to access that resource at all!
To address this and similar use cases, FOCA provides configurable access control based on the popular Casbin project.
The access control model is abstracted into a configuration file based on the PERM (Policy, Effect, Request, Matchers) metamodel. You can provide the required model definition as per your particular use case. Policies can then be defined on the basis of that model, stored in a MongoDB database and enforced on incoming requests based on the matchers and effects defined in the policies.
The flow described above is highlighted in the schema below (taken from Casbin):
The PERM model is composed of four foundations - Policy, Effect, Request, Matchers - describing the relationship between resources and users.
A policy defines who can do what or who has what permissions.
The basic syntax for a policy is
p = sub, obj, act, eft
which can be read as: Who(sub
) can/cannot(eft
) do what(act
) on some
resource(obj
)?
An effect can be understood as a model in which a logical combination judgment is performed on the result of a matcher. For example:
e = some(where(p.eft == allow))
This statement expressed that if the matching strategy result p.eft
has the
result of (some) allow
, then the final result is True
and access is
granted.
Here eft
can be either allow
or deny
. If it is not included (which is
frequently the case), the default value is allow
.
In the above diagram, as per the defined policy:
- John has permission to read
RECORD1
- John has no permission to modify/write to
RECORD1
- Harry has permission to read
RECORD1
- Harry has permission to modify/write to
RECORD1
A request defines the names and order of parameters to be passed to the matchers. A basic request is a tuple object, requiring at least a subject (accessed entity), object (accessed resource) and action (access method).
For instance, a request definition may look like this:
r = sub , obj, act
In the above diagram, as per the incoming request:
- John wants to read
RECORD1
- John wants to modify/write to
RECORD1
A matcher integrates the request (r
) and policy (p
). For example:
m = r.sub == p.sub && r.act == p.act && r.obj == p.obj
This simple and common matching rule means that if the requested parameters
(entities, resources, and methods) are equal, that is, if they can be found in
the policy, then the policy result (p.eft
) is returned.
You can tweak the default access control behavior by setting a number of configuration parameters:
security:
access_control:
model: access_control_model_definition
api_specs: 'path/to/your/access/control/specs'
api_controllers: 'path/to/your/access/control/spec/controllers'
api_route: '/path/to/access_control_api'
db_name: access_control_db_name
collection_name: access_control_collection_name
owner_headers: admin_identification_properties
user_headers: user_identification_properties
The application created with this config would provide an access control model
model
. Corresponding permissions could be accessed and altered by a user with admin permissions via the dedicated endpoints defined in theapi_specs
, operationalized by the controllers inapi_controllers
and hosted atapi_route
. Permissions will be stored in collectioncollection_name
of a dedicated MongoDB databasedb_name
. The headersowner_headers
anduser_headers
would be set for admins and regular users, respectively.Cf. the API model for further options and details.
FOCA sets up a MongoDB database and collection to manage permission resources.
Default names are set to access_control_db
and permission_rules
,
respectively. To manually set the names, provide values for the db_name
and
collection_name
parameters, respectively.
FOCA comes with a default API for configuring permission resources. However,
you can provide a custom Swagger 2.x or OpenAPI 3.x definition
for /permissions
endpoints via api_specs
, provide a module containing
custom controllers for the defined endpoints via the api_controllers
parameter and tell FOCA where to host the endpoints via api_route
.
The specs and controllers used by default can be accessed via the links below:
Access control works on the basis of model definitions. If a custom model
definition is not provided via parameter model
, a role-based access control
(RBAC) model definition will be used by default. To learn more
on writing your own custom models, refer to the Casbin
documentation.
For access control to work, we must provide specific properties for every
request. These are used to validate the incoming request and to differentiate
users and owners/admins. You can set up owner_headers
and user_headers
to
specify custom owner and user properties, respectively.
Once your app is up and running, you can explore the access control API endpoints via a Swagger UI in your browser, e.g.:
firefox http://<host>/admin/access-control/ui/ # or use your browser of choice
The exact route at which endpoints are served depends on the value of
AccessControlConfig.api_route
.