-
Notifications
You must be signed in to change notification settings - Fork 3k
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 support for Open Policy Agent #19532
Conversation
From the old PR I believe the only items that remain unresolved: Grants:I am happy to remove this and implement a default deny if @dain or others think there is no value to supporting this in OPA. IMHO OPA could provide a simple central point to enforce global policies as to what users can grant permissions on what catalogs, while deferring more granular permissioning to the connector access control logic for each catalog if needed. Given that the meaning of a Allowing OPA to answer an authorization question for a grant query would still let users implement their more specific permissioning logic at the connector access control level if needed, whereas denying here would immediately deny any query. It also lets users decide whether they want to globally allow or deny this style of queries. I don't have lots of experience with this specific part of Trino, but the rest of the plugin is written with the goal of deferring all authorization requests to OPA such that users can plug in any policy they want without changing any Trino logic; and I think this same goal could be beneficial here. Fields in the request contextI removed
Including the Trino version number in the request & documenting fields in the requestFrom discussion on slack with @dain What way would I be able to obtain the Trino version programatically? The only way I've seen is from the This item is pending Cleaning up
|
1fb3d6c
to
3aec31d
Compare
For For version, I put up a PR to add it to |
Sounds good, will remove them for now
That would be great! The PR looks good, thank you! |
plugin/trino-opa/src/main/java/io/trino/plugin/opa/OpaHttpClient.java
Outdated
Show resolved
Hide resolved
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.
Some comments
plugin/trino-opa/src/main/java/io/trino/plugin/opa/OpaAccessControl.java
Show resolved
Hide resolved
plugin/trino-opa/src/main/java/io/trino/plugin/opa/OpaAccessControl.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/main/java/io/trino/plugin/opa/OpaAccessControl.java
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/OpaBatchAccessControlFilteringUnitTest.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/OpaAccessControlFilteringUnitTest.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/HttpClientUtils.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/OpaAccessControlFilteringUnitTest.java
Outdated
Show resolved
Hide resolved
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.
Some comments
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.fail; | ||
|
||
public class RequestTestUtilities |
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.
final
for utilitiy classes
plugin/trino-opa/src/test/java/io/trino/plugin/opa/RequestTestUtilities.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/RequestTestUtilities.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/RequestTestUtilities.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/RequestTestUtilities.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/RequestTestUtilities.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/ResponseTest.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/ResponseTest.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/ResponseTest.java
Outdated
Show resolved
Hide resolved
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.
Looking good
@ParameterizedTest(name = "{index}: {0}") | ||
@MethodSource("io.trino.plugin.opa.FilteringTestHelpers#emptyInputTestCases") | ||
public void testEmptyRequests( | ||
BiFunction<OpaAccessControl, SystemSecurityContext, Collection> callable) | ||
{ |
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 have been removing Parameterized tests throughtout the code base because they are difficult to understand and debug because the test cases are separated from the test code, and they are often over abstracted into generic functions like this, so a reader can not know what is actually being tested. Please just inline the cases.
@ParameterizedTest(name = "{index}: {0}") | ||
@MethodSource("io.trino.plugin.opa.FilteringTestHelpers#emptyInputTestCases") | ||
public void testEmptyRequests( | ||
BiFunction<OpaAccessControl, SystemSecurityContext, Collection> callable) |
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.
The Collection
type here is a raw type which disables type checking in Java. Add something <?>
, or even better set the actual type.
plugin/trino-opa/src/test/java/io/trino/plugin/opa/OpaAccessControlSystemTest.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/OpaAccessControlSystemTest.java
Outdated
Show resolved
Hide resolved
plugin/trino-opa/src/test/java/io/trino/plugin/opa/OpaAccessControlUnitTest.java
Outdated
Show resolved
Hide resolved
@ParameterizedTest(name = "{index}: {0}") | ||
@MethodSource("io.trino.plugin.opa.OpaAccessControlUnitTest#noResourceActionTestCases") |
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.
as with the other tests, remove use of @ParameterizedTest
|
||
private static Stream<Arguments> tableWithPropertiesTestCases() | ||
{ | ||
Stream<FunctionalHelpers.Consumer4<OpaAccessControl, SystemSecurityContext, CatalogSchemaTableName, Map>> methods = Stream.of( |
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.
Raw Map
type
3aec31d
to
ecda42a
Compare
All comments should be addressed, I've removed parameterization on some tests, particularly the following ones in
The new If you are happy with the changes made, I will change all the other tests accordingly |
Late to the party, but how is this performant at scale, particularly with the follow-on PR for row-based access control? It seems to me that a REST call per row in the input is going to really stink. Why not use the Compile API to pre-fill user and context into the policies, then execute the query with the data locally? E.g., https://blog.openpolicyagent.org/write-policy-in-opa-enforce-policy-in-sql-d9d24db93bf4 |
That is a good question. From our experimentation it seems to be working well enough as we’re deploying it alongside each worker.
The OPA binary is very simple to deploy and run so we just co locate it.
That said, I’d love to hear your suggestion on the compile API, I’m not familiar with it. Would this allow us to compile the rego and execute it externally to trino?
The row level filtering I wouldn’t expect to be much of an issue, as the actual rows are never sent to OPA. OPA just produces filter expressions that Trino applies locally - kind of like adding an extra WHERE clause
Thanks!
…___________________
Pablo Arteaga
This message was sent from a mobile device, apologies for any typos or inadvertent auto-corrects.
On 14 Dec 2023, at 21:55, T. Miller ***@***.***> wrote:
Late to the party, but how is this performant at scale, particularly with the follow-on PR for row-based access control? It seems to me that a REST call per row in the input is going to really stink.
Why not use the Compile API to pre-fill user and context into the policies, then execute the query with the data locally?
—
Reply to this email directly, view it on GitHub<#19532 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ALEL2M36BW75V5O54TMH4MTYJNYTLAVCNFSM6AAAAAA6PWIKPCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJWG4YTQMJZGU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Just saw your updated comment with the link, thanks! IMHO, at the moment we should keep a simple solution where OPA makes a full, final, decision. In fact, Trino doesn't really know all that much about the data either: in the example you linked, the application contacting OPA is aware of what pets are owned by whom and what clinicians are allowed to interact with them. This is not the case in Trino - many of these are coming from business logic that may be entirely external to Trino, and as such may as well be pushed into OPA. E.g.: the information as to who owns a table is only partially available in Trino - tables may well be created by scripts and thus be owned by fake service accounts. That said, I think it would be nice to in the future use this compile logic to allow OPA to return expressions that Trino would execute on the data and make the decision internally. The reason I think we should defer that is two-fold:
As for the row level filtering, note that row level filtering is done within Trino. There is never a case where each row is sent to OPA, because the OPA plugin never even sees the rows. The Trino SPI expects authorizers to return a list of And, in fact, using row level filtering would bring us one step closer to the system you suggested 😄 |
0365917
to
fd6d65c
Compare
I rebased the PR and bumped the version. I will also update the documentation branch (I'm around halfway through with that) and we can merge that after this PR too |
cc @trinodb/maintainers for new plugin |
} | ||
|
||
@Config("opa.allow-permissioning-operations") | ||
@ConfigDescription("Whether to allow permissioning operations (GRANT, DENY, ...) as well as role management - OPA will not be queried for any such operations, they will be bulk allowed or denied depending on this setting") |
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.
Is this term "permissioning" really what we want to use. Is that some sort of weird terminology used in OPA .. if not I would prefer we use something like
allow-security-operations
or allow-sql-security-operations
or allow-sql-security-statements
.. wdyt ?
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 agree, the work "permissioning" is strange, and we should rename the java methods, and the config property. I suggest allow-permission-management-operations
or allow-security-management-operations
. @mosabua for the docs, we should mention that OPA does not have a permissions management backend for Trino, so these operations will fail regardless... meaning there is no code that takes a SQL GRANT statement and created OPA rules.
I just had to look up the link for something else as well and was wondering about the status :) Is it maybe worth getting together for two hours one evening and hashing out the remaining open points? I'd volunteer to write minutes and post them here so everything is documented and public.. |
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 is good. I have one comment about changing the work "permissioning", and there is a trivial merge conflict for the main pom.
Can you update these two items, squash and push, and I'll merge it?
} | ||
|
||
@Config("opa.allow-permissioning-operations") | ||
@ConfigDescription("Whether to allow permissioning operations (GRANT, DENY, ...) as well as role management - OPA will not be queried for any such operations, they will be bulk allowed or denied depending on this setting") |
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 agree, the work "permissioning" is strange, and we should rename the java methods, and the config property. I suggest allow-permission-management-operations
or allow-security-management-operations
. @mosabua for the docs, we should mention that OPA does not have a permissions management backend for Trino, so these operations will fail regardless... meaning there is no code that takes a SQL GRANT statement and created OPA rules.
Absolutely, sorry I missed this comment - I am happy to meet up whether for this PR (which will hopefully be merged soon!) or for the follow ups for row level filtering / column masking :) Thanks a lot for your offer @soenkeliebau ! |
fd6d65c
to
54873d2
Compare
Rebase and renaming of the field is now done @dain Thanks! |
Description
This PR supersedes #17940 which was getting hard to follow due to the large number of comments
Additional context and related issues
Docs PR by @mosabua is #20246
Release notes
( ) This is not user-visible or is docs only, and no release notes are required.
( ) Release notes are required. Please propose a release note for me.
(X) Release notes are required, with the following suggested text:
And make it link to the docs