@@ -1412,6 +1412,7 @@ data:
14121412 # - allow
14131413 # - batch
14141414 # - columnMask
1415+ # - batchColumnMasks
14151416 # - rowFilters
14161417 # These rules use the rules and functions in requested_permission.rego
14171418 # and actual_permissions.rego to calculate the result.
@@ -1655,6 +1656,7 @@ data:
16551656 # "schemaName": "schema",
16561657 # "tableName": "table",
16571658 # "columnName": "column",
1659+ # "columnType": "varchar",
16581660 # },
16591661 # },
16601662 # },
@@ -1709,6 +1711,90 @@ data:
17091711 column_mask := {"expression": column.mask}
17101712 }
17111713
1714+ # METADATA
1715+ # description: |
1716+ # Entry point for fetching column masks in batch, configured in the
1717+ # Trino property `opa.policy.batch-column-masking-uri`.
1718+ #
1719+ # The input has the following form:
1720+ #
1721+ # {
1722+ # "action": {
1723+ # "operation": "GetColumnMasks",
1724+ # "filterResources": [{
1725+ # "column": {
1726+ # "catalogName": "catalog",
1727+ # "schemaName": "schema",
1728+ # "tableName": "table",
1729+ # "columnName": "column",
1730+ # "columnType": "varchar",
1731+ # }},
1732+ # {"column": ...},
1733+ # ...
1734+ # ],
1735+ # },
1736+ # "context": {
1737+ # "identity": {
1738+ # "groups": ["group1", ...],
1739+ # "user": "username",
1740+ # },
1741+ # "softwareStack": {"trinoVersion": "455"},
1742+ # }
1743+ # }
1744+ #
1745+ # The batchColumnMask rule queries the column constraints in the
1746+ # Trino policies for each of the resources in the "filterResources"
1747+ # list of the request and returns a list of viewExpressions, containing
1748+ # the column mask if any set and optionally the identity for the mask
1749+ # evaluation, and the index of the corresponding resource in the
1750+ # "filterResources" list of the request.
1751+ # A column mask is an SQL expression,
1752+ # e.g. "'XXX-XX-' + substring(credit_card, -4)".
1753+ # entrypoint: true
1754+ batchColumnMasks contains column_mask if {
1755+ input.action.operation == "GetColumnMask"
1756+ some index, resource in input.action.filterResources
1757+
1758+ column := column_constraints(
1759+ resource.column.catalogName,
1760+ resource.column.schemaName,
1761+ resource.column.tableName,
1762+ resource.column.columnName,
1763+ )
1764+
1765+ is_string(column.mask)
1766+ is_string(column.mask_environment.user)
1767+
1768+ column_mask := {
1769+ "index": index,
1770+ "viewExpression": {
1771+ "expression": column.mask,
1772+ "identity": column.mask_environment.user,
1773+ },
1774+ }
1775+ }
1776+
1777+ batchColumnMasks contains column_mask if {
1778+ input.action.operation == "GetColumnMask"
1779+ some index, resource in input.action.filterResources
1780+
1781+ column := column_constraints(
1782+ resource.column.catalogName,
1783+ resource.column.schemaName,
1784+ resource.column.tableName,
1785+ resource.column.columnName,
1786+ )
1787+
1788+ is_string(column.mask)
1789+ is_null(column.mask_environment.user)
1790+
1791+ column_mask := {
1792+ "index": index,
1793+ "viewExpression": {"expression": column.mask},
1794+ }
1795+ }
1796+
1797+
17121798 # METADATA
17131799 # description: |
17141800 # Entry point for fetching row filters, configured in the Trino
0 commit comments