-
Notifications
You must be signed in to change notification settings - Fork 236
[Policy Store | Management Spec] Add policy privileges to spec and update admin service impl #1529
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
base: main
Are you sure you want to change the base?
Conversation
3702203
to
0cd21a2
Compare
integration-tests/src/main/java/org/apache/polaris/service/it/env/ManagementApi.java
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.
LGTM! At some point, we should update the relevant docs
minLength: 1 | ||
maxLength: 256 |
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.
It's interesting we have this limits here, not only new entity like Policy, but also for table/view, etc. This becomes a an extra Polaris limit. Should we lift it somehow? I could see a corner case that users migrate a table with a long name will fail. Not a blocker for this PR though. cc @eric-maynard @dennishuo @collado-mike for more context.
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.
Yeah, I follow the existing pattern to include these limits for the new schema. May be we can do this in a follow-up to remove all the limits if they are not needed?
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.
Definitely, we can deal with it in a follow-up.
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.
@HonahX shall we also contain a pattern definition here? for example
pattern: '^(?!\s*[s|S][y|Y][s|S][t|T][e|E][m|M]\$).*$'
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.
Good point, I checked the yaml and seems the pattern is defined for catalogRole
, principal
, catalogName
. For namespace and table there is pattern
NamespaceGrant:
allOf:
- $ref: '#/components/schemas/GrantResource'
- type: object
properties:
namespace:
type: array
items:
type: string
privilege:
$ref: '#/components/schemas/NamespacePrivilege'
required:
- namespace
- privilege
TableGrant:
allOf:
- $ref: '#/components/schemas/GrantResource'
- type: object
properties:
namespace:
type: array
items:
type: string
tableName:
type: string
minLength: 1
maxLength: 256
privilege:
$ref: '#/components/schemas/TablePrivilege'
required:
- namespace
- tableName
- privilege
I think this pattern is mainly to prevent granting privileges to system defined roles/principals. If we have similar use case for namespace, table, policy, we can add that in the future. WDYT?
- POLICY_CREATE | ||
- POLICY_WRITE | ||
- POLICY_READ | ||
- POLICY_DROP | ||
- POLICY_LIST | ||
- POLICY_FULL_METADATA | ||
- CATALOG_ATTACH_POLICY | ||
- CATALOG_DETACH_POLICY |
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.
[not-blocker] is it possible to add some comments on what each of them mean ?
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.
+1 but we should probably do this separately, since the existing ones need comments too
managementApi.createCatalogRole(currentCatalogName, CATALOG_ROLE_2); | ||
List<CatalogPrivilege> policyPrivilegesOnCatalog = | ||
List.of( | ||
CatalogPrivilege.POLICY_LIST, | ||
CatalogPrivilege.POLICY_CREATE, | ||
CatalogPrivilege.POLICY_DROP, | ||
CatalogPrivilege.POLICY_WRITE, | ||
CatalogPrivilege.POLICY_READ, | ||
CatalogPrivilege.POLICY_FULL_METADATA, | ||
CatalogPrivilege.CATALOG_ATTACH_POLICY, | ||
CatalogPrivilege.CATALOG_DETACH_POLICY); | ||
Stream<CatalogGrant> catalogGrants = | ||
policyPrivilegesOnCatalog.stream() | ||
.map(p -> new CatalogGrant(p, GrantResource.TypeEnum.CATALOG)); | ||
catalogGrants.forEach(g -> managementApi.addGrant(currentCatalogName, CATALOG_ROLE_2, g)); | ||
|
||
Assertions.assertThat(managementApi.listGrants(currentCatalogName, CATALOG_ROLE_2)) | ||
.extracting(GrantResources::getGrants) | ||
.asInstanceOf(InstanceOfAssertFactories.list(GrantResource.class)) | ||
.map(gr -> ((CatalogGrant) gr).getPrivilege()) | ||
.containsExactlyInAnyOrderElementsOf(policyPrivilegesOnCatalog); |
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.
should we not undo the grants at catalog level to not effect subsequent test ?
|
||
@Test | ||
public void testGrantsOnNamespace() { | ||
restCatalog.createNamespace(NS1); |
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.
optional : should we add an nested namespace test as well, this could just be running this in a loop, wdyt ? just testing the resolution.
PolicyPrivilege: | ||
type: string | ||
enum: | ||
- CATALOG_MANAGE_ACCESS |
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.
question, why do we need CATALOG_MANAGE_ACCESS for PolicyPrivilege?
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.
+1 this shouldn't be here
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.
Isn't this essentially just function is a super-privilege? I see it only TablePrivileges
too, for example, even though it's not in the docs.
- POLICY_DROP | ||
- POLICY_WRITE | ||
- POLICY_LIST | ||
- POLICY_FULL_METADATA |
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 am always confused by the FULL_METADATA, but policy doesn't have a metadata concept, that simply refers to full access capability, right? would POLICY_FULL_ACCESS make more sense?
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.
Isn't that the same as for namespaces? We call that NAMESPACE_FULL_METADATA
.
minLength: 1 | ||
maxLength: 256 |
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.
@HonahX shall we also contain a pattern definition here? for example
pattern: '^(?!\s*[s|S][y|Y][s|S][t|T][e|E][m|M]\$).*$'
@@ -621,6 +623,19 @@ public Response addGrantToCatalogRole( | |||
adminService.grantPrivilegeOnCatalogToRole(catalogName, catalogRoleName, privilege); | |||
break; | |||
} | |||
case PolicyGrant policyGrant: | |||
{ |
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.
Shall we do those in separate PR? so that we can separate the change of API spec and backend implementaiton?
new ResolverPath(List.of(catalogRoleName), PolarisEntityType.CATALOG_ROLE), | ||
catalogRoleName); | ||
ResolverStatus status = resolutionManifest.resolveAll(); | ||
if (status.getStatus() == ResolverStatus.StatusEnum.ENTITY_COULD_NOT_BE_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.
is taht implementation mostly the same as authorizeGrantOnNamespaceOperationOrThrow, how about let's merge thoe two functions, let the function take a EntityType, and an entity name. The only thing you need to take care here is probably the error message, and i think we can do a simple enum.
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.
It's mostly like authorizeGrantOnTableLikeOperationOrThrow
, but it deals with a PolicyIdentifier
instead of a TableIdentifier
.
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.
Oh, i am actually referring to the namespaces, but all those function seems very similar. I think we can either internally handle this part according to the type, or just let the caller pass this argument List entityNames.
|
||
PolarisResolvedPathWrapper resolvedPathWrapper = | ||
resolutionManifest.getResolvedPath( | ||
identifier, PolarisEntityType.POLICY, PolarisEntitySubType.ANY_SUBTYPE); |
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 see other places don't need the subtype argument, is there a reason that we need that for Policy?
throw new NoSuchPolicyException(String.format("Policy not exists: %s", identifier)); | ||
} | ||
|
||
List<PolarisEntity> catalogPath = resolvedPathWrapper.getRawParentPath(); |
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.
Similar as above, i think we can have a common function that is used for both NameSpace and Policy
@@ -150,6 +150,11 @@ public enum PolarisPrivilege { | |||
CATALOG_DETACH_POLICY(81, PolarisEntityType.CATALOG), | |||
NAMESPACE_DETACH_POLICY(82, PolarisEntityType.NAMESPACE), | |||
TABLE_DETACH_POLICY(83, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), | |||
POLICY_MANAGE_GRANTS_ON_SECURABLE( |
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 am actually little bit confused for this privilege, is that a privilege neds to be granted for roles? does it needs to be configured in the spec somewhere also?
This PR adds new policy related privileges to
polaris-management-api.yml
and updatePolarisAdminService
to allow granting new privileges