Reject unknown policyType filter values in the Policy API - #5310
Open
SEPURI-SAI-KRISHNA wants to merge 2 commits into
Open
Reject unknown policyType filter values in the Policy API#5310SEPURI-SAI-KRISHNA wants to merge 2 commits into
SEPURI-SAI-KRISHNA wants to merge 2 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Updates the Policy API to reject unknown policyType query parameter values (HTTP 400) instead of silently treating them as “no filter,” preventing accidental unfiltered listings and incorrect applicable-policy selection.
Changes:
- Added
PolicyCatalogUtils.resolvePolicyTypeFilter(...)to centrally resolve/validate thepolicyTypequery parameter (null/empty allowed; unknown rejected). - Updated
PolicyCatalogAdapterlisting endpoints to use the new resolver. - Added unit + integration tests to verify HTTP 400 behavior and updated
CHANGELOG.md.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogUtils.java | Adds shared resolver that enforces valid policyType values and throws BadRequestException for unknown types. |
| runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogAdapter.java | Switches policy listing endpoints to use the centralized resolver (enabling 400 on unknown type). |
| runtime/service/src/test/java/org/apache/polaris/service/catalog/policy/PolicyCatalogUtilsTest.java | Adds focused unit tests for accepted vs rejected policyType inputs. |
| integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisPolicyServiceIntegrationTest.java | Adds end-to-end coverage to ensure unknown policyType yields HTTP 400. |
| CHANGELOG.md | Documents the behavior change for API consumers. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The listPolicies and getApplicablePolicies endpoints resolved the optional policyType query parameter with PolicyType.fromName, which returns null for any unrecognized name. Since null is also the sentinel meaning "no filter", an unrecognized value silently degraded into an unfiltered listing: a misspelled type such as system.data_compaction returned HTTP 200 along with policies of every type, leaving the client unable to distinguish a filtered result from an unfiltered one. The raw parameter is now resolved by PolicyCatalogUtils.resolvePolicyTypeFilter. An absent or empty value continues to mean "no filter", as the parameter is declared with allowEmptyValue: true; any other value must name a known policy type and is otherwise rejected with HTTP 400. This matches the behavior of createPolicy, which already rejected unknown type names, and the 400 response documented for both endpoints.
The rejection message named only the offending value, leaving a client to consult the specification or the source to discover what it should have sent. It now quotes the supplied value and lists the accepted names, derived from PredefinedPolicyTypes so the message and the set actually accepted by PolicyType.fromName cannot drift apart. A test asserts every valid type name appears in the message.
SEPURI-SAI-KRISHNA
force-pushed
the
policy-type-filter-validation
branch
from
August 18, 2026 02:55
36155d1 to
4a12083
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The Policy API resolves the optional
policyTypequery parameter withPolicyType.fromName(...), which returnsnullfor any name it does notrecognize.
nullis also the sentinel that means "no filter", so anunrecognized value silently degrades into an unfiltered listing:
GET /polaris/v1/{prefix}/namespaces/{namespace}/policies?policyType=...GET /polaris/v1/{prefix}/applicable-policies?policyType=...A misspelled type such as
system.data_compaction(underscore instead ofhyphen) therefore returns HTTP 200 together with policies of every type,
and the client has no way to tell a filtered result from an unfiltered one.
For
getApplicablePoliciesthis is the more damaging case: a caller askingwhich snapshot-expiry policy applies to a table receives policies of all
types and may act on the wrong one.
createPolicyalready rejects unknown type names with aBadRequestException(
PolicyCatalog#createPolicy), so the two listing endpoints were alsoinconsistent with the rest of the same API, and with their own specification,
which documents a 400 response.
Changes
PolicyCatalogUtils#resolvePolicyTypeFilternow resolves the raw queryparameter, and both call sites in
PolicyCatalogAdapteruse it:null) or empty value still means "no filter" — the parameter isdeclared
allowEmptyValue: trueinspec/polaris-catalog-apis/policy-apis.yaml,so empty must keep working;
with
BadRequestException, which maps to HTTP 400.No public interface or extension point is changed:
PolicyCatalogUtilsis aninternal helper in the service module, and
PolicyTypeis untouched.Testing
PolicyCatalogUtilsTest(new): parameterized over everyPredefinedPolicyTypesvalue for the accepted cases, plus
null/ empty for "no filter", plus unknownnames, wrong separators, wrong case and surrounding whitespace for the rejected
cases.
PolarisPolicyServiceIntegrationTest: two new end-to-end tests assert HTTP 400from
listPoliciesandgetApplicablePolicieswhen an unknownpolicyTypeissupplied while a real policy exists in the namespace.
Both integration tests were confirmed to fail against the unpatched resolver
(
expected: 400 but was: 200) and to pass with the fix.PolicyServiceIntegrationTestruns 48 tests with 0 failures, and
spotlessCheck/checkstyleMain/checkstyleTestpass for:polaris-runtime-serviceand:polaris-tests.Notes
While reading this area I noticed that
listPoliciesacceptspageTokenandpageSizeand declaresnext-page-tokenin its response schema, but theimplementation ignores all three and always lists everything. That is a
separate change with design questions of its own (result ordering, the
Set<PolicyIdentifier>response shape), so it is deliberately not bundled here;I plan to raise it as its own issue.
AI assistance was used while preparing this change. I have reviewed the
implementation and the tests, and I am responsible for the contribution.
Checklist
CHANGELOG.md(if needed)site/content/in-dev/unreleased(if needed) — no user-facingdocumentation covers the
policyTypeparameter, so no update was required