Add row-level security filter in query #17564
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds the ability to attach row filters to a query, thus restrict row-level data access for given users.
Description
A query follows these steps: initialize -> authorize -> execute. In the authorize step, the permissions are checked for all the required resources in the query. Before this PR, the authorize step only returns allow or deny access on a table. Granting access to a table means a user can see all data in this table. After this PR, the authorize step can return allow access along with restrictions (i.e. a row filter that must be applied to the table ), which restrict users' data access at row level. For example, customers can only see rows relevant to their company.
The
authorizeAllResourceActions
now returns aAuthorizationResult
instead ofAccess
, this class also replacesDruidPlanner.AuthResult
class. The main difference betweenAuthorizationResult
andAccess
is that the former contains a map of table withDimFilter
. It can also haveResourceAction
Iterables which DruidPlanner cares about.In the authorize step of
QueryLifecycle
, it would enforce the filters on tables in the datasource tree, transformTableDataSource
toRestrictedDataSource
. In the execute step, filters are applied throughRestrictedSegment
andRestrictedCursorFactory
.Key changed/added classes in this PR
AuthorizationResult
. The class should be used for all the authorization calls, while theAccess
class is still used inAuthorizer
interface. It has an static variableALLOW_ALL
, which should be used for all internal calls.Objects.requireNonNull(authResult.getFailureMessage()))
is called to get a failure message, which replacedaccess.toString()
,access.toMessage()
,access.getMessage()
. The class contains:Access
. AddedOptional<DimFilter> rowFilter
field, which represents a restrictions returned fromauthorizer
. Also updated constructor.AbstractStatement
. ReplaceDruidPlanner.AuthResult
withAuthorizationResult
.AuthConfig
. Added flag enableStrictPolicyCheck, when enabled, it would check every table needs to have a restriction in place, meaning it has an entry in the restrictions map, could be Optional.empty().AuthorizationUtils
. It now consolidates all restrictions for authorizing resource actions into a restrictions map, which is included inAuthorizationResult
. Also updated javadoc for all public methods.RestrictedDataSource
, which wraps aTableDataSource
with a DimFilter. If the filter is null, meaning there's no applied.RestrictedSegment
, which represents a segment with a filter.RestrictedCursorFactory
, can be created byRestrictedSegment.asCursorFactory
, enforces the DimFilter onCursor
.DataSource
interface, added a sub type ofrestrict
, added a default methodmapWithRestriction
.TableDataSource
, added the impl ofmapWithRestriction
.JoinDataSource
can acceptRestrictedDataSource
as left-hand side datasource.Query
interfaced, added a default methodwithPolicyRestrictions
.SegmentMetadataQuery
, added the impl ofwithDataSource
.QueryLifeCycle
, replacebaseQuery
withbaseQuery.withPolicyRestrictions
if authorization result is notALLOW_ALL
(calls from internal services).Caveats
UnionDataSource
doesn't work withRestrictedDataSource
, planning to fix that later.This PR has: