Skip to content

feat(policy)!: undo subject mapping operator decomposition#3685

Merged
strantalis merged 2 commits into
mainfrom
fix/undo-operator-decomposition
Jul 1, 2026
Merged

feat(policy)!: undo subject mapping operator decomposition#3685
strantalis merged 2 commits into
mainfrom
fix/undo-operator-decomposition

Conversation

@alkalescent

@alkalescent alkalescent commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Undo the subject mapping operator decomposition while keeping the
DynamicValueMapping feature. The decomposed evaluator was never adopted on
main (EvaluateCondition still switches on operator), so the added enum and
field surface is unused complexity.

Changes

  • Remove ConditionComparisonOperatorEnum and ConditionQuantifierEnum.
  • Remove the comparison, quantifier, and case_insensitive fields from
    Condition; restore Condition.operator to required. Reserve the removed
    field numbers/names (4/5/6) to prevent reuse.
  • DynamicValueResolver now uses SubjectMappingOperatorEnum operator. NOT_IN
    is rejected at the buf.validate boundary because dynamic resolution is
    existential over the resolved entity values.
  • Drop case_insensitive everywhere.
  • Remove the Comparison*/Quantifier* shorthand consts; regenerate
    protocol/go and the policy docs.

Breaking Changes

ConditionComparisonOperatorEnum/ConditionQuantifierEnum are removed;
Condition.comparison/quantifier/case_insensitive are removed and
operator is required again; DynamicValueResolver.comparison is replaced by
operator. The DVM messages have no consumers yet, so breaking them (including
field numbers) is acceptable.

Verification

  • buf lint clean; buf breaking flags only the intended removals.
  • make proto-generate produces a focused diff (no unrelated doc churn).
  • protocol/go, service, and sdk modules build; protocol/go tests pass.

Follow-up

The DSPX-2754 dynamic attribute values implementation branch will be updated
to consume these reverted protos (operator-based DVM evaluation, DB column
rename) in a dependent change.

Summary by CodeRabbit

  • Breaking Changes

    • Policy conditions now use a single operator field instead of separate comparison, quantifier, and case-sensitivity options.
    • Dynamic value resolution now follows the same simplified operator-based format.
    • NOT_IN is not supported for dynamic resolution.
  • Documentation

    • Updated API and protocol documentation to match the new condition format.
    • Removed outdated condition and enum references from generated docs.

The operator decomposition split SubjectMappingOperatorEnum into
ConditionComparisonOperatorEnum + ConditionQuantifierEnum (+ case_insensitive)
and rewired DynamicValueResolver onto the comparison enum. The decomposed
evaluator was never adopted on main, so the added surface is unused complexity.

Undo the decomposition while keeping the DynamicValueMapping feature:

- Remove ConditionComparisonOperatorEnum and ConditionQuantifierEnum.
- Remove the comparison, quantifier, and case_insensitive fields from Condition
  and restore Condition.operator to required.
- DynamicValueResolver now uses SubjectMappingOperatorEnum. NOT_IN is rejected at
  the buf.validate boundary because dynamic resolution is existential.
- Drop case_insensitive everywhere.
- Remove the Comparison*/Quantifier* shorthand consts and regenerate protocol/go
  and the policy docs.

BREAKING CHANGE: ConditionComparisonOperatorEnum and ConditionQuantifierEnum are
removed; Condition.comparison/quantifier/case_insensitive are removed and
operator is required again; DynamicValueResolver.comparison is replaced by
operator (SubjectMappingOperatorEnum).

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
@github-actions github-actions Bot added comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) docs Documentation labels Jun 29, 2026
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@alkalescent, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7ff35fb4-fb0a-4469-bd9a-c38ca9fea891

📥 Commits

Reviewing files that changed from the base of the PR and between 08f2376 and 0409e91.

⛔ Files ignored due to path filters (1)
  • protocol/go/policy/objects.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (1)
  • service/policy/objects.proto
📝 Walkthrough

Walkthrough

Removes ConditionComparisonOperatorEnum and ConditionQuantifierEnum enums from the policy proto schema. Condition and DynamicValueResolver messages drop comparison, quantifier, and case_insensitive fields, using a single SubjectMappingOperatorEnum operator instead. Changes propagate to generated Go constants, all OpenAPI specs, and gRPC HTML documentation.

Condition operator consolidation

Layer / File(s) Summary
Proto schema changes
service/policy/objects.proto
Deletes ConditionComparisonOperatorEnum and ConditionQuantifierEnum enums; updates DynamicValueResolver to use SubjectMappingOperatorEnum operator (with NOT_IN excluded); reserves old Condition field numbers and names.
Go constants and tests
protocol/go/policy/enums.gen.go, protocol/go/internal/policy/enums.go, protocol/go/internal/policy/enums_test.go
Removes generated and internal shorthand constants for comparison/quantifier enums; adds OperatorIn, OperatorNotIn, OperatorInContains; removes corresponding test functions.
OpenAPI specs
docs/openapi/policy/objects.openapi.yaml, docs/openapi/policy/dynamicvaluemapping/..., docs/openapi/policy/*/...
Removes ConditionComparisonOperatorEnum and ConditionQuantifierEnum component schemas across all OpenAPI specs; updates policy.Condition required fields to include operator; reworks DynamicValueResolver to require operator with a not: enum: [2] constraint.
gRPC HTML docs
docs/grpc/index.html
Removes TOC entries and enum documentation blocks for deleted enums; updates Condition and DynamicValueResolver field tables to reflect the operator-based model.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

Possibly related PRs

  • opentdf/platform#3408: Adds operator shorthand constants (OperatorIn/OperatorNotIn/OperatorInContains) that this PR now surfaces in the internal enums package.
  • opentdf/platform#3652: Modifies policy.Condition operator documentation in the same OpenAPI and gRPC doc files touched here.
  • opentdf/platform#3668: Modifies policy.Condition.operator definition in service/policy/objects.proto, directly overlapping with this PR's proto changes.

Suggested reviewers

  • elizabethhealy
  • c-r33d

🐇 Farewell, comparison and quantifier too,
operator alone now carries the queue.
Reserved fields hold the memory of old,
while single operator is the story retold.
Hop hop, the proto is tidy and bright! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the breaking policy change and the reversal of subject mapping operator decomposition.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/undo-operator-decomposition

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request simplifies the policy evaluation logic by undoing the previously introduced decomposition of subject mapping operators. Since the decomposed evaluator was not adopted in the main codebase, this change removes the unnecessary complexity and restores the required operator field in the Condition message, ensuring a cleaner and more maintainable schema.

Highlights

  • Reversion of Operator Decomposition: Removed the unused ConditionComparisonOperatorEnum and ConditionQuantifierEnum, reverting to the original operator-based evaluation model.
  • Proto Schema Cleanup: Removed redundant fields (comparison, quantifier, case_insensitive) from the Condition message and reserved their field numbers and names to prevent future reuse.
  • DynamicValueResolver Updates: Updated DynamicValueResolver to use SubjectMappingOperatorEnum directly, while enforcing validation constraints to reject NOT_IN operators.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Ignored Files
  • Ignored by pattern: docs/openapi/**/* (9)
    • docs/openapi/policy/actions/actions.openapi.yaml
    • docs/openapi/policy/attributes/attributes.openapi.yaml
    • docs/openapi/policy/dynamicvaluemapping/dynamic_value_mapping.openapi.yaml
    • docs/openapi/policy/objects.openapi.yaml
    • docs/openapi/policy/obligations/obligations.openapi.yaml
    • docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
    • docs/openapi/policy/resourcemapping/resource_mapping.openapi.yaml
    • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
    • docs/openapi/policy/unsafe/unsafe.openapi.yaml
  • Ignored by pattern: protocol/**/* (4)
    • protocol/go/internal/policy/enums.go
    • protocol/go/internal/policy/enums_test.go
    • protocol/go/policy/enums.gen.go
    • protocol/go/policy/objects.pb.go
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.


The complex paths we tried to tread, / With extra enums, we were led. / But simple code is best to keep, / So back to basics, while we sleep.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request simplifies policy conditions by removing the decomposed comparison, quantifier, and case_insensitive fields from both Condition and DynamicValueResolver messages, reverting back to using SubjectMappingOperatorEnum directly. The corresponding enums ConditionComparisonOperatorEnum and ConditionQuantifierEnum have been deleted, and the documentation has been updated accordingly. The reviewer suggests reserving field number 3 and the names comparison and case_insensitive in the DynamicValueResolver message to prevent future incompatible reuse, similar to what was done for the Condition message.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread service/policy/objects.proto
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 216.863876ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 111.621393ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 459.656884ms
Throughput 217.55 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 46.147785649s
Average Latency 458.967408ms
Throughput 108.35 requests/second

@alkalescent alkalescent marked this pull request as ready for review June 30, 2026 04:26
@alkalescent alkalescent requested review from a team as code owners June 30, 2026 04:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/openapi/policy/dynamicvaluemapping/dynamic_value_mapping.openapi.yaml`:
- Around line 635-644: The schema for operator currently excludes the wrong enum
value type, so update the `operator` definition in
`dynamic_value_mapping.openapi.yaml` to block the string value used by
`policy.SubjectMappingOperatorEnum` rather than the numeric placeholder. Adjust
the `operator` schema near the `policy.SubjectMappingOperatorEnum` reference so
`not.enum` matches the actual string token for
`SUBJECT_MAPPING_OPERATOR_ENUM_NOT_IN`, keeping the description and `$ref`
aligned with the enum definition.

In `@service/policy/objects.proto`:
- Around line 213-228: The DynamicValueResolver message removed field 3 without
reserving its tag/name, so update that message to reserve the deleted
case_insensitive field the same way Condition reserves removed fields. Add the
reservation in DynamicValueResolver alongside subject_external_selector_value
and operator so the old wire/JSON contract cannot be reused later.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: eb32223c-a262-40d3-a3a3-df6154df3d92

📥 Commits

Reviewing files that changed from the base of the PR and between 78366f7 and 08f2376.

⛔ Files ignored due to path filters (1)
  • protocol/go/policy/objects.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (14)
  • docs/grpc/index.html
  • docs/openapi/policy/actions/actions.openapi.yaml
  • docs/openapi/policy/attributes/attributes.openapi.yaml
  • docs/openapi/policy/dynamicvaluemapping/dynamic_value_mapping.openapi.yaml
  • docs/openapi/policy/objects.openapi.yaml
  • docs/openapi/policy/obligations/obligations.openapi.yaml
  • docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
  • docs/openapi/policy/resourcemapping/resource_mapping.openapi.yaml
  • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
  • docs/openapi/policy/unsafe/unsafe.openapi.yaml
  • protocol/go/internal/policy/enums.go
  • protocol/go/internal/policy/enums_test.go
  • protocol/go/policy/enums.gen.go
  • service/policy/objects.proto
💤 Files with no reviewable changes (3)
  • protocol/go/internal/policy/enums_test.go
  • protocol/go/policy/enums.gen.go
  • protocol/go/internal/policy/enums.go

Comment thread service/policy/objects.proto
Remove the reserved field numbers/names added for the removed comparison,
quantifier, and case_insensitive fields. The decomposed proto surface had no
consumers, so reserving the numbers is unnecessary. Regenerated protocol/go.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 238.508217ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 106.931093ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 483.539919ms
Throughput 206.81 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.767322962s
Average Latency 455.965429ms
Throughput 109.25 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • examples
  • otdfctl
  • sdk
  • service
  • lib/fixtures
  • tests-bdd

See the workflow run for details.

@strantalis strantalis merged commit 84f3b92 into main Jul 1, 2026
43 of 45 checks passed
@strantalis strantalis deleted the fix/undo-operator-decomposition branch July 1, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) docs Documentation size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants