Skip to content

[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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

HonahX
Copy link
Contributor

@HonahX HonahX commented May 6, 2025

This PR adds new policy related privileges to polaris-management-api.yml and update PolarisAdminService to allow granting new privileges

Copy link
Contributor

@eric-maynard eric-maynard left a 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

@github-project-automation github-project-automation bot moved this from PRs In Progress to Ready to merge in Basic Kanban Board May 14, 2025
Comment on lines +1431 to +1432
minLength: 1
maxLength: 256
Copy link
Contributor

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.

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?

Copy link
Contributor

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.

Copy link
Contributor

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]\$).*$'

Copy link
Contributor Author

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?

Comment on lines +1359 to +1366
- POLICY_CREATE
- POLICY_WRITE
- POLICY_READ
- POLICY_DROP
- POLICY_LIST
- POLICY_FULL_METADATA
- CATALOG_ATTACH_POLICY
- CATALOG_DETACH_POLICY
Copy link
Contributor

@singhpk234 singhpk234 May 14, 2025

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 ?

Copy link
Contributor

@eric-maynard eric-maynard May 14, 2025

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

Comment on lines +558 to +578
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);
Copy link
Contributor

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);
Copy link
Contributor

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
Copy link
Contributor

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?

Copy link
Contributor

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

Copy link
Contributor

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
Copy link
Contributor

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?

Copy link
Contributor

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.

Comment on lines +1431 to +1432
minLength: 1
maxLength: 256
Copy link
Contributor

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:
{
Copy link
Contributor

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) {
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor

@gh-yzou gh-yzou May 14, 2025

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);
Copy link
Contributor

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();
Copy link
Contributor

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(
Copy link
Contributor

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants