Overview
In order to create rich client business applications, it is critical to address the data security requirements.
Security is about controlling who can do what. In other words, it is basically about controlling who can write data, who can read data, and who can delete data. It might be necessary to have such kind of control at the level of the whole document or at the level of specific fields within a document. In order to achieve that, security rules need to be defined.
Security rules might change after creation time to reflect the fact that different people, than those who created the document, are required to update a document. Hence, these security rules would need to be somehow persisted with the data. Again, these rules can be enforced in the business logic layer of the rich client application, but this would not be reliable enough since a malicious client can always tamper with the business logic and send undesired security rules to the Apstrata database service. This points out the need to be able to enforce security rules on the server side. This can also be done using schemas and/or scripting.
When querying data, we can specify what fields to return (the selection criteria) as well as what documents to return (the query conditions or predicates). It is important to have control at both levels. For example, querying for the names of customers in a certain region should return empty data set not only if the user does not have read access to the customer name field, but also if the user does not have read access to the customer region field. Otherwise, users will always be able to detect the existence of data to which they do not have access.
Introducing ACLs
Some security rules can be defined in the schema itself in a declarative way. Security rules are defined per group of fields. In Apstrata, a security rule is specified as an access control list (ACL). In general, we have three types of ACLs: read ACL, write ACL, and delete ACL. The read and write ACLs are defined per fields group whereas the delete ACL is defined per document.
As for dynamic fields which are not specified in the schema, you can also define read and write ACLs for them. These ACLs are referred to as default ACLs as opposed to fields group ACLs.
An ACL contains one or more elements, where each element is either a user or a group of users. A group entry in the ACL should be prefixed with the term "group:" in order to differentiate it from a user.
Example of a read ACL:
<read>group:Admins; user1; user2; group:Managers</read>
By default, there are built in identifiers which can be specified as ACL entries:
1. creator , meaning the creator of the document can read, write or delete a document
<read>creator</read> <write>creator></write> <delete>creator</delete>
2. anonymous , meaning that anyone can read, write or delete a document
<read>anonymous</read> <write>anonymous></write> <delete>anonymous</delete>
3. authenticated-users , meaning that all logged-in users can read, write or delete a document
<read>authenticated-users</read> <write>authenticated-users</write> <delete>authenticated-users</delete>
4. nobody, meaning that no one can read, write or delete a document except for the account owner
<read>nobody</read> <write>nobody</write> <delete>nobody</delete>
Note: An owner is treated as a super user, and hence bypasses all security checks. In other words, even if an ACL is set to nobody, the owner will always have access. In essence, an owner can perform any operation regardless of ACLs.
Furthermore, specific types of ACLs can be specified at a global level or at a store level instead of at a schema level.
Please refer to each service in order to learn more about its specific ACLs.