Skip to content

Switch OPA and Ranger authorizers to resolveSelections - #5445

Open
zhang-arvin wants to merge 1 commit into
apache:mainfrom
zhang-arvin:fix/5439-remove-synthetic-principals
Open

Switch OPA and Ranger authorizers to resolveSelections#5445
zhang-arvin wants to merge 1 commit into
apache:mainfrom
zhang-arvin:fix/5439-remove-synthetic-principals

Conversation

@zhang-arvin

Copy link
Copy Markdown

Fixes #5439

Summary

Switch external authorizers (OPA, Ranger) from resolveAll() to resolveSelections() with REFERENCE_CATALOG, REQUESTED_PATHS, and REQUESTED_TOP_LEVEL_ENTITIES.

This avoids resolving the caller principal and principal roles, which external authorizers do not need and which may not exist in the metastore for external principals.

Background

PR #5119 introduces external principals and a temporary hack in the Resolver: synthetic principals and principal roles. This hack is needed because the current external authorizers call resolveAll(), which tries to resolve the caller principal from the metastore — but external principals do not exist in the metastore.

Changes

  • OpaPolarisAuthorizer.resolveAuthorizationInputs(): Changed from resolveAll() to resolveSelections() with REFERENCE_CATALOG, REQUESTED_PATHS, REQUESTED_TOP_LEVEL_ENTITIES.
  • RangerPolarisAuthorizer.resolveAuthorizationInputs(): Same change.

Why this works

External authorizers (OPA, Ranger) do not use resolved caller principal/principal roles in their authorization logic. They derive actor information from the AuthorizationRequest.principal() directly. By skipping CALLER_PRINCIPAL and CALLER_PRINCIPAL_ROLES resolution, we avoid the need for synthetic principal entities in the Resolver.

Checklist

  • I have read the Polaris contribution guidelines
  • My code follows the code style of this project
  • No new dependencies are introduced
  • This change does not affect internal authorizer behavior (PolarisAuthorizerImpl still uses resolveAll())

@ayushtkn ayushtkn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanx @zhang-arvin for the changes.

On scope: the title and Fixes #5439 read as though the synthetic-principal hack is being removed from the Resolver, but this PR only changes the two authorizers — and the hack isn't in main yet, since #5119 is still open. To be fair to the PR, #5439's body defines the fix as exactly this ("until external authorizers change their implementation of resolveAuthorizationInputs() to avoid calling resolveAll()"), so the mismatch is really between that issue's title and its body.

I'd still retitle to something like "Switch OPA and Ranger authorizers to resolveSelections", so it's clear what this delivers, and let #5439 close when #5119 lands without the workaround.

Comment on lines +141 to +144
Set.of(
Resolvable.REFERENCE_CATALOG,
Resolvable.REQUESTED_PATHS,
Resolvable.REQUESTED_TOP_LEVEL_ENTITIES));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This selection set is not equivalent to resolveAll() when the manifest has no reference catalog.
ResolvePlan.fromSelections() throws IllegalArgumentException if REFERENCE_CATALOG or REQUESTED_PATHS is selected and the catalog name is null. resolveAll() already skips those in that case.
PolarisAdminService uses newResolutionManifest(null) for root ops, principal/principal-role ops, and root grants. Those paths will break for OPA.
Always resolve REQUESTED_TOP_LEVEL_ENTITIES; add REFERENCE_CATALOG and REQUESTED_PATHS only when a reference catalog is present.
Also update OpaPolarisAuthorizerTest.resolveAuthorizationInputsResolvesAll(), which still verifies resolveAll().

Comment on lines 93 to 97
Set.of(
Resolvable.REFERENCE_CATALOG,
Resolvable.REQUESTED_PATHS,
Resolvable.REQUESTED_TOP_LEVEL_ENTITIES));
}

@ayushtkn ayushtkn Sep 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as OpaPolarisAuthorizer: this unconditional set will throw on admin calls with a null catalog. Please apply the same catalog-conditional selections here.

Would also be good to add Ranger unit tests for resolveAuthorizationInputs() covering both catalog-scoped and null-catalog manifests. testAuthzRoot only exercises authorizeOrThrow, so it would not catch this.

One caveat: a test that mocks PolarisResolutionManifest (like OpaPolarisAuthorizerTest.resolveAuthorizationInputsResolvesAll()) never reaches the real ResolvePlan.fromSelections(), so the IllegalArgumentException can't surface. To actually pin this, either capture the argument and assert the selection set excludes REFERENCE_CATALOG/REQUESTED_PATHS when there's no catalog, or use a real manifest constructed with a null catalog name.

@adutra adutra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a fix for #5439.

@zhang-arvin zhang-arvin changed the title [Polaris-5439] Remove synthetic principals hack in Resolver Switch OPA and Ranger authorizers to resolveSelections Sep 7, 2026
Switch external authorizers (OPA, Ranger) from resolveAll() to
resolveSelections() with REFERENCE_CATALOG, REQUESTED_PATHS, and
REQUESTED_TOP_LEVEL_ENTITIES. This avoids resolving the caller
principal and principal roles, which external authorizers do not need
and which may not exist in the metastore for external principals.

This change removes the need for synthetic principal entities in the
Resolver when external principals are used, as the external authorizers
no longer trigger resolution of the caller principal.
@zhang-arvin
zhang-arvin force-pushed the fix/5439-remove-synthetic-principals branch from bf42e68 to bd29a50 Compare September 7, 2026 17:34
@zhang-arvin

Copy link
Copy Markdown
Author

Updated per review feedback:

  • PolarisResolutionManifest now exposes a public getCatalogName() getter.
  • OPA and Ranger authorizers branch their resolveSelections set on catalog presence: with a reference catalog they select REFERENCE_CATALOG, REQUESTED_PATHS and REQUESTED_TOP_LEVEL_ENTITIES; for null-catalog (admin) manifests they select only REQUESTED_TOP_LEVEL_ENTITIES, avoiding the IllegalArgumentException from ResolvePlan.fromSelections.
  • OpaPolarisAuthorizerTest.resolveAuthorizationInputsResolvesAll replaced with selection-set asserts for both the catalog and null-catalog branches; symmetric tests added to RangerPolarisAuthorizerTest.
  • PR title updated to 'Switch OPA and Ranger authorizers to resolveSelections'.

Let me know if anything else is needed. Thanks!

@flyingImer flyingImer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking code concerns from my side. I agree with keeping #5439 open until the synthetic-principal workaround is actually removed, so this should use Related to rather than Fixes.

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.

Remove synthetic principals hack in Resolver

4 participants