Skip to main content
Version: v4.17

Local Policies

Local policies apply to a specific repository and specify access control at the level of tables or collections in a repository. Local policies are created and managed from the Policies tab in the Repository Details page.

Policy Structure

The structure of a local policy is very similar to that of a global policy with the same top level fields: governedData, readRules, deleteRules, updateRules, and insertRules. The specific differences within these fields are specified below.

  • governedData is an object with a single required field locations that specifies the database tables or collections (or objects in case of S3) that the policy applies to. In the most general case, a location is specified as <database>.<schema>.<table>. Wildcard characters are permitted. In case of specific database types, the format may be slightly different. For example, for MySQL, you would only specify <schema>.<table> while for MongoDB, you would specify <database>.<collection>. Note that local policies cannot be granularly applied to individual fields.

  • governedOperations supports the following operations: "alter", "drop", and "create" in addition to the other operations: "read", "update", "delete", and "insert". The "alter" operation applies to modification of tables (e.g., adding or dropping a column), "drop" applies to commands that attempt to drop (delete) the table. The "create" operation applies to commands that attempt to create a table.

  • Corresponding to the operations "alter", "drop", and "create", alterRules, dropRules, and createRules respectively can be specified.

  • Rules and how they are evaluated is nearly identical to that for global policies, including how the rule conditions are defined. The only difference is that the constraints object has the following fields (all optional).

    • maxRows: row limit while accessing the table.
    • alert: as for global policies, specifies an alert to be raised when the table is accessed.
    • datasetRewrite: Dataset rewrites are a very powerful policy feature that allows the incoming query to be rewritten such that every occurrence of the table is replaced by a specified subquery. In the most common case, the subquery would add a filter condition to the table being accessed. Placeholder values representing the database and the table specification as well as fields from the activity log can be used in the substitution query. As an example, the value of this field can be "SELECT * from ${dataset} WHERE email = '${identity.endUserEmail}'".

    Note that datasetRewrite can only be specified in readRules.

Default Policies

Like global policies, default local policies specify the value of governedData as "default". A default policy applies to all table accesses that are not governed by any of the targeted local policies. As an example, consider the following default policy.

{
"governedData": "default",
"governedOperations": ["read", "update", "delete", "insert"],
"readRules": [],
"updateRules": [],
"deleteRules": [],
"insertRules": []
}

This policy will apply to data access operations on any table for which the operation is not governed by any of the targeted policies. As can be seen, this policy denies access to all users, hence it implements a "deny by default" security model.

Complete Policy Example

The following policy governs access to the table customers within any schema in the database appdb. Users except those in the admin group are restricted to reading their own data. The web application that uses the database account webapp can read the data without restrictions. Further, only this application can update, delete, or insert data in the table.

{
"governedData": {
"locations": ["appdb.*.customers"]
},
"readRules": [
{
"conditions": [
"attribute": "identity.userGroups",
"operator": "contains",
"value": "admin"
],
"constraints": {}
},
{
"conditions": [
{
"attribute": "identity.repoUser",
"operator": "equals",
"value": "webapp"
}
],
"constraints": {}
},
{
"conditions": [],
"constraints": {
"datasetRewrite": "SELECT * FROM ${dataset} WHERE email = '${identity.endUserEmail}'"
}
}
],
"updateRules": [
{
"conditions": [
{
"attribute": "identity.repoUser",
"operator": "equals",
"value": "webapp"
}
],
"constraints": {}
}
],
"deleteRules": [
{
"conditions": [
{
"attribute": "identity.repoUser",
"operator": "equals",
"value": "webapp"
}
],
"constraints": {}
}
],
"insertRules": [
{
"conditions": [
{
"attribute": "identity.repoUser",
"operator": "equals",
"value": "webapp"
}
],
"constraints": {}
}
]
}

The policy above has three read rules. The first applies only if the user is a member of the admin group and allows access without any constraints. The second rule applies if the connection uses the webapp database account and also allows unconstrained access. The third rule has no conditions and hence applies to all users. This rule specifies a dataset rewriting constraint that specifies a substition query that will filter out all rows from the table except those pertaining to the user themselves. Since the rules are evaluated in sequence and evaluation stops when the first matching rule is found, the effect of these two rules is that members of the admin group and applications using the webapp database account will see all the data while all other users will only see their own data.

There is just one update rule and similar delete and insert rules. These rules have a condition requiring the database account to be webapp and no constraints. For all other users, this rule will not match and hence update, delete, or insert access will be denied.