Skip to content

feat(policy): DSPX-3498 dynamic attribute value entitlement mappings#3568

Open
alkalescent wants to merge 5 commits into
mainfrom
DSPX-2754-dynamic-attribute-values-impl
Open

feat(policy): DSPX-3498 dynamic attribute value entitlement mappings#3568
alkalescent wants to merge 5 commits into
mainfrom
DSPX-2754-dynamic-attribute-values-impl

Conversation

@alkalescent

@alkalescent alkalescent commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Important

Depends on #3580 (protocol-first). This PR adds a new protocol/go package, so the per-module go mod tidy CI check stays red until #3580 merges and protocol/go is released. Sequence: merge #3580 → release protocol/go → rebase this branch and bump sdk/service go.mod → CI goes green.

Proposed Changes

Implements the DynamicValueMapping policy primitive end to end (the model chosen by the DSPX-2754 spike / ADR 0005). It raises entitlement authority from a concrete AttributeValue to the AttributeDefinition: a single mapping entitles dynamically-requested values by comparing the requested resource value segment against the entity representation at decision time, instead of pre-provisioning a value + subject mapping per discrete ID (MRNs, account IDs, etc.).

Design highlights (improving on the reference spike):

  • Dedicated operator + resolver (DynamicValueOperatorEnum: RESOURCE_VALUE_IN / RESOURCE_VALUE_IN_CONTAINS, DynamicValueResolver) so dynamic operators stay isolated from static subject-mapping operators and the schema honestly expresses "dynamic".
  • Optional static SubjectConditionSet pre-gate (normal static semantics, no field overload) to support compound "entity attribute AND resource value" conditions.
  • No-coexistence enforced both directions between value-level subject mappings and dynamic mappings on the same definition.
  • HIERARCHY rejected; canonicalized (case/whitespace) value comparison.
  • Dynamic values are first-class in decisioning: they flow into the same entitlements map and ANY_OF / ALL_OF rule layer as static values (manifest stays a list of attribute FQNs).

Wiring: proto + generated code + SDK client; DB migration + sqlc + CRUD; dedicated DynamicValueMappingService; decision-time evaluator; PDP load/merge with synthetic-value support; and authz cache. Replaces the throwaway spike package and ports its tests. GetEntitlements intentionally does not enumerate dynamic values (high-cardinality, resource-scoped).

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 service && go build ./...
  • cd service && go test ./internal/subjectmappingbuiltin/... ./internal/access/v2/... ./authorization/v2/...
  • cd service && golangci-lint run ./internal/subjectmappingbuiltin/... ./internal/access/v2/ ./authorization/v2/ ./policy/db/ ./policy/dynamicvaluemapping/
  • DB-layer CRUD and end-to-end GetDecision verification require a live Postgres/platform and are not included here.

Related

Summary by CodeRabbit

Release Notes

  • New Features

    • Added definition-scoped dynamic value mappings with full CRUD support (create, list, get, update, delete).
    • Added pagination for listing dynamic value mappings by attribute definition.
  • Policy Enforcement

    • Authorization now evaluates dynamic value mappings at the attribute-definition level and merges the resulting entitlements into decisions.
    • Added support for dynamic-synthesized attribute values and multi-value resource entitlement matching (ANY/ALL behavior).
  • Performance & Reliability

    • Dynamic mappings are cached for faster authorization.
  • Validation & Governance

    • Improved validation and coexistence protections, including stricter handling of attribute rule transitions involving dynamic mappings.
  • Documentation & Tests

    • Added ADR and expanded integration/unit test coverage for dynamic mapping behavior and pagination.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

More reviews will be available in 32 minutes and 19 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

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 credits.

🚦 How do rate limits work?

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

For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 65f9b668-1eb8-4a8f-97d9-25cbf3502473

📥 Commits

Reviewing files that changed from the base of the PR and between b3aa840 and fa7dd03.

📒 Files selected for processing (25)
  • service/authorization/v2/cache.go
  • service/integration/dynamic_value_mappings_test.go
  • service/internal/access/v2/helpers.go
  • service/internal/access/v2/helpers_test.go
  • service/internal/access/v2/just_in_time_pdp.go
  • service/internal/access/v2/pdp.go
  • service/internal/access/v2/pdp_dynamic_test.go
  • service/internal/access/v2/policy_store.go
  • service/internal/access/v2/validators.go
  • service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin.go
  • service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin_test.go
  • service/internal/subjectmappingbuiltin/subject_mapping_builtin.go
  • service/logger/audit/constants.go
  • service/pkg/server/services_test.go
  • service/policy/adr/0005-dynamic-attribute-value-entitlements-spike.md
  • service/policy/db/attributes.go
  • service/policy/db/dynamic_value_mappings.go
  • service/policy/db/dynamic_value_mappings.sql.go
  • service/policy/db/migrations/20260618000000_add_dynamic_value_mappings.sql
  • service/policy/db/models.go
  • service/policy/db/queries/dynamic_value_mappings.sql
  • service/policy/db/subject_mappings.go
  • service/policy/db/utils.go
  • service/policy/dynamicvaluemapping/dynamic_value_mapping.go
  • service/policy/policy.go
📝 Walkthrough

Walkthrough

Introduces DynamicValueMapping as a new first-class policy primitive enabling definition-level, high-cardinality attribute value entitlements. Adds a database migration, CRUD service with Connect RPC handlers, a dynamic value mapping evaluation builtin and a refactored EvaluateCondition, PDP integration with decisioning, and authorization cache support with coexistence constraints between dynamic mappings and value-level subject mappings.

Changes

Dynamic Value Mapping Feature

Layer / File(s) Summary
DB schema, models, and SQL queries
service/policy/db/migrations/20260618000000_add_dynamic_value_mappings.sql, service/policy/db/models.go, service/policy/db/queries/dynamic_value_mappings.sql, service/policy/db/dynamic_value_mappings.sql.go
Migration creates dynamic_value_mappings and dynamic_value_mapping_actions tables with foreign keys, resolver fields (subject_external_selector_value, comparison, case_insensitive), optional subject_condition_set static gate, and namespace association; includes trigger and three lookup indexes. Sqlc models DynamicValueMapping and DynamicValueMappingAction added. All CRUD queries (list with filtering/sorting/pagination, get, create with action array unnesting, update with action synchronization, delete) plus three supporting count/lookup queries defined and sqlc-generated.
DB CRUD implementation and coexistence enforcement
service/policy/db/dynamic_value_mappings.go, service/policy/db/attributes.go, service/policy/db/subject_mappings.go, service/policy/db/utils.go
PolicyDBClient CRUD methods: create validates attribute rules (only ANY_OF/ALL_OF), enforces coexistence (rejects if value-level subject mappings exist), resolves namespace and actions, validates consistency across attribute/actions/subject condition set, marshals metadata; get/list/update/delete with hydration. UnsafeUpdateAttribute blocks rule changes to HIERARCHY when dynamic mappings exist. CreateSubjectMapping blocks creation when a dynamic mapping already exists on the definition. Sort-param helpers for dynamic value mapping list queries.
DynamicValueMapping RPC service and registration
service/policy/dynamicvaluemapping/dynamic_value_mapping.go, service/policy/policy.go, service/logger/audit/constants.go, service/go.mod
DynamicValueMappingService implements Create/List/Get/Update/Delete Connect RPC handlers with namespace validation, audit events, and error statusification; config hot-reload via OnConfigUpdate hook; graceful shutdown. Registered in NewRegistrations() alongside existing policy services. ObjectTypeDynamicValueMapping audit constant added. github.com/opentdf/platform/protocol/go bumped to v0.34.0 and github.com/opentdf/platform/sdk to v0.23.0.
Subject mapping builtin: EvaluateCondition rewrite and new dynamic evaluator
service/internal/subjectmappingbuiltin/subject_mapping_builtin.go, service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin.go, service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin_test.go
EvaluateCondition rewritten to decompose comparison and quantifier operators with backward-compatibility normalization for legacy IN/NOT_IN/IN_CONTAINS; new compareEntityValue helper with case-insensitive matching and four comparison behaviors. New EvaluateDynamicValueMappingsWithActions evaluates definition-scoped dynamic mappings: flattens entity properties, iterates decisionable attributes, evaluates optional SubjectConditionSet static gate with AND semantics, compares resolved entity values against resource value segment using resolver's comparison operator and case-insensitivity, merges deduplicated actions into AttributeValueFQNsToActions keyed by value FQN. Six unit tests cover MRN example, canonicalization, CONTAINS operator, static gate (single and multiple subject sets), and cross-definition isolation.
PDP, access helpers, policy store, and validators
service/internal/access/v2/pdp.go, service/internal/access/v2/helpers.go, service/internal/access/v2/policy_store.go, service/internal/access/v2/validators.go, service/internal/access/v2/just_in_time_pdp.go, service/internal/access/v2/helpers_test.go, service/internal/access/v2/pdp_dynamic_test.go
PolicyDecisionPoint stores dynamicMappingsByDefinitionFQN indexed by attribute FQN; NewPolicyDecisionPointWithDynamicValueMappings initializes with validation (skips invalid/unknown/HIERARCHY-rule mappings, optionally skips namespace-missing mappings). GetDecision threads dynamic mapping index into getResourceDecisionableAttributes and calls EvaluateDynamicValueMappingsWithActions before rule evaluation, merging results into entitledFQNsToActions. getResourceDecisionableAttributes synthesizes missing values when either direct entitlements enabled OR dynamic mapping exists. EntitlementPolicyStore and EntitlementPolicyRetriever extended with ListAllDynamicValueMappings (paginated via SDK). validateDynamicValueMapping validates non-nil mapping, non-empty FQN, non-HIERARCHY rule, required selector/comparison, and at least one action. JustInTimePDP loads dynamic mappings and passes them to NewPolicyDecisionPointWithDynamicValueMappings. New PDP test validates multi-value resource entitlement with ANY_OF vs ALL_OF semantics.
Authorization cache integration
service/authorization/v2/cache.go
EntitlementPolicyCache.Refresh fetches dynamic value mappings from retriever and writes to cache under new key; marks isCacheFilled = false only on dynamic write failure. ListAllDynamicValueMappings cache accessor returns empty slice on cache miss, errors on retrieval failure or type mismatch. EntitlementPolicy struct extended with DynamicValueMappings []*policy.DynamicValueMapping field.
Integration test suite for DynamicValueMapping CRUD and constraints
service/integration/dynamic_value_mappings_test.go
DynamicValueMappingsSuite exercises PolicyClient CRUD: create/get with field persistence, static gate hydration with SubjectConditionSet, rejection of HIERARCHY attribute definitions, bidirectional coexistence constraints (dynamic-then-subject vs subject-then-dynamic), rule-change rejection to HIERARCHY, update/delete with verification, and list-by-definition pagination. Helper methods provision fresh attribute definition, standard read action, dynamic value resolver, and subject condition set payload.
Helper and unit test updates
service/internal/access/v2/helpers_test.go, service/pkg/server/services_test.go
helpers_test updated with new nil parameter for dynamic mappings in three direct-entitlements subtests (success case and two error cases); test expectations unchanged. services_test increments numExpectedPolicyServices from 10 to 11 to account for new DynamicValueMappingService registration.
ADR spike documentation
service/policy/adr/0005-dynamic-attribute-value-entitlements-spike.md
ADR 0005 documents DynamicValueMapping spike: motivation for definition-level, high-cardinality entitlements; recommendation for new primitive with RESOURCE_VALUE_IN/RESOURCE_VALUE_IN_CONTAINS operator inversion; option comparisons (reusing subject mappings, adding rule type); edge cases (value-segment FQN constraints, canonicalization, cross-definition isolation, multi-value resources, API enforcement, direct-entitlement overlap); open questions on selector syntax, ERS trust, persistence, canonicalization configuration; out-of-scope items.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant DynamicValueMappingService
    participant PolicyDBClient
    participant AuditLogger

    Client->>DynamicValueMappingService: CreateDynamicValueMapping(req)
    DynamicValueMappingService->>DynamicValueMappingService: validate namespace scoping
    DynamicValueMappingService->>PolicyDBClient: CreateDynamicValueMapping(ctx, r)
    PolicyDBClient->>PolicyDBClient: coexistence check (no subject mappings on definition)
    PolicyDBClient->>PolicyDBClient: validate namespace consistency
    PolicyDBClient->>PolicyDBClient: insert dynamic_value_mappings + action IDs
    PolicyDBClient-->>DynamicValueMappingService: *policy.DynamicValueMapping
    DynamicValueMappingService->>AuditLogger: record create success event
    DynamicValueMappingService-->>Client: CreateDynamicValueMappingResponse
Loading
sequenceDiagram
    rect rgba(70, 130, 180, 0.5)
        Note over JustInTimePDP,PolicyDecisionPoint: PDP initialization with dynamic mappings
    end
    participant JustInTimePDP
    participant EntitlementPolicyRetriever
    participant PolicyDecisionPoint
    participant EvaluateDynamicValueMappingsWithActions

    JustInTimePDP->>EntitlementPolicyRetriever: ListAllDynamicValueMappings(ctx)
    EntitlementPolicyRetriever-->>JustInTimePDP: []*DynamicValueMapping (paginated)
    JustInTimePDP->>PolicyDecisionPoint: NewPolicyDecisionPointWithDynamicValueMappings(allDynamicValueMappings)
    PolicyDecisionPoint->>PolicyDecisionPoint: validate + index mappings by definition FQN

    rect rgba(60, 179, 113, 0.5)
        Note over PolicyDecisionPoint,EvaluateDynamicValueMappingsWithActions: Decision evaluation
    end
    PolicyDecisionPoint->>PolicyDecisionPoint: getResourceDecisionableAttributes(dynamicMappingsByDefinitionFQN)
    PolicyDecisionPoint->>EvaluateDynamicValueMappingsWithActions: mappingsByDefinitionFQN, decisionableAttrs, entityRep
    EvaluateDynamicValueMappingsWithActions->>EvaluateDynamicValueMappingsWithActions: evaluate static gate (SubjectConditionSet)
    EvaluateDynamicValueMappingsWithActions->>EvaluateDynamicValueMappingsWithActions: evaluate value resolver (selector + comparison)
    EvaluateDynamicValueMappingsWithActions-->>PolicyDecisionPoint: entitled FQNs → actions
    PolicyDecisionPoint->>PolicyDecisionPoint: merge into entitledFQNsToActions, apply rules
    PolicyDecisionPoint-->>JustInTimePDP: AccessDecision
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • opentdf/platform#3580: Protocol and SDK types for DynamicValueMapping and DynamicValueResolver, which this PR's PDP and cache layers consume.

Suggested reviewers

  • elizabethhealy
  • c-r33d
  • jakedoublev

Poem

🐇 Hop through the policy land so grand,
Where DynamicValueMappings take a stand!
No more hard-coded values in a row—
Just selectors and comparisons, watch entitlements flow.
The bunny indexed mappings by FQN with care,
And now the PDP grants access with flair! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.94% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title "feat(policy): DSPX-3498 dynamic attribute value entitlement mappings" clearly and specifically summarizes the main change: implementing dynamic attribute value entitlement mappings as a new policy feature.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch DSPX-2754-dynamic-attribute-values-impl

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.

@github-actions github-actions Bot added comp:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) comp:sdk A software development kit, including library, for client applications and inter-service communicati comp:authorization docs Documentation size/xl labels Jun 4, 2026
@github-actions

github-actions Bot commented Jun 4, 2026

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 179.705299ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 405.58654ms
Throughput 246.56 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 46.591212655s
Average Latency 463.808555ms
Throughput 107.32 requests/second

@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 a new policy primitive, DefinitionValueEntitlementMapping, which enables dynamic entitlement mappings at the attribute definition level. This allows for more flexible and scalable authorization by comparing resource values against entity attributes at decision time, rather than relying on pre-provisioned static mappings. The change includes a full end-to-end implementation, including protocol definitions, service logic, database persistence, and integration into the existing policy decision point.

Highlights

  • New Policy Primitive: Introduced the DefinitionValueEntitlementMapping primitive to support dynamic attribute value entitlement at the definition level.
  • Dynamic Evaluation Logic: Added DynamicValueOperatorEnum and DefinitionValueResolver to allow for dynamic comparison of resource values against entity attributes at decision time.
  • Service and Persistence: Implemented a dedicated CRUD service, database migrations, and SQLC queries to manage the new entitlement mappings.
  • PDP Integration: Integrated dynamic mapping evaluation into the Policy Decision Point (PDP) and added caching to maintain performance.
  • Validation and Safety: Enforced no-coexistence rules to prevent conflicts between static value-level subject mappings and new dynamic mappings on the same definition.
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/**/* (21)
    • docs/openapi/authorization/authorization.openapi.yaml
    • docs/openapi/authorization/v2/authorization.openapi.yaml
    • docs/openapi/common/common.openapi.yaml
    • docs/openapi/entity/entity.openapi.yaml
    • docs/openapi/entityresolution/entity_resolution.openapi.yaml
    • docs/openapi/entityresolution/v2/entity_resolution.openapi.yaml
    • docs/openapi/kas/kas.openapi.yaml
    • docs/openapi/policy/actions/actions.openapi.yaml
    • docs/openapi/policy/attributes/attributes.openapi.yaml
    • docs/openapi/policy/definitionvalueentitlement/definition_value_entitlement.openapi.yaml
    • docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml
    • docs/openapi/policy/keymanagement/key_management.openapi.yaml
    • docs/openapi/policy/namespaces/namespaces.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/selectors.openapi.yaml
    • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
    • docs/openapi/policy/unsafe/unsafe.openapi.yaml
    • docs/openapi/wellknownconfiguration/wellknown_configuration.openapi.yaml
  • Ignored by pattern: protocol/**/* (4)
    • protocol/go/policy/definitionvalueentitlement/definition_value_entitlement.pb.go
    • protocol/go/policy/definitionvalueentitlement/definition_value_entitlement_grpc.pb.go
    • protocol/go/policy/definitionvalueentitlement/definitionvalueentitlementconnect/definition_value_entitlement.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.


Dynamic rules now take the stage, No longer static on the page. From definition, values flow, To let the right permissions grow.

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 implements Definition Value Entitlement Mappings (DSPX-2754), which move entitlement authority from concrete attribute values to the attribute definition level. The changes span SDK client generation, caching, PDP evaluation, database storage, and a new gRPC service. The review feedback is highly constructive and identifies several critical issues that should be addressed: a potential data race hazard in the gRPC service, possible nil pointer dereferences in both the PDP evaluator and the database client, a bug in error handling that could return nil values, incorrect type formatting in cache errors, and a redundant database index in the migration script.

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/definitionvalueentitlement/definition_value_entitlement.go Outdated
Comment thread service/authorization/v2/cache.go Outdated
Comment thread service/internal/access/v2/helpers.go Outdated
Comment thread service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin.go Outdated
Comment thread service/policy/db/definition_value_entitlement_mappings.go Outdated
Comment thread service/policy/db/definition_value_entitlement_mappings.go Outdated
@github-actions

github-actions Bot commented Jun 5, 2026

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 185.014087ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 429.531288ms
Throughput 232.81 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.331230891s
Average Latency 441.164371ms
Throughput 112.79 requests/second

@github-actions

github-actions Bot commented Jun 5, 2026

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 193.209357ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 452.432409ms
Throughput 221.03 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 47.779208084s
Average Latency 475.780561ms
Throughput 104.65 requests/second

@github-actions

github-actions Bot commented Jun 5, 2026

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 153.929845ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 411.672475ms
Throughput 242.91 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.358428704s
Average Latency 431.654544ms
Throughput 115.32 requests/second

@github-actions

github-actions Bot commented Jun 5, 2026

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 186.551087ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 444.671341ms
Throughput 224.89 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.347542117s
Average Latency 451.731513ms
Throughput 110.26 requests/second

@github-actions

github-actions Bot commented Jun 8, 2026

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 179.271779ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 449.588328ms
Throughput 222.43 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 47.609789466s
Average Latency 474.175763ms
Throughput 105.02 requests/second

@github-actions

github-actions Bot commented Jun 8, 2026

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 305.274891ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 560.889955ms
Throughput 178.29 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.183073863s
Average Latency 439.810332ms
Throughput 113.17 requests/second

alkalescent added a commit that referenced this pull request Jun 9, 2026
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>
alkalescent added a commit that referenced this pull request Jun 10, 2026
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>
alkalescent added a commit that referenced this pull request Jun 11, 2026
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>
alkalescent added a commit that referenced this pull request Jun 11, 2026
Adds the DynamicValueMapping / DynamicValueResolver messages and
DynamicValueOperatorEnum to objects.proto, and a dedicated
DynamicValueMappingService (policy.dynamicvaluemapping), with regenerated
protocol/go and OpenAPI/gRPC docs. Protocol-first half of DSPX-2754; the consumer
implementation (service/sdk/db/PDP) is PR #3568.

Includes review fixes: namespace oneof + min_len:1/uri + direct validation rules on
CreateDynamicValueMappingRequest; per-field List filter comments; and a
namespace_fqn filter (namespace_id|namespace_fqn oneof) on ListDynamicValueMappingsRequest.

Refs: DSPX-2754, DSPX-3498
Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
alkalescent added a commit that referenced this pull request Jun 15, 2026
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>
alkalescent added a commit that referenced this pull request Jun 15, 2026
Adds the DynamicValueMapping / DynamicValueResolver messages and
DynamicValueOperatorEnum to objects.proto, and a dedicated
DynamicValueMappingService (policy.dynamicvaluemapping), with regenerated
protocol/go and OpenAPI/gRPC docs. Protocol-first half of DSPX-2754; the consumer
implementation (service/sdk/db/PDP) is PR #3568.

Includes review fixes: namespace oneof + min_len:1/uri + direct validation rules on
CreateDynamicValueMappingRequest; per-field List filter comments; and a
namespace_fqn filter (namespace_id|namespace_fqn oneof) on ListDynamicValueMappingsRequest.

Refs: DSPX-2754, DSPX-3498
Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
@alkalescent alkalescent requested a review from a team as a code owner June 18, 2026 19:21
@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 201.122219ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 438.473351ms
Throughput 228.06 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 46.77497537s
Average Latency 466.089327ms
Throughput 106.89 requests/second

@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: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
service/authorization/v2/cache.go (2)

227-233: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add dynamic value mappings count to debug log.

The debug log includes counts for all other cached fields (attributes, subject_mappings, registered_resources, obligations) but omits dynamic_value_mappings_count. This inconsistency reduces observability.

📊 Proposed fix to maintain logging consistency
 	c.logger.DebugContext(ctx,
 		"refreshed EntitlementPolicyCache",
 		slog.Int("attributes_count", len(attributes)),
 		slog.Int("subject_mappings_count", len(subjectMappings)),
+		slog.Int("dynamic_value_mappings_count", len(dynamicValueMappings)),
 		slog.Int("registered_resources_count", len(registeredResources)),
 		slog.Int("obligations_count", len(obligations)),
 	)
🤖 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/authorization/v2/cache.go` around lines 227 - 233, The
c.logger.DebugContext call in the cache refresh log statement is missing the
count of dynamic_value_mappings, while it includes counts for attributes,
subject_mappings, registered_resources, and obligations. Add a new slog.Int
field to the debug log that captures the length of the dynamic_value_mappings
variable with a key name of dynamic_value_mappings_count to maintain consistency
and observability across all cached fields.

17-305: ⚠️ Potential issue | 🟡 Minor

Remove unused variable declarations in cache.go.

golangci-lint reports 2 unused variables that violate the Go code quality standards:

  • Line 32: minRefreshInterval is declared but never used
  • Line 33: maxRefreshInterval is declared but never used

Either remove these declarations or use them if they are intended for future functionality. Tests pass successfully. Run gofumpt -w service/authorization/v2/cache.go locally to verify formatting before finalizing.

🤖 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/authorization/v2/cache.go` around lines 17 - 305, The variables
minRefreshInterval and maxRefreshInterval are declared in the package-level var
block but are never used anywhere in the code, causing a lint violation. Remove
these two variable declarations entirely unless they are intended for future
functionality, in which case add a comment explaining their purpose. After
making this change, run gofumpt to ensure proper formatting.

Source: Coding guidelines

🤖 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/internal/access/v2/pdp.go`:
- Around line 213-224: The current validation only checks if the definitionFQN
exists in allAttributesByDefinitionFQN but does not enforce that the definition
is not a HIERARCHY type. Enhance the validation logic to retrieve the canonical
definition from allAttributesByDefinitionFQN using the definitionFQN key, then
check whether that definition represents a HIERARCHY type. If it is a HIERARCHY
definition, add a warning log and continue to skip indexing the mapping in
dynamicMappingsByDefinitionFQN, similar to how the code currently handles
missing definitions. This ensures that mappings targeting HIERARCHY definitions
are properly rejected regardless of whether AttributeDefinition.Rule is set in
the payload.

In
`@service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin_test.go`:
- Around line 124-160: The test TestEvaluateDynamicValueMappings_StaticGate only
exercises a single SubjectSet within the SubjectConditionSet, leaving the AND/OR
aggregation logic between multiple SubjectSet items untested and vulnerable to
regression. Create a new test case that includes multiple SubjectSet items in
the SubjectConditionSet (similar to the existing test but with multiple subject
sets), and verify the expected behavior when combining multiple condition sets
with different AND/OR operators. Include test scenarios that validate both
passing and failing cases across the multiple subject set aggregation to ensure
the gate behavior is correctly locked in.

In `@service/policy/db/dynamic_value_mappings.go`:
- Around line 189-211: The update flow for dynamic value mappings is missing
namespace consistency validation that is enforced in the create path. Add a call
to validateDynamicValueMappingNamespaceConsistency in the update method (similar
to the create flow) to ensure that the actionIDs resolved via
resolveSubjectMappingActions and the SubjectConditionSetID being updated are
consistent with the targetNamespaceID. This validation should be applied after
populating the updateParams struct to prevent cross-namespace references from
being introduced through updates.

In `@service/policy/db/queries/dynamic_value_mappings.sql`:
- Around line 199-200: The deleteDynamicValueMapping query has a SQLFluff LT14
formatting violation because the WHERE clause is on the same line as the DELETE
statement. Move the WHERE clause to a new line so that the WHERE keyword starts
on its own line after the DELETE FROM dynamic_value_mappings statement,
following proper SQL formatting standards.
- Around line 171-190: The action_delete and action_insert CTEs are executing
regardless of whether mapping_update successfully found and updated a row, which
can cause foreign-key errors when the mapping doesn't exist. Add a condition to
both action_delete and action_insert CTEs that checks whether the mapping with
the given id actually exists (or was successfully updated) before attempting to
delete or insert actions. This ensures these mutations only proceed when the
parent mapping update is successful, preventing concurrent deletes from turning
into deterministic not-found errors.

In `@service/policy/db/subject_mappings.go`:
- Around line 270-274: The no-coexistence enforcement in the current create
method and its reciprocal check in CreateDynamicValueMapping lack atomicity,
allowing concurrent requests to bypass the
ensureNoDynamicValueMappingCoexistence check and CreateDynamicValueMapping's
corresponding check. Add definition-level serialization (such as a locking
mechanism keyed by definition ID) that protects the entire check-then-insert
operation in both create paths, ensuring that only one concurrent request can
perform the validation and insert for the same definition at a time.

In `@service/policy/dynamicvaluemapping/dynamic_value_mapping.go`:
- Around line 27-37: The `OnConfigUpdate` function writes to `svc.config` and
`svc.dbClient` without synchronization, creating a data race when handlers read
these fields concurrently. Add a sync.RWMutex field to the
DynamicValueMappingService struct to protect these shared fields, then acquire
the write lock before updating `svc.config` and `svc.dbClient` in the
`OnConfigUpdate` function. Ensure all other code paths that read or write to
these fields also use the appropriate locking mechanism (RLock for reads, Lock
for writes).
- Around line 90-106: The PolicyCRUDSuccess audit call in the RunInTx callback
is logged before the transaction commit is confirmed, meaning it will record
success even if the transaction fails during commit. Move the audit success
logging (the s.logger.Audit.PolicyCRUDSuccess call and the auditParams
assignments for ObjectID and Original) outside and after the RunInTx call, so it
only executes after the entire transaction including commit has completed
successfully, specifically after verifying that err is nil from the RunInTx
operation.

---

Outside diff comments:
In `@service/authorization/v2/cache.go`:
- Around line 227-233: The c.logger.DebugContext call in the cache refresh log
statement is missing the count of dynamic_value_mappings, while it includes
counts for attributes, subject_mappings, registered_resources, and obligations.
Add a new slog.Int field to the debug log that captures the length of the
dynamic_value_mappings variable with a key name of dynamic_value_mappings_count
to maintain consistency and observability across all cached fields.
- Around line 17-305: The variables minRefreshInterval and maxRefreshInterval
are declared in the package-level var block but are never used anywhere in the
code, causing a lint violation. Remove these two variable declarations entirely
unless they are intended for future functionality, in which case add a comment
explaining their purpose. After making this change, run gofumpt to ensure proper
formatting.
🪄 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: 56a7d11e-1ec4-421c-ad88-d93b64af9468

📥 Commits

Reviewing files that changed from the base of the PR and between 5841bbe and 9a9fb61.

⛔ Files ignored due to path filters (1)
  • service/go.sum is excluded by !**/*.sum
📒 Files selected for processing (25)
  • service/authorization/v2/cache.go
  • service/go.mod
  • service/integration/dynamic_value_mappings_test.go
  • service/internal/access/v2/helpers.go
  • service/internal/access/v2/helpers_test.go
  • service/internal/access/v2/just_in_time_pdp.go
  • service/internal/access/v2/pdp.go
  • service/internal/access/v2/pdp_dynamic_test.go
  • service/internal/access/v2/policy_store.go
  • service/internal/access/v2/validators.go
  • service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin.go
  • service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin_test.go
  • service/internal/subjectmappingbuiltin/subject_mapping_builtin.go
  • service/logger/audit/constants.go
  • service/policy/adr/0005-dynamic-attribute-value-entitlements-spike.md
  • service/policy/db/attributes.go
  • service/policy/db/dynamic_value_mappings.go
  • service/policy/db/dynamic_value_mappings.sql.go
  • service/policy/db/migrations/20260618000000_add_dynamic_value_mappings.sql
  • service/policy/db/models.go
  • service/policy/db/queries/dynamic_value_mappings.sql
  • service/policy/db/subject_mappings.go
  • service/policy/db/utils.go
  • service/policy/dynamicvaluemapping/dynamic_value_mapping.go
  • service/policy/policy.go

Comment thread service/internal/access/v2/pdp.go
Comment thread service/policy/db/dynamic_value_mappings.go
Comment thread service/policy/db/queries/dynamic_value_mappings.sql
Comment thread service/policy/db/queries/dynamic_value_mappings.sql
Comment thread service/policy/db/subject_mappings.go
Comment thread service/policy/dynamicvaluemapping/dynamic_value_mapping.go
Comment thread service/policy/dynamicvaluemapping/dynamic_value_mapping.go
@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 187.962122ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 439.211994ms
Throughput 227.68 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 46.226501975s
Average Latency 459.54918ms
Throughput 108.16 requests/second

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

@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 197.835903ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 478.662501ms
Throughput 208.92 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.603170723s
Average Latency 454.301924ms
Throughput 109.64 requests/second

@alkalescent alkalescent changed the title feat(policy): DSPX-2754 dynamic attribute value entitlement mappings feat(policy): DSPX-3498 dynamic attribute value entitlement mappings Jun 22, 2026
@alkalescent alkalescent force-pushed the DSPX-2754-dynamic-attribute-values-impl branch from 91a8596 to dd6d7e9 Compare June 22, 2026 18:13
@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 206.781026ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 501.76112ms
Throughput 199.30 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 46.939463063s
Average Latency 466.969482ms
Throughput 106.52 requests/second

@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 `@service/integration/dynamic_value_mappings_test.go`:
- Around line 181-196: The TestListByDefinition test currently only creates a
single dynamic value mapping and verifies its retrieval, but does not test
pagination semantics. Extend this test to create multiple dynamic value mappings
(enough to span multiple pages), then call ListDynamicValueMappings with
pagination parameters (such as limit or page_token) to validate that page
boundaries are respected and continuation tokens work correctly. This will
ensure the pagination path in the ListDynamicValueMappings method is properly
covered by the test.

In `@service/policy/db/queries/dynamic_value_mappings.sql`:
- Around line 158-197: The updateDynamicValueMapping query at line 158 is
annotated with :execrows but returns a result set using SELECT cnt FROM
update_count. The :execrows annotation causes sqlc to generate code that calls
RowsAffected(), which returns -1 for SELECT statements instead of the actual
count value, breaking the not-found detection logic. Change the query annotation
from :execrows to :one so that sqlc generates code that properly scans and
returns the cnt value from the result set.
🪄 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: efad754f-1ae8-40f5-b279-0cd8de81b6f7

📥 Commits

Reviewing files that changed from the base of the PR and between 91a8596 and dd6d7e9.

⛔ Files ignored due to path filters (1)
  • service/go.sum is excluded by !**/*.sum
📒 Files selected for processing (26)
  • service/authorization/v2/cache.go
  • service/go.mod
  • service/integration/dynamic_value_mappings_test.go
  • service/internal/access/v2/helpers.go
  • service/internal/access/v2/helpers_test.go
  • service/internal/access/v2/just_in_time_pdp.go
  • service/internal/access/v2/pdp.go
  • service/internal/access/v2/pdp_dynamic_test.go
  • service/internal/access/v2/policy_store.go
  • service/internal/access/v2/validators.go
  • service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin.go
  • service/internal/subjectmappingbuiltin/dynamic_value_mapping_builtin_test.go
  • service/internal/subjectmappingbuiltin/subject_mapping_builtin.go
  • service/logger/audit/constants.go
  • service/pkg/server/services_test.go
  • service/policy/adr/0005-dynamic-attribute-value-entitlements-spike.md
  • service/policy/db/attributes.go
  • service/policy/db/dynamic_value_mappings.go
  • service/policy/db/dynamic_value_mappings.sql.go
  • service/policy/db/migrations/20260618000000_add_dynamic_value_mappings.sql
  • service/policy/db/models.go
  • service/policy/db/queries/dynamic_value_mappings.sql
  • service/policy/db/subject_mappings.go
  • service/policy/db/utils.go
  • service/policy/dynamicvaluemapping/dynamic_value_mapping.go
  • service/policy/policy.go

Comment thread service/integration/dynamic_value_mappings_test.go
Comment thread service/policy/db/queries/dynamic_value_mappings.sql

@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: 1

🤖 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/integration/dynamic_value_mappings_test.go`:
- Around line 209-227: The pagination test validates offsets and counts but does
not verify that the actual items in each page are distinct. After collecting the
responses from the first and second ListDynamicValueMappings calls, extract the
IDs from each page's GetDynamicValueMappings() results and add assertions to
ensure there is no overlap between the two sets of IDs. Additionally, verify
that the union of all IDs from both pages equals the total count of 3 to ensure
complete coverage without gaps or duplicates across the paginated results.
🪄 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: 1dcd856b-6591-4975-9f30-950eff2a27a6

📥 Commits

Reviewing files that changed from the base of the PR and between dd6d7e9 and b3aa840.

📒 Files selected for processing (1)
  • service/integration/dynamic_value_mappings_test.go

Comment thread service/integration/dynamic_value_mappings_test.go
@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 210.626671ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 463.119798ms
Throughput 215.93 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.072538709s
Average Latency 438.423865ms
Throughput 113.45 requests/second

@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 201.793825ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 424.774648ms
Throughput 235.42 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.97387517s
Average Latency 448.418319ms
Throughput 111.18 requests/second

Service consumer for dynamic value mappings, built on protocol/go v0.34.0 and
sdk v0.23.0:

- DB: dynamic_value_mappings table + queries + CRUD, no-coexistence guard with
  value-level subject mappings, comparison + case_insensitive columns.
- Service: DynamicValueMappingService, validators, and PDP wiring that loads
  dynamic mappings via the SDK and evaluates them alongside subject mappings.
- Evaluation: shared comparison helper (EQUALS/CONTAINS/STARTS_WITH/ENDS_WITH)
  used by both static conditions (with quantifier + deprecated-operator
  normalization) and the dynamic resolver (existential, case_insensitive).

protocol/go protos, the dynamicvaluemapping package, and the sdk wrapper landed
in #3580 and #3635; this PR bumps to those releases.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
…ing indexing

- Bump numExpectedPolicyServices to 11 now that DynamicValueMappingService is
  registered (fixes the go (service) CI failure).
- PDP: skip HIERARCHY attribute definitions when indexing dynamic value mappings,
  using the canonical definition map (defense in depth vs an unset payload rule).
- Add a multi-SubjectSet static-gate test to lock the AND aggregation across
  subject sets.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
…te value

ensureNoDynamicValueMappingCoexistence ran on the CreateSubjectMapping path and
returned ErrNotFound for a non-existent attribute value, masking the foreign-key
violation that the create insert previously surfaced. Treat a not-found value as
"nothing to guard" and return nil so the normal create path reports
ErrForeignKeyViolation. The coexistence guard still fires for existing values.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
Add TestListByDefinition_Pagination asserting page boundaries (Total and
NextOffset) across multiple dynamic value mappings on one definition, matching
the subject-mapping list pagination coverage.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
…rlap

Strengthen TestListByDefinition_Pagination to verify the paginated pages
partition the corpus: page items are distinct, page 2 does not repeat page 1,
and the union covers all created mappings exactly once.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
@alkalescent alkalescent force-pushed the DSPX-2754-dynamic-attribute-values-impl branch from 99f98fc to fa7dd03 Compare June 23, 2026 19:02
@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 180.332433ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 462.319509ms
Throughput 216.30 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 46.854077811s
Average Latency 466.146265ms
Throughput 106.71 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:authorization comp:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) comp:sdk A software development kit, including library, for client applications and inter-service communicati docs Documentation size/xl

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants