Skip to content

feat(policy): DSPX-2754 DynamicValueMapping protos + generated code#3580

Open
alkalescent wants to merge 2 commits into
mainfrom
DSPX-2754-protocol-dynamic-value-mapping
Open

feat(policy): DSPX-2754 DynamicValueMapping protos + generated code#3580
alkalescent wants to merge 2 commits into
mainfrom
DSPX-2754-protocol-dynamic-value-mapping

Conversation

@alkalescent
Copy link
Copy Markdown
Contributor

@alkalescent alkalescent commented Jun 5, 2026

Proposed Changes

  • Protocol-first half of the dynamic attribute value entitlement feature (DSPX-2754). Adds the DynamicValueMapping / DynamicValueResolver messages and DynamicValueOperatorEnum to objects.proto, plus a dedicated DynamicValueMappingService in a new policy.dynamicvaluemapping package. Includes regenerated protocol/go and OpenAPI/gRPC docs.
  • No service implementation, DB, SDK client, or PDP wiring here. Those land in the consumer PR.

Why split: the dedicated service introduces a new protocol/go package. The per-module go mod tidy CI check does not use the go workspace, so consumer modules cannot tidy against a package that is not yet in a released protocol/go. Landing and releasing protocol/go first lets the consumer PR require the new version and pass CI.

Checklist

  • I have added or updated unit tests
  • I have added or updated integration tests (if appropriate)
  • I have added or updated documentation

Testing Instructions

  • cd protocol/go && go build ./... && GOFLAGS=-mod=mod go mod tidy (clean)
  • buf lint service

Related

Summary by CodeRabbit

  • New Features

    • Added Dynamic Value Mapping service with Create, Read, List, Update, and Delete operations for managing dynamic value mappings.
    • Introduced dynamic value operators and resolvers to support dynamic resource value resolution at decision time.
  • Documentation

    • Updated OpenAPI specifications with new dynamic value mapping API definitions and improved formatting in authorization schema documentation.

Protocol-first half of the dynamic attribute value entitlement work: adds the
DynamicValueMapping / DynamicValueResolver messages and DynamicValueOperatorEnum to
objects.proto, and a dedicated DynamicValueMappingService
(policy.dynamicvaluemapping), plus regenerated protocol/go and OpenAPI/gRPC docs.

No service implementation here. This lands and releases protocol/go first so the
consumer PR (#3568) can require the new version and pass per-module 'go mod tidy'.

Refs: DSPX-2754, DSPX-3498
Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2026

Too many files changed? Review this PR in Change Stack to see how the pieces fit before you dive in.

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces the Dynamic Value Mapping feature, a new entitlement model enabling runtime resolution of resource value segments. It includes Protobuf domain objects and service contracts, complete OpenAPI documentation, generated Go Connect-RPC bindings, and minor formatting updates to existing specs and module configuration.

Changes

Dynamic Value Mapping Feature

Layer / File(s) Summary
Domain Model: DynamicValueMapping, Resolver, and Operators
service/policy/objects.proto, docs/openapi/policy/objects.openapi.yaml
Introduces DynamicValueOperatorEnum (exact match, substring, with inversion), DynamicValueResolver (selector + operator pair), and DynamicValueMapping (attribute definition linked to resolver, optional pre-gate, permitted actions, namespace, metadata).
Service Contract and CRUD Operations
service/policy/dynamicvaluemapping/dynamic_value_mapping.proto
Defines DynamicValueMappingService with LIST/GET/CREATE/UPDATE/DELETE operations, including sorting, pagination, field validation (UUIDs, CEL constraints, oneof scoping), and idempotency markers on reads.
OpenAPI Specification and Documentation
docs/openapi/policy/dynamicvaluemapping/dynamic_value_mapping.openapi.yaml
Complete OpenAPI 3.1 spec with POST endpoints for all five operations, component schemas for request/response DTOs, domain model definitions, shared metadata/connection types, and service routing.
Generated Go Connect-RPC Bindings
protocol/go/policy/dynamicvaluemapping/dynamicvaluemappingconnect/dynamic_value_mapping.connect.go
Auto-generated client interface with constructor, client method implementations, handler interface with HTTP routing, handler constructor, and unimplemented stub handler.
Supporting Changes: Whitespace Formatting and Toolchain
docs/openapi/authorization/authorization.openapi.yaml, docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml, protocol/go/go.mod
Whitespace/newline formatting adjustments in authorization and subject mapping specs, plus Go module toolchain directive.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • c-r33d
  • dmihalcik-virtru

Poem

🐰 A rabbit hops through dynamic paths,
Resolving values at runtime's behest,
Where operators dance and conditions rest,
New mappings bloom in the policy grass.

🚥 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 main change: introducing DynamicValueMapping proto definitions and generated code as part of the DSPX-2754 feature.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch DSPX-2754-protocol-dynamic-value-mapping

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


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 and usage tips.

@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 implements the protocol-first phase of the dynamic attribute value entitlement feature (DSPX-2754). By introducing new protobuf messages and a dedicated service, it establishes the foundation for resolving entitlement authority dynamically at decision time, moving away from static pre-provisioning. This change is isolated to the protocol layer to facilitate modular go module management and dependency resolution for future consumer implementations.

Highlights

  • Dynamic Value Mapping Protocol: Introduced the DynamicValueMapping and DynamicValueResolver messages to enable dynamic attribute value entitlement, allowing for entitlement decisions based on entity representation at runtime.
  • New Service Definition: Added the DynamicValueMappingService with full CRUD capabilities (List, Get, Create, Update, Delete) to manage these new dynamic mappings.
  • Operator Extension: Added DynamicValueOperatorEnum to service/policy/objects.proto to support resource value comparison operations like IN and IN_CONTAINS.
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/**/* (4)
    • docs/openapi/authorization/authorization.openapi.yaml
    • docs/openapi/policy/dynamicvaluemapping/dynamic_value_mapping.openapi.yaml
    • docs/openapi/policy/objects.openapi.yaml
    • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
  • Ignored by pattern: protocol/**/* (5)
    • protocol/go/go.mod
    • protocol/go/policy/dynamicvaluemapping/dynamic_value_mapping.pb.go
    • protocol/go/policy/dynamicvaluemapping/dynamic_value_mapping_grpc.pb.go
    • protocol/go/policy/dynamicvaluemapping/dynamicvaluemappingconnect/dynamic_value_mapping.connect.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 values shift and flow in time, Dynamic logic, reason's climb. With proto structures clearly set, The policy engine's not done yet.

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.

@github-actions github-actions Bot added comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) docs Documentation size/m labels Jun 5, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

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 introduces a new DynamicValueMappingService along with its CRUD operations and associated protobuf definitions, such as DynamicValueResolver and DynamicValueOperatorEnum, to support dynamic, definition-level value entitlement. The review feedback highlights several opportunities to improve validation in CreateDynamicValueMappingRequest, including ensuring consistent FQN validation, enforcing mutual exclusivity between namespace fields, and simplifying CEL expressions by leveraging standard validation rules.

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/dynamicvaluemapping/dynamic_value_mapping.proto
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 336.832358ms
Throughput 296.88 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 33.216360399s
Average Latency 330.581872ms
Throughput 150.53 requests/second

Address review: add namespace_id/namespace_fqn oneof, use min_len:1 + uri on FQN
fields, and replace verbose CEL with direct uuid/uri rules (consistent with
CreateSubjectMappingRequest; protovalidate skips unset oneof members).

Refs: DSPX-2754, DSPX-3498
Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
alkalescent added a commit that referenced this pull request Jun 5, 2026
Mirror the proto validation fix from #3580 (namespace oneof, min_len:1 + uri on FQN
fields, direct uuid/uri rules) so the consumer branch stays in sync.

Refs: DSPX-2754, DSPX-3498
Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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.437717ms
Throughput 217.66 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 46.966216532s
Average Latency 467.832798ms
Throughput 106.46 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

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

See the workflow run for details.

@alkalescent alkalescent marked this pull request as ready for review June 5, 2026 21:56
@alkalescent alkalescent requested review from a team as code owners June 5, 2026 21:56
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 `@service/policy/dynamicvaluemapping/dynamic_value_mapping.proto`:
- Around line 41-42: The comment on the field namespace_id is
incorrect/misleading; update the comment for the field namespace_id (in the
dynamic value mapping proto) to remove the reference to Attribute Definition ID
and clearly state it is the Namespace ID to filter by (e.g., "Namespace ID to
filter by"), leaving the separate attribute_definition_id field’s own comment
unchanged so generated docs no longer conflate the two.
- Around line 72-75: The schema currently enforces exclusivity via
buf.validate.message.oneof (validation-only) for the fields namespace_id and
namespace_fqn, which doesn't get reflected in generated OpenAPI; change the
proto to make these mutually exclusive at the protobuf level by moving
namespace_id and namespace_fqn into a real oneof (e.g., oneof namespace_selector
{ string namespace_id = X; string namespace_fqn = Y; }) so the generated OpenAPI
includes the exclusivity, and apply the same change for the other occurrence
mentioned (lines ~107-114) where the buf.validate.message.oneof is used; keep
the field names namespace_id and namespace_fqn and ensure tags/types remain
consistent when creating the oneof.
🪄 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: 231eabb5-f6b3-45c3-8567-e28d9b8703af

📥 Commits

Reviewing files that changed from the base of the PR and between 626ce47 and e0f9220.

⛔ Files ignored due to path filters (3)
  • protocol/go/policy/dynamicvaluemapping/dynamic_value_mapping.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/dynamicvaluemapping/dynamic_value_mapping_grpc.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/objects.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (9)
  • docs/grpc/index.html
  • docs/openapi/authorization/authorization.openapi.yaml
  • docs/openapi/policy/dynamicvaluemapping/dynamic_value_mapping.openapi.yaml
  • docs/openapi/policy/objects.openapi.yaml
  • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
  • protocol/go/go.mod
  • protocol/go/policy/dynamicvaluemapping/dynamicvaluemappingconnect/dynamic_value_mapping.connect.go
  • service/policy/dynamicvaluemapping/dynamic_value_mapping.proto
  • service/policy/objects.proto

Comment on lines +41 to +42
// Namespace ID, or Attribute Definition ID to filter by
string namespace_id = 1 [(buf.validate.field).cel = {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the filter description typo.

The namespace_id comment currently says “Namespace ID, or Attribute Definition ID to filter by”, but attribute_definition_id is a separate field. This text propagates into generated docs and is misleading.

Suggested edit
-  // Namespace ID, or Attribute Definition ID to filter by
+  // Namespace ID to filter by
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Namespace ID, or Attribute Definition ID to filter by
string namespace_id = 1 [(buf.validate.field).cel = {
// Namespace ID to filter by
string namespace_id = 1 [(buf.validate.field).cel = {
🤖 Prompt for 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.

In `@service/policy/dynamicvaluemapping/dynamic_value_mapping.proto` around lines
41 - 42, The comment on the field namespace_id is incorrect/misleading; update
the comment for the field namespace_id (in the dynamic value mapping proto) to
remove the reference to Attribute Definition ID and clearly state it is the
Namespace ID to filter by (e.g., "Namespace ID to filter by"), leaving the
separate attribute_definition_id field’s own comment unchanged so generated docs
no longer conflate the two.

Comment on lines +72 to +75
option (buf.validate.message).oneof = {
fields: ["namespace_id", "namespace_fqn"]
required: false
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Promote namespace selector exclusivity into the schema contract (not validation-only).

namespace_id/namespace_fqn exclusivity is currently enforced via buf.validate.message.oneof, but the generated OpenAPI schema does not encode that constraint. This creates client/server contract drift: OpenAPI-based clients can send both fields and get runtime validation failures.

Proto-level approach to preserve exclusivity in downstream generated schemas
-  // Optional: Namespace ID or FQN to scope the mapping to
-  option (buf.validate.message).oneof = {
-    fields: ["namespace_id", "namespace_fqn"]
-    required: false
-  };
@@
-  // Optional: namespace ID or FQN for the mapping
-  string namespace_id = 7 [(buf.validate.field).string.uuid = true];
-  string namespace_fqn = 8 [
-    (buf.validate.field).string = {
-      min_len: 1
-      uri: true
-    }
-  ];
+  // Optional: namespace ID or FQN for the mapping
+  oneof namespace_selector {
+    string namespace_id = 7 [(buf.validate.field).string.uuid = true];
+    string namespace_fqn = 8 [
+      (buf.validate.field).string = {
+        min_len: 1
+        uri: true
+      }
+    ];
+  }

Based on learnings, docs/openapi/policy/*.openapi.yaml is auto-generated, so this should be fixed in proto and then regenerated (not patched directly in YAML).

Also applies to: 107-114

🤖 Prompt for 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.

In `@service/policy/dynamicvaluemapping/dynamic_value_mapping.proto` around lines
72 - 75, The schema currently enforces exclusivity via
buf.validate.message.oneof (validation-only) for the fields namespace_id and
namespace_fqn, which doesn't get reflected in generated OpenAPI; change the
proto to make these mutually exclusive at the protobuf level by moving
namespace_id and namespace_fqn into a real oneof (e.g., oneof namespace_selector
{ string namespace_id = X; string namespace_fqn = Y; }) so the generated OpenAPI
includes the exclusivity, and apply the same change for the other occurrence
mentioned (lines ~107-114) where the buf.validate.message.oneof is used; keep
the field names namespace_id and namespace_fqn and ensure tags/types remain
consistent when creating the oneof.

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/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant