-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add SystemAccessControl.getTableColumnMasks SPI function and OPA implementation #21997
base: master
Are you sure you want to change the base?
Conversation
return columns.stream() | ||
.map(c -> Map.entry(c, getColumnMask(context, tableName, c.getName(), c.getType()))) | ||
.filter(entry -> entry.getValue().isPresent()) | ||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this should have a default that calls getColumnMask
, looking at other function in this interface none of them do this. Should this logic be left to another class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, the default should be to call the old method
the engine should call the new method only
the old method should be deprecated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks! do we want to remove getColumnMask
from the AccessControl
interface? that would be the best way to ensure the engine is not using it anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, remove the supposed-to-be-unused method from the interface defined in trino-main
deprecation is needed only for trino-spi's interfaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the function from trino-main's interfaces, let me know if missed some.
Do we want to remove getColumnMask
's implementation from the FileBasedAccessControl and OpaAccessControl implementation? (or others if you have any in mind)
core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorAccessControl.java
Show resolved
Hide resolved
core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorAccessControl.java
Outdated
Show resolved
Hide resolved
return columns.stream() | ||
.map(c -> Map.entry(c, getColumnMask(context, tableName, c.getName(), c.getType()))) | ||
.filter(entry -> entry.getValue().isPresent()) | ||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, the default should be to call the old method
the engine should call the new method only
the old method should be deprecated
e256f67
to
a31b864
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
Let's cleanup the commits as follows:
- Squash
Deprecate getColumnMask from SPI interfaces
intoAdd access control SPI function for table column masks
. The deprecation should be mentioned in the commit message body. - Fixup
Remove getColumnMask from the AccessControl interface
intoAdd use table column masks SPI function for access control in core
and change title to say something like change access control to fetch column masks in bulk - Fixup
Add FBAC tests for getTableColumnMasks
into the commit that changed file based access control (no need to mention you added tests in the commit message/body) - For the other two commits change the commit message to say something like "Implement column mask bulk fetch api" or "convert to ...", so it is clear what changed
field.getName().ifPresent( | ||
fieldName -> columnSchemaBuilder.add(ColumnSchema.builder().setName(fieldName).setType(field.getType()).setHidden(field.isHidden()).build())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would reformat this so the columnschema builder is split across multiple lines, like this:
field.getName().ifPresent( | |
fieldName -> columnSchemaBuilder.add(ColumnSchema.builder().setName(fieldName).setType(field.getType()).setHidden(field.isHidden()).build())); | |
field.getName().ifPresent(fieldName -> columnSchemaBuilder.add(ColumnSchema.builder() | |
.setName(fieldName) | |
.setType(field.getType()) | |
.setHidden(field.isHidden()) | |
.build())); |
analyzeColumnMask(session.getIdentity().getUser(), table, name, field, accessControlScope, mask.get()); | ||
} | ||
Map<ColumnSchema, ViewExpression> masks = accessControl.getTableColumnMasks(session.toSecurityContext(), name, columnSchemas); | ||
for (Map.Entry<ColumnSchema, ViewExpression> entry : masks.entrySet()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would iterate over columnSchemas
instead of the returned map incase connector returns extra junk columns... just a bit safer
@@ -739,9 +741,17 @@ public List<ViewExpression> getRowFilters(SystemSecurityContext context, Catalog | |||
@Override | |||
public Optional<ViewExpression> getColumnMask(SystemSecurityContext context, CatalogSchemaTableName tableName, String columnName, Type type) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to drop this method
@@ -125,4 +126,18 @@ public OpaConfig setOpaColumnMaskingUri(URI opaColumnMaskingUri) | |||
this.opaColumnMaskingUri = Optional.ofNullable(opaColumnMaskingUri); | |||
return this; | |||
} | |||
|
|||
@NotNull | |||
public Optional<URI> getOpaBatchColumnMaskingUri() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you planning on supporting non-batched column masks in the long run. With this PR Trino will always ask for a batch of masks, do you want to support doing a call per column?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We won't be supporting single column masks. I do think this should be Optional
so we don't break current configurations; the plugin will query opaColumnMaskingUri
in parallel to get each mask. Admins can set this once they implement batching in Rego.
return result.result().stream() | ||
.map(resultItem -> Map.entry(columns.get(resultItem.index()), resultItem.viewExpression())) | ||
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a bit redundant:
return result.result().stream() | |
.map(resultItem -> Map.entry(columns.get(resultItem.index()), resultItem.viewExpression())) | |
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)); | |
return result.result().stream() | |
.collect(toImmutableMap(item -> columns.get(item.index(), item-> item.viewExpression())); |
public record OpaBatchColumnMaskQueryResultItem(int index, OpaViewExpression viewExpression) | ||
{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT the {}
can be on the same line as the record declaration
a31b864
to
07a396a
Compare
711ee6a
to
9aba72b
Compare
Deprecate `SystemAccessControl#getColumnMask` and `ConnectorAccessControl#getColumnMask` from SPI interfaces.
9aba72b
to
da4616a
Compare
Description
Addresses issues raised in #21359.
Adds the
getTableColumnMasks
function to the SPI(which defaults to calling
getColumnMask
repeatedly) thatSystemAcessControl
/ConnectorAccessControl
plugins can implement to process column mask requests in batches.Updates the
StatementAnalyzer
andAccessControl
to use this batched method of getting column masks whenever possible (which is all cases).The issue linked above goes into the performance implications.
This PR updates the OPA plugin to implement the new SPI function with 2 modes of operation:
batchColumnMasksUri
OPA Server endpoint that delegates collection of column masks to the Rego policy code; This requires changes to the Rego code running on the OPA server and the Trino configs.Additional context and related issues
#21359
Release notes
( ) This is not user-visible or is docs only, and no release notes are required.
(x) Release notes are required. Please propose a release note for me.
( ) Release notes are required, with the following suggested text: