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 fieldlocations
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
, andcreateRules
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 inreadRules
.
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.