Skip to content

fix(policy): include action_attribute_values in GetRegisteredResource response#3472

Merged
pflynn-virtru merged 3 commits into
opentdf:mainfrom
pflynn-virtru:fix/issue-3471-getrr-action-attribute-values
May 13, 2026
Merged

fix(policy): include action_attribute_values in GetRegisteredResource response#3472
pflynn-virtru merged 3 commits into
opentdf:mainfrom
pflynn-virtru:fix/issue-3471-getrr-action-attribute-values

Conversation

@pflynn-virtru

@pflynn-virtru pflynn-virtru commented May 13, 2026

Copy link
Copy Markdown
Member

Summary

GetRegisteredResource returned each value with only id, value, and fqn populated — the action_attribute_values field was always empty even when mappings existed. Callers that authorize on (resource, action) → attributes via this RPC were silently denied; GetRegisteredResourceValue returned the same value with mappings populated, exposing the divergence.

Root cause: the getRegisteredResource SQL in service/policy/db/queries/registered_resources.sql built each value's JSON object with only id and value. listRegisteredResources already used the correct LEFT JOIN LATERAL pattern; this PR mirrors it into the single-resource query and regenerates the sqlc binding. The follow-up commit also wraps the inner JSON_AGG in both queries with COALESCE(..., '[]'::json) so a value with no mappings produces an empty array rather than SQL NULL.

Fixes #3471

Why this is different from #3398

PR #3398 (also a "hydrate a nested field that some queries populate and others don't" change, on ListAttributes) was closed with the explanation that ListAttributes is on a lot of hot paths and the team would rather pursue selectors/expanders than expand the default response payload. That concern is real for paginated list RPCs but does not apply to this change:

  • Bug fix, not feature expansion. GetRegisteredResource is the only sibling that fails to populate action_attribute_values. ListRegisteredResources and GetRegisteredResourceValue both already hydrate it. The proto field RegisteredResourceValue.action_attribute_values is declared and documented; leaving it empty here is divergence, not an opt-in payload addition.
  • Silent authorization failures in production. Downstream callers that read value.GetActionAttributeValues() off the GetRegisteredResource response see an empty slice and deny the request with "no attribute mappings found for resource", even though the mappings exist in the database and are returned by every sibling RPC. This is the bug described in GetRegisteredResource omits action_attribute_values from nested values #3471 — not a payload-completeness preference.
  • Not a hot-path list endpoint. GetRegisteredResource is a single-item lookup by id or name. The cardinality argument that motivated closing feat(policy): hydrate resource_mappings on ListAttributes values #3398 (thousands of attribute values × N mappings each, on a frequently-called paginated endpoint) does not transfer.
  • No proto change, no new field, no new opt-in toggle. The shape this PR returns is already what listRegisteredResources returns today.

If the team would prefer to address this through a GetRegisteredResourceWithMappings selector or an expand=action_attribute_values parameter instead of fixing the divergence inline, happy to redirect — but the silent-denial bug is real and the rest of the policy DB queries already treat populating this field as the default.

Test plan

  • Wrote failing integration test first; confirmed it fails against unfixed SQL with Should NOT be empty, but was [] (red-green verified).
  • Confirmed it passes after the SQL fix.
  • Full TestRegisteredResourcesSuite integration suite passes (testcontainers/postgres) — both the new test and the existing fixture-based tests against values with no AAVs.
  • go test ./service/policy/... unit tests pass.
  • golangci-lint run on changed files: 0 new issues.
  • gofumpt clean on changed Go files.
  • Reviewer: re-verify with cd service && go test ./integration/ -run TestRegisteredResourcesSuite -count=1.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests

    • Added integration test for retrieving registered resources with action attribute values.
    • Enhanced existing test with stricter validation of namespaced action information and attribute identifiers.
  • Bug Fixes

    • Registered resources now properly return action attribute values with complete namespace details when fetched.

Review Change Stack

… response

The getRegisteredResource SQL query built each value's JSON object with
only id and value, omitting action_attribute_values even when mappings
existed. Callers that authorize on (resource, action) -> attributes via
GetRegisteredResource were silently denied because the field came back
empty, while GetRegisteredResourceValue for the same value id returned
the populated mappings.

Mirror the LATERAL join pattern already used in listRegisteredResources
so action_attribute_values is aggregated per resource value, and add a
matching integration test (the existing list-side test masked the gap).

Fixes opentdf#3471

Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7aa847d3-dad6-433c-b211-0785ea211b3d

📥 Commits

Reviewing files that changed from the base of the PR and between 8473d21 and a208168.

📒 Files selected for processing (3)
  • service/integration/registered_resources_test.go
  • service/policy/db/queries/registered_resources.sql
  • service/policy/db/registered_resources.sql.go

📝 Walkthrough

Walkthrough

Queries for registered resources now include per-value action_attribute_values (aggregated via LEFT JOIN LATERAL and COALESCE) and generated sqlc code and tests were updated/added to assert the action namespace (name/FQN) and attribute identifiers for both list and get endpoints.

Changes

Action-Attribute-Values propagation

Layer / File(s) Summary
getRegisteredResource: add action_attribute_values via LATERAL
service/policy/db/queries/registered_resources.sql, service/policy/db/registered_resources.sql.go
getRegisteredResource now populates each values element with an action_attribute_values JSON array built by a correlated LEFT JOIN LATERAL aggregating registered_resource_action_attribute_values joined to actions and attribute_values; generated sqlc code and inline comments updated to match.
listRegisteredResources: inline FQN + COALESCE for action_attribute_values
service/policy/db/queries/registered_resources.sql, service/policy/db/registered_resources.sql.go
listRegisteredResources was updated to include action_attribute_values per value, compute action namespace FQNs inline (CONCAT) and wrap JSON aggregation with COALESCE(..., '[]'::json) to ensure a consistent empty-array shape when mappings are absent.
Integration tests asserting action_attribute_values presence
service/integration/registered_resources_test.go
Tightens Test_ListRegisteredResources_RegResValuesContainActionAttributeValues assertions to inspect the created resource and its per-value ActionAttributeValues, and adds Test_GetRegisteredResource_RegResValuesContainActionAttributeValues to create a namespaced resource with two values (create/update) and assert both returned values contain the expected ActionAttributeValues including action namespace name and FQN and attribute value FQNs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • opentdf/platform#3206: Modifies registered resource action-attribute mapping handling and same-namespace resolution/validation during mapping creation; likely related to how action/attribute FQNs are resolved.

Suggested labels

size/m

Suggested reviewers

  • elizabethhealy

Poem

🐰
I hopped through rows and joined them tight,
LATERAL filled the gaps tonight,
Actions and attributes, side by side,
No empty lists where truths reside,
A grateful rabbit taps the keys in delight.

🚥 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 primary fix: including action_attribute_values in the GetRegisteredResource response to resolve the bug described in the linked issue.
Linked Issues check ✅ Passed The PR fully addresses issue #3471: the SQL changes add action_attribute_values to getRegisteredResource by mirroring the LEFT JOIN LATERAL pattern from listRegisteredResources, includes COALESCE wrapping for empty arrays, and test additions validate the fix.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the identified bug: SQL query updates, sqlc binding regeneration, test additions, and documentation comments are all focused on populating action_attribute_values in the GetRegisteredResource response.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 addresses a data inconsistency where the GetRegisteredResource RPC was failing to return action_attribute_values for registered resources. By updating the underlying SQL query to correctly join and aggregate these values, the response now accurately reflects the associated mappings, ensuring consistent behavior with other parts of the system.

Highlights

  • SQL Query Update: Updated the getRegisteredResource SQL query to include a LEFT JOIN LATERAL that correctly fetches and aggregates action_attribute_values for each resource value.
  • SQLC Regeneration: Regenerated the Go bindings using sqlc to reflect the updated database schema and query structure.
  • Integration Testing: Added a new integration test Test_GetRegisteredResource_RegResValuesContainActionAttributeValues to verify that action attribute values are correctly populated in the API response.
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.

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 query was missing a join, Data hidden, a point to adjoin. With lateral power, We fixed the dark hour, And now the results will purloin.

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:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) size/s labels May 13, 2026

@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 enhances the retrieval of registered resources by updating the database queries to include action attribute values. The SQL logic now utilizes a lateral join to aggregate action and attribute metadata, including namespaces and fully qualified names (FQNs), into the JSON output for resource values. A new integration test was added to verify that these attributes are correctly returned and namespaced. Feedback was provided to refactor the verification loop in the new test to reduce code duplication and improve maintainability.

Comment thread service/integration/registered_resources_test.go Outdated
@pflynn-virtru
pflynn-virtru marked this pull request as ready for review May 13, 2026 16:20
@pflynn-virtru
pflynn-virtru requested review from a team as code owners May 13, 2026 16:20
@pflynn-virtru
pflynn-virtru requested a review from Copilot May 13, 2026 16:24
@pflynn-virtru

Copy link
Copy Markdown
Member Author

@coderabbitai help

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai rate limit to show your current review rate limit status.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai evaluate custom pre-merge check --instructions <custom-checks-instructions> --name <custom-checks-title> [--mode <error|warning>] to validate the custom pre-merge checks instructions. Defaults to error when --mode is omitted.
  • @coderabbitai ignore pre-merge checks to override pre-merge checks and get an approval on PR.
  • @coderabbitai run pre-merge checks to run pre-merge checks on the pull request.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve merge conflict to automatically resolve merge conflicts.
  • @coderabbitai autofix to automatically fix issues identified in unresolved review comments.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai generate configuration to create a PR that adds the current resolved configuration as .coderabbit.yaml (or show it if already present).
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit configuration file (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

@pflynn-virtru

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

Copilot AI 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.

Pull request overview

Fixes a divergence in the policy DB layer where GetRegisteredResource did not populate RegisteredResourceValue.action_attribute_values, causing authorization logic depending on (resource, action) → attributes to deny requests despite mappings existing.

Changes:

  • Updated getRegisteredResource SQL to LATERAL-join and aggregate action/attribute-value mappings into each returned resource value.
  • Regenerated sqlc bindings to reflect the updated SQL shape in the Go DB client.
  • Added an integration test asserting GetRegisteredResource returns values with populated action_attribute_values.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
service/policy/db/registered_resources.sql.go Regenerated sqlc output for getRegisteredResource to include nested action_attribute_values.
service/policy/db/queries/registered_resources.sql Mirrors the existing list-query LATERAL join pattern into the single-resource query to populate action_attribute_values.
service/integration/registered_resources_test.go Adds an integration test verifying GetRegisteredResource includes action/attribute mappings on returned values.
Files not reviewed (1)
  • service/policy/db/registered_resources.sql.go: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread service/policy/db/queries/registered_resources.sql
…ests

Address review feedback on both the get-side and list-side together to
keep the two query/test pairs symmetric.

- SQL: wrap the inner JSON_AGG in both getRegisteredResource and
  listRegisteredResources LATERAL subqueries with COALESCE(..., '[]'::json)
  so a value with no action/attribute mappings produces an empty JSON
  array instead of SQL NULL. protojson tolerates null for repeated
  fields, but the array shape is a cleaner contract for downstream
  consumers.
- Tests: replace the duplicated if/if value-lookup with a switch and a
  default: FailNow branch in both Test_GetRegisteredResource_... and
  Test_ListRegisteredResources_... so an unexpected value id fails the
  test instead of being silently skipped.

No behavior change for callers; sqlc binding regenerated.

Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
Comment thread service/integration/registered_resources_test.go Outdated
Comment thread service/policy/db/queries/registered_resources.sql Outdated
Address review feedback from @jakedoublev on opentdf#3472:

- SQL: drop the LEFT JOIN against attribute_fqns for the action's
  namespace FQN in both getRegisteredResource and listRegisteredResources
  LATERAL subqueries; namespace FQN is deterministic from the name, so
  build it inline as CONCAT('https://', ans.name). Mirrors the pattern
  used by service/policy/db/queries/obligations.sql.
- Tests: tighten both Test_GetRegisteredResource_... and
  Test_ListRegisteredResources_... so each value asserts the SPECIFIC
  action name and attribute value FQN that was created (e.g. val1 ->
  ActionNameCreate + .../attr1/value/value1), instead of merely checking
  that the returned action and attribute value were non-nil. Pulls the
  per-AAV checks out of the value-id switch so the structural assertions
  run once per value.

Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
@pflynn-virtru
pflynn-virtru added this pull request to the merge queue May 13, 2026
Merged via the queue into opentdf:main with commit 29eff55 May 13, 2026
40 checks passed
@pflynn-virtru
pflynn-virtru deleted the fix/issue-3471-getrr-action-attribute-values branch May 13, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GetRegisteredResource omits action_attribute_values from nested values

3 participants