Access Control Lists (/ACL)
Access control lists with API constructor
Deprecated feature
In Aidbox you can configure Access control lists using API Constructor.
aidbox.rest.acl provides a set of operations supporting SQL :filters to be added on each request. :filters can be used to restrict access to resources
Examples
Code examples on this page are taken from the ACL and the multitenancy example projects
Overview
Available aidbox.rest/op-engines
Expects the same as regular FHIR API engines and also a :filter
aidbox.rest.acl/searchaidbox.rest.acl/createaidbox.rest.acl/readaidbox.rest.acl/updateaidbox.rest.acl/conditional-updateaidbox.rest.acl/deleteaidbox.rest.acl/conditional-deleteaidbox.rest.acl/create-with-filter-table-insert— create resource and create entry in filter tableaidbox.rest.acl/patient-level-bulk-exportaidbox.rest.acl/group-level-bulk-export
Example
search-observation
{:zen/tags #{aidbox.rest/op}
:engine aidbox.rest.acl/search
:resource "Observation"
:format "fhir"
:filter observation-filter}
Filter
An ACL operation requires :filter to be specified. A filter requires to define :expression which will be added to a SQL formed by the operation. :expression is made of templates joined with :and or :or operators. A filter optionally accepts :filter-table
Example
observation-filter
{:zen/tags #{aidbox.rest.acl/filter}
:filter-table acl-box.acl/acl-table
:expression [:and acl-box.acl/user-condition
acl-box.acl/subject-conditon]}
Filter table insert
aidbox.rest.acl/create-with-filter-table-insert engine requires :filter-table-insert property which links operation with the schema tagged with aidbox.rest.acl/filter-table-insert.
insert-into-filter-table schema has the following keys:
engine: currently onlyaidbox.rest.acl/filter-table-insert-row-sqlis supportedfilter-table: zen symbol defining filter tableparams: sql parameters. See Parameter section.values: values to insert in row. This property value is a map in which keys are column names and values are sql substrings for values.
Example
insert-into-filter-table
{:zen/tags #{aidbox.rest.acl/filter-table-insert}
:engine aidbox.rest.acl/filter-table-insert-row-sql
:filter-table acl-box.acl/acl-table
:params {:user-id acl-box.acl/user-id-param}
:values {:id "gen_random_uuid()"
:txid "nextval('transaction_id_seq'::text)"
:status "'created'"
:resource "jsonb_build_object('patient', jsonb_build_object('resourceType', 'Patient',
'id', {{target-id}}::text),
'user', jsonb_build_object('resourceType', 'User',
'id', {{params.user-id}}::text))"}}
Filter table
Filter table defines SQL table to be joined or searched in with SQL templates.
Example
acl-table
{:zen/tags #{aidbox.rest.acl/filter-table}
:schema "public" ;; Custom resource table acl-box.custom-resources/PatientAccess
:name "patientaccess"}
Template
Defines SQL template string. Accepts params. In the template string you can refer to variables with {{<var>}} syntax. Available variables:
paramscan be referred with{{params.<path>.<to>.<param>}}syntax.{{filter-table}}is the:filter-tableadded to thefilter{{target-resource}}is the jsonb of a resource being checked{{target-id}}is the id of the resource
Example
user-condition
{:zen/tags #{aidbox.rest.acl/sql-template}
:params {:user-id user-id-param}
:template "{{filter-table}}.resource#>>'{user, id}' = {{params.user-id}}"}
subject-conditon
{:zen/tags #{aidbox.rest.acl/sql-template}
:template "{{target-resource}}#>>'{subject, id}' = {{filter-table}}.resource#>>'{patient, id}'"}
id-conditon
{:zen/tags #{aidbox.rest.acl/sql-template}
:template "{{target-id}} = {{filter-table}}.resource#>>'{patient, id}'"}
Parameter
Defines a path in a request where to get data. The data can be used in a SQL template
Example
user-id-param
{:zen/tags #{aidbox.rest.acl/request-param}
:source-schema {:type zen/string}
:path [:user :id]}
Conditional CRUD
By default, aidbox.rest.acl/create, aidbox.rest.acl/conditional-update, aidbox.rest.acl/conditional-delete engines don't make ACL checks on underlying searches. That can lead to "multiple matches" error even when a user doesn't have access to some resources. Such behavior could be overwritten by acl-checks-on-search? parameter.
Example
observation-conditional-delete
{:zen/tags #{aidbox.rest/op}
:engine aidbox.rest.acl/conditional-delete
:resource "Observation"
:format "fhir"
:filter observation-filter
:acl-checks-on-search? true}