Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 133 additions & 5 deletions docs/src/main/sphinx/security/opa-access-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ with the following minimal configuration:

```properties
access-control.name=opa
opa.policy.uri=https://your-opa-endpoint/v1/data/allow
opa.policy.uri=https://opa.example.com/v1/data/trino/allow
```

To combine OPA access control with file-based or other access control systems,
Expand All @@ -45,17 +45,21 @@ The following table lists the configuration properties for the OPA access contro
- Description
* - `opa.policy.uri`
- The **required** URI for the OPA endpoint, for example,
`https://opa.example.com/v1/data/allow`.
`https://opa.example.com/v1/data/trino/allow`.
* - `opa.policy.row-filters-uri`
- The **optional** URI for fetching row filters - if not set no row filtering
is applied. For example, `https://opa.example.com/v1/data/rowFilters`.
is applied. For example, `https://opa.example.com/v1/data/trino/rowFilters`.
* - `opa.policy.column-masking-uri`
- The **optional** URI for fetching column masks - if not set no masking
is applied. For example, `https://opa.example.com/v1/data/columnMask`.
is applied. For example, `https://opa.example.com/v1/data/trino/columnMask`.
* - `opa.policy.batch-column-masking-uri`
- The **optional** URI for fetching columns masks in batches; must **not**
be used with `opa.policy.column-masking-uri`. For example,
`http://opa.example.com/v1/data/trino/batchColumnMasks`.
* - `opa.policy.batched-uri`
- The **optional** URI for activating batch mode for certain authorization
queries where batching is applicable, for example
`https://opa.example.com/v1/data/batch`. Batch mode is described
`https://opa.example.com/v1/data/trino/batch`. Batch mode is described
[](opa-batch-mode).
* - `opa.log-requests`
- Configure if request details, including URI, headers and the entire body, are
Expand Down Expand Up @@ -304,6 +308,130 @@ column.
The same "identity" field may be returned to evaluate column masks under a
different identity.

### Batch column masking

If column masking is enabled, by default, the plugin will fetch each column
mask individually from OPA. When working with very wide tables this
can result in a performance degradation.

Configuring `opa.policy.batch-column-masking-uri` allows Trino to fetch the masks
for multiple columns in a single request. The list of requested columns is included
in the request under `action.filterResources`.

If `opa.policy.batch-column-masking-uri` is set it overrides the value of
`opa.policy.column-masking-uri` so that the plugin uses batch column
masking.

An OPA policy supporting batch column masking must return a list of objects,
each containing the following data:
- `viewExpression`:
- `expression`: the expression to apply to the column, as a string
- `identity` (optional): the identity to evaluate the expression as, as a
string
- `index`: a reference the index of the column in the request to which this mask
applies

For example, a policy configuring batch column masking may be defined by the
following rego script:

```text
package trino
import future.keywords.in
import future.keywords.if
import future.keywords.contains

default allow := true

batchColumnMasks contains {
"index": i,
"viewExpression": {
"expression": "NULL"
}
} if {
some i
column_resource := input.action.filterResources[i]
column_resource.catalogName == "sample_catalog"
column_resource.schemaName == "sample_schema"
column_resource.tableName == "restricted_table"
column_resource.columnName == "user_phone"
}


batchColumnMasks contains {
"index": i,
"viewExpression": {
"expression": "'****' || substring(user_name, -3)",
"identity": "admin"
}
} if {
some i
column_resource := input.action.filterResources[i]
column_resource.catalogName == "sample_catalog"
column_resource.schemaName == "sample_schema"
column_resource.tableName == "restricted_table"
column_resource.columnName == "user_name"
}
```

A batch column masking request is similar to the following example:

```json
{
"context": {
"identity": {
"user": "foo",
"groups": ["some-group"]
},
"softwareStack": {
"trinoVersion": "434"
}
},
"action": {
"operation": "GetColumnMask",
"filterResources": [
{
"column": {
"catalogName": "sample_catalog",
"schemaName": "sample_schema",
"tableName": "restricted_table",
"columnName": "user_phone",
"columnType": "VARCHAR"
}
},
{
"column": {
"catalogName": "sample_catalog",
"schemaName": "sample_schema",
"tableName": "restricted_table",
"columnName": "user_name",
"columnType": "VARCHAR"
}
}
]
}
}
```

The related OPA response is displayed in the following snippet:

```json
[
{
"index": 0,
"viewExpression": {
"expression": "NULL"
}
},
{
"index": 1,
"viewExpression": {
"expression": "'****' || substring(user_name, -3)",
"identity": "admin"
}
}
]
```

(opa-batch-mode)=
## Batch mode

Expand Down