Skip to content

feat(policy): Enforce same namespace when actions referenced downstream#3206

Merged
elizabethhealy merged 19 commits into
mainfrom
dspx-2450-assume-action-namespace-downstream
Mar 26, 2026
Merged

feat(policy): Enforce same namespace when actions referenced downstream#3206
elizabethhealy merged 19 commits into
mainfrom
dspx-2450-assume-action-namespace-downstream

Conversation

@elizabethhealy

@elizabethhealy elizabethhealy commented Mar 24, 2026

Copy link
Copy Markdown
Member

Proposed Changes

Subject Mappings (DB) (Existing Behavior)

  • Parent namespace provided:
    • Action by name: resolved/created in that namespace (createOrListActionsByNameInNamespace) (service/policy/db/subject_mappings.go:706).
    • Action by id: must have same namespace, else ErrNamespaceMismatch (service/policy/db/subject_mappings.go:680).
    • Attribute value + SCS must also match parent namespace (service/policy/db/subject_mappings.go:663, service/policy/db/subject_mappings.go:694).
  • Parent namespace omitted:
    • Action by name: resolved/created in global (unnamespaced) actions (createOrListActionsByName) (service/policy/db/subject_mappings.go:724).
    • Action by id: must be unnamespaced (namespace ""), else mismatch (service/policy/db/subject_mappings.go:687).
    • Attribute value can be namespaced; SCS must be unnamespaced (service/policy/db/subject_mappings.go:654).

Registered Resource Values (DB)

  • Parent namespace comes from the resource (service/policy/db/registered_resources.go:576).
  • Parent namespace provided:
    • Action by name: resolved/created in parent namespace (service/policy/db/registered_resources.go:637 + shared resolver).
    • Action by id: must match parent namespace (service/policy/db/registered_resources.go:693).
    • Attribute value must match parent namespace (service/policy/db/registered_resources.go:677).
  • Parent namespace omitted:
    • Action by name: resolved/created as global (unnamespaced).
    • Action by id: must be unnamespaced.
    • Attribute value may be any namespace (service/policy/db/registered_resources.go:669).

Obligation Triggers / Obligation Values (DB)

  • Parent namespace is obligation namespace (from obligation value) (service/policy/db/obligations.go:664).
  • Action by name: resolved/created in obligation namespace (service/policy/db/obligations.go:740).
  • Action by id: validated to same namespace; mismatch if different (including global-vs-namespaced mismatch) (service/policy/db/obligations.go:714, service/policy/db/obligations.go:787).
  • Attribute value (id or fqn) is resolved and must be in same namespace (service/policy/db/obligations.go:760).

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

Summary by CodeRabbit

  • Bug Fixes

    • Tightened namespace enforcement: cross-namespace action and attribute references now reliably fail with clearer errors.
    • Improved error classifications for missing, mismatched, or invalid action/attribute references.
  • Tests

    • Added and updated integration tests to cover namespace isolation, action/attribute lookup, default trigger resolution, and related error cases; tests now use unique namespaces per run.
  • Refactor

    • Centralized and consolidated resolution and namespace-validation logic for obligation triggers and registered resource values.

@coderabbitai

coderabbitai Bot commented Mar 24, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: ddc0f201-981f-4d67-b5e3-f275f9197818

📥 Commits

Reviewing files that changed from the base of the PR and between 28e3eac and ac24bc0.

📒 Files selected for processing (1)
  • service/policy/db/obligations.go

📝 Walkthrough

Walkthrough

Refactors DB action resolution and adds namespace-consistency validation for obligation triggers and registered-resources; updates SQL/queries, DB helpers, and multiple integration tests to use namespace-scoped action lookups and per-run unique namespaces/actions.

Changes

Cohort / File(s) Summary
Obligation DB & SQL
service/policy/db/obligations.go, service/policy/db/obligations.sql.go, service/policy/db/queries/obligations.sql
Added resolveObligationTriggerActionID and validateObligationNamespaceConsistency; CreateObligationTrigger now resolves actionID and enforces namespace consistency. Removed action-name-based SQL fallback, reindexed SQL params and dropped ActionName from params.
Registered-resources DB logic
service/policy/db/registered_resources.go
Extracted resolution/validation into resolveRegResAAV and validateRRAAVNamespaceConsistency; action name resolution now strictly namespace-scoped and per-AAV namespace checks added.
Obligation-related integration tests
service/integration/obligation_triggers_test.go, service/integration/obligations_test.go
Tests create per-run unique namespaces/actions, fetch actions from DB, adjust teardown to ignore empty/NotFound deletions, and update expected error types (e.g., db.ErrNotFound, db.ErrNamespaceMismatch).
Attribute/Registered-resource integration tests
service/integration/actions_test.go, service/integration/attribute_values_test.go, service/integration/registered_resources_test.go
Switched from fixture-standard actions to namespace-scoped DB lookups, use dynamic namespace names, and added/updated tests asserting namespace-enforcement errors.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client/Test
  participant PDB as PolicyDBClient
  participant DB as Database

  Client->>PDB: CreateObligationTrigger(req: action id/name, attrValue id/fqn, obligation id)
  PDB->>PDB: resolveObligationTriggerActionID(action identifier, obligationNs)
  alt identifier is id
    PDB->>DB: SELECT action WHERE id = $id
  else identifier is name
    PDB->>DB: SELECT action(s) WHERE name = $name AND namespace = obligationNs
  end
  DB-->>PDB: action row or not found
  PDB->>PDB: validateObligationNamespaceConsistency(obligationNs, attributeValue, actionID)
  PDB->>DB: SELECT attribute_value / attribute, SELECT action by id
  DB-->>PDB: attribute + action rows or namespace mismatch
  PDB->>DB: INSERT INTO obligation_triggers (resolved ActionID, attribute_value id/fqn, obligation_value id)
  DB-->>PDB: inserted trigger / error
  PDB-->>Client: created ObligationTrigger or error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

size/xl

Suggested reviewers

  • alkalescent
  • c-r33d
  • jakedoublev

Poem

🐰 I hopped through namespaces, neat and bright,
Resolved each action in its proper right.
Tests wear fresh names each run anew,
Triggers and values now match true,
A rabbit cheers — consistency in sight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(policy): Enforce same namespace when actions referenced downstream' directly and clearly summarizes the main objective: enforcing namespace consistency for action references in downstream policy database operations (obligations, registered resources, and subject mappings).

✏️ 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-2450-assume-action-namespace-downstream

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

@github-actions github-actions Bot added comp:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) labels Mar 24, 2026
@elizabethhealy elizabethhealy changed the title feat(policy): Assume same namespace of action downstream feat(policy): Assume same namespace when actions referenced downstream Mar 24, 2026
@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 enhances the policy service by introducing support for namespace-scoped actions. It ensures that every new namespace is automatically populated with standard actions like create, read, update, and delete. Furthermore, it refines the action resolution logic across the system, particularly when creating obligation triggers and registered resource action attribute values, to intelligently prioritize actions defined within the same namespace, providing a more granular and context-aware policy enforcement mechanism.

Highlights

  • Namespace-Scoped Standard Actions: Introduced a mechanism to automatically seed standard actions (create, read, update, delete) into new namespaces upon their creation, ensuring each namespace has its own set of fundamental actions.
  • Action Resolution Logic: Modified the action resolution process for creating obligation triggers and registered resource action attribute values. When an action is referenced by name, the system now prioritizes finding an action within the same namespace as the associated obligation value or registered resource. If a namespace-specific action is not found, it falls back to a global action with the same name.
  • Database Query Enhancements: Added a new SQL query seedStandardActionsForNamespace to efficiently insert standard actions into a namespace, handling potential conflicts. The createObligationTrigger SQL query was updated to implement the new namespace-aware action lookup logic.
  • Integration Tests: Added new integration tests to verify that standard actions are correctly seeded when a namespace is created and that the system correctly prefers namespace-scoped actions when creating obligation triggers.

🧠 New Feature in Public Preview: You can now enable Memory 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 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 counter productive. 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.


Namespaces now align, Actions find their proper home, Order starts to bloom.

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

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 388.47459ms
Throughput 257.42 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.166732373s
Average Latency 410.000319ms
Throughput 121.46 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

@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.583271ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 397.680106ms
Throughput 251.46 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.986276251s
Average Latency 407.709371ms
Throughput 121.99 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 386.688846ms
Throughput 258.61 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.656922268s
Average Latency 404.258163ms
Throughput 122.98 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

@elizabethhealy

Copy link
Copy Markdown
Member Author

@coderabbitai review

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 379.0436ms
Throughput 263.82 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.8154346s
Average Latency 396.988666ms
Throughput 125.58 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 412.837347ms
Throughput 242.23 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.66446885s
Average Latency 394.683984ms
Throughput 126.06 requests/second

Comment thread service/policy/db/obligations.go Outdated
Comment thread service/policy/db/registered_resources.go Outdated
@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.105844ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 380.053811ms
Throughput 263.12 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.938923748s
Average Latency 396.979414ms
Throughput 125.19 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

@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

♻️ Duplicate comments (1)
service/policy/db/obligations.go (1)

715-717: ⚠️ Potential issue | 🟠 Major

Classify bad action identifiers before querying.

Line 717 uses pgtypeUUID(actionID) without the usual .Valid guard, and Line 737 still returns a plain error when both id and name are empty. That means malformed IDs are no longer rejected up front like the other ID-based paths in this file, and callers lose errors.Is(err, db.ErrMissingValue) on the empty-identifier path.

🩹 Minimal fix
 	actionID := action.GetId()
 	if actionID != "" {
-		got, err := c.queries.getAction(ctx, getActionParams{ID: pgtypeUUID(actionID)})
+		parsedActionID := pgtypeUUID(actionID)
+		if !parsedActionID.Valid {
+			return "", db.ErrUUIDInvalid
+		}
+		got, err := c.queries.getAction(ctx, getActionParams{ID: parsedActionID})
 		if err != nil {
 			return "", db.WrapIfKnownInvalidQueryErr(
 				errors.Join(db.ErrMissingValue, fmt.Errorf("failed to get action by id [%v]: %w", actionID, err)),
 			)
 		}
@@
 	actionName := strings.ToLower(action.GetName())
 	if actionName == "" {
-		return "", errors.New("action identifier must include either id or name")
+		return "", errors.Join(
+			db.ErrMissingValue,
+			errors.New("action identifier must include either id or name"),
+		)
 	}

Also applies to: 735-738

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@service/policy/db/obligations.go` around lines 715 - 717, Validate and
classify bad action identifiers before querying: when using actionID (variable
actionID) wrap pgtypeUUID(actionID) in a pgtype UUID value and check its .Valid
flag before calling c.queries.getAction (the getActionParams should only use a
valid pgtypeUUID), returning db.ErrMissingValue for an empty or invalid ID so
callers can use errors.Is(err, db.ErrMissingValue); also ensure the branch that
currently returns a plain error when both id and name are empty returns
db.ErrMissingValue instead and that any malformed UUID produces a clear
classified error rather than proceeding to c.queries.getAction.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@service/policy/db/obligations.go`:
- Around line 796-799: The error message in the obligation trigger namespace
check uses the wrong subsystem label; update the fmt.Errorf in the if branch
that compares actionNsID and targetNsID (where a.ID, actionNsID, targetNsID and
db.ErrNamespaceMismatch are used) so the message refers to the obligation
trigger/action namespace matching the target namespace (e.g., "action [ID]
namespace [..] does not match the specified obligation trigger namespace [..]")
instead of "subject mapping namespace"; leave the error wrapping with
db.ErrNamespaceMismatch intact.

In `@service/policy/db/registered_resources.go`:
- Around line 649-652: The AttributeValueId branch currently just copies
ident.AttributeValueId into attributeValueID and skips resolution when
targetNsID == "", causing unnamespaced (global) IDs to bypass validation; update
the handling in the switch over aav.GetAttributeValueIdentifier() (the
ActionAttributeValue_AttributeValueId case) to resolve or existence-check the ID
via the same GetAttributeValue lookup used for FQNs (respecting targetNsID), and
return a validation error before building the batch if the ID is
missing/malformed or the lookup fails; apply the same change to the other
identical block around the later range (lines handling the second
ActionAttributeValue switch) so both identifier forms (ID and FQN) are validated
consistently prior to batch creation.

---

Duplicate comments:
In `@service/policy/db/obligations.go`:
- Around line 715-717: Validate and classify bad action identifiers before
querying: when using actionID (variable actionID) wrap pgtypeUUID(actionID) in a
pgtype UUID value and check its .Valid flag before calling c.queries.getAction
(the getActionParams should only use a valid pgtypeUUID), returning
db.ErrMissingValue for an empty or invalid ID so callers can use errors.Is(err,
db.ErrMissingValue); also ensure the branch that currently returns a plain error
when both id and name are empty returns db.ErrMissingValue instead and that any
malformed UUID produces a clear classified error rather than proceeding to
c.queries.getAction.
🪄 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: 8b26feec-d55d-41e5-9066-862c336c3197

📥 Commits

Reviewing files that changed from the base of the PR and between 9aa6561 and 7fdeec4.

📒 Files selected for processing (2)
  • service/policy/db/obligations.go
  • service/policy/db/registered_resources.go

Comment thread service/policy/db/obligations.go
Comment thread service/policy/db/registered_resources.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 200.13342ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 389.03724ms
Throughput 257.04 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.7196409s
Average Latency 405.520142ms
Throughput 122.79 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: 1

♻️ Duplicate comments (1)
service/policy/db/obligations.go (1)

800-803: ⚠️ Potential issue | 🟡 Minor

Fix the error message label — still says "subject mapping namespace".

This branch validates an obligation trigger, but the error message incorrectly refers to "subject mapping namespace". This will surface in logs/API errors and misdirect debugging.

✏️ Minimal fix
 	if actionNsID != targetNsID {
 		return errors.Join(db.ErrNamespaceMismatch,
-			fmt.Errorf("action [%s] namespace [%s] does not match the specified subject mapping namespace [%s]", a.ID, actionNsID, targetNsID))
+			fmt.Errorf("action [%s] namespace [%s] does not match the specified obligation namespace [%s]", a.ID, actionNsID, targetNsID))
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@service/policy/db/obligations.go` around lines 800 - 803, The error message
in the obligation trigger namespace check erroneously refers to "subject mapping
namespace"; update the message in the branch that compares actionNsID and
targetNsID (where it returns errors.Join with db.ErrNamespaceMismatch) to
accurately state that the action's namespace does not match the
obligation/trigger namespace (use a.ID, actionNsID, targetNsID in the message).
Keep the same error construction (errors.Join with db.ErrNamespaceMismatch) but
replace "subject mapping namespace" with "obligation/trigger namespace" or
similar accurate wording.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@service/policy/db/obligations.go`:
- Around line 714-733: The partial namespace check in
resolveObligationTriggerActionID (the if block that inspects actionNamespace and
compares GetId() to obligationNamespaceID) is redundant and incomplete; remove
that entire conditional so namespace validation is handled only by
validateObligationNamespaceConsistency elsewhere, leaving
resolveObligationTriggerActionID to simply fetch the action, hydrate namespace
(but not enforce mismatch here) and return actionID, nil after successful
lookup; reference resolveObligationTriggerActionID,
hydrateNamespaceFromInterface, and validateObligationNamespaceConsistency to
locate the related logic.

---

Duplicate comments:
In `@service/policy/db/obligations.go`:
- Around line 800-803: The error message in the obligation trigger namespace
check erroneously refers to "subject mapping namespace"; update the message in
the branch that compares actionNsID and targetNsID (where it returns errors.Join
with db.ErrNamespaceMismatch) to accurately state that the action's namespace
does not match the obligation/trigger namespace (use a.ID, actionNsID,
targetNsID in the message). Keep the same error construction (errors.Join with
db.ErrNamespaceMismatch) but replace "subject mapping namespace" with
"obligation/trigger namespace" or similar accurate wording.
🪄 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: ed007138-9bdd-4516-9f75-7697edca882b

📥 Commits

Reviewing files that changed from the base of the PR and between 7fdeec4 and 28e3eac.

📒 Files selected for processing (1)
  • service/policy/db/obligations.go

Comment thread service/policy/db/obligations.go
@github-actions

Copy link
Copy Markdown
Contributor

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 390.776454ms
Throughput 255.90 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.943971335s
Average Latency 417.377279ms
Throughput 119.21 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

@elizabethhealy
elizabethhealy added this pull request to the merge queue Mar 26, 2026
Merged via the queue into main with commit 4b5463a Mar 26, 2026
38 checks passed
@elizabethhealy
elizabethhealy deleted the dspx-2450-assume-action-namespace-downstream branch March 26, 2026 14:18
JBCongdon pushed a commit to JBCongdon/platform that referenced this pull request May 24, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.14.0](opentdf/platform@service/v0.13.0...service/v0.14.0)
(2026-04-21)


### ⚠ BREAKING CHANGES

* **sdk:** reclassify KAS 400 errors — distinguish tamper from
misconfiguration
([opentdf#3166](opentdf#3166))
* **policy:** optional namespace for RRs
([opentdf#3165](opentdf#3165))
* **policy:** Namespace subject mappings and subject condition sets.
([opentdf#3143](opentdf#3143))
* **policy:** Optional namespace on actions protos, NamespacedPolicy
feature flag ([opentdf#3155](opentdf#3155))
* **policy:** add namespaced actions schema and namespace-aware action
queries ([opentdf#3154](opentdf#3154))
* **policy:** only require namespace on GetAction if no id provided
([opentdf#3144](opentdf#3144))
* **policy:** add namespace field to Actions proto
([opentdf#3130](opentdf#3130))
* **policy:** namespace Registered Resources
([opentdf#3111](opentdf#3111))
* **policy:** add namespace field to RegisteredResource proto
([opentdf#3110](opentdf#3110))

### Features

* **authz:** Namespaced policy in decisioning
([opentdf#3226](opentdf#3226))
([0355934](opentdf@0355934))
* **cli:** migrate otdfctl into platform monorepo
([opentdf#3205](opentdf#3205))
([5177bec](opentdf@5177bec))
* fix tracing ([opentdf#3242](opentdf#3242))
([57e5680](opentdf@57e5680))
* **policy:** add GetObligationTrigger RPC
([opentdf#3318](opentdf#3318))
([d68e39d](opentdf@d68e39d))
* **policy:** add namespace field to Actions proto
([opentdf#3130](opentdf#3130))
([bedc9b3](opentdf@bedc9b3))
* **policy:** add namespace field to RegisteredResource proto
([opentdf#3110](opentdf#3110))
([04fd85d](opentdf@04fd85d))
* **policy:** add namespaced actions schema and namespace-aware action
queries ([opentdf#3154](opentdf#3154))
([c0443f1](opentdf@c0443f1))
* **policy:** add sort ListSubjectMappings API
([opentdf#3255](opentdf#3255))
([9d5d757](opentdf@9d5d757))
* **policy:** Add sort support listregisteredresources api
([opentdf#3312](opentdf#3312))
([91a3ff3](opentdf@91a3ff3))
* **policy:** add sort support to ListAttributes API
([opentdf#3223](opentdf#3223))
([ec3312f](opentdf@ec3312f))
* **policy:** add sort support to ListKeyAccessServer
([opentdf#3287](opentdf#3287))
([7fae2d7](opentdf@7fae2d7))
* **policy:** Add sort support to ListNamespaces API
([opentdf#3192](opentdf#3192))
([aac86cd](opentdf@aac86cd))
* **policy:** add sort support to listobligations api
([opentdf#3300](opentdf#3300))
([9221cac](opentdf@9221cac))
* **policy:** add sort support to ListSubjectConditionSets API
([opentdf#3272](opentdf#3272))
([9010f12](opentdf@9010f12))
* **policy:** add SortField proto and update PageRequest for sort
support ([opentdf#3187](opentdf#3187))
([6cf1862](opentdf@6cf1862))
* **policy:** Enforce same namespace when actions referenced downstream
([opentdf#3206](opentdf#3206))
([4b5463a](opentdf@4b5463a))
* **policy:** namespace Registered Resources
([opentdf#3111](opentdf#3111))
([6db1883](opentdf@6db1883))
* **policy:** Namespace subject mappings and condition sets
([opentdf#3172](opentdf#3172))
([6deed50](opentdf@6deed50))
* **policy:** Namespace subject mappings and subject condition sets.
([opentdf#3143](opentdf#3143))
([3006780](opentdf@3006780))
* **policy:** optional namespace for RRs
([opentdf#3165](opentdf#3165))
([8948018](opentdf@8948018))
* **policy:** rollback migration strategy for namespaced actions
([opentdf#3235](opentdf#3235))
([f7e5e01](opentdf@f7e5e01))
* **policy:** Seed existing namespaces with standard actions
([opentdf#3228](opentdf#3228))
([12136b0](opentdf@12136b0))
* **policy:** Seed namespaces with standard actions on creation +
namespaced actions for obligation triggers
([opentdf#3161](opentdf#3161))
([984d76b](opentdf@984d76b))


### Bug Fixes

* **ci:** Upgrade toolchain version to 1.25.8
([opentdf#3116](opentdf#3116))
([e1b7882](opentdf@e1b7882))
* **core:** do not concat slashes directly in url/file paths
([opentdf#3290](opentdf#3290))
([114c2a7](opentdf@114c2a7))
* **deps:** bump github.com/jackc/pgx/v5 from 5.7.5 to 5.9.0 in /service
([opentdf#3316](opentdf#3316))
([017362e](opentdf@017362e))
* **deps:** bump github.com/opentdf/platform/lib/identifier from 0.2.0
to 0.3.0 in /service
([opentdf#3162](opentdf#3162))
([8bc5dcd](opentdf@8bc5dcd))
* **deps:** bump github.com/opentdf/platform/protocol/go from 0.16.0 to
0.17.0 in /service
([opentdf#3125](opentdf#3125))
([29fec61](opentdf@29fec61))
* **deps:** bump github.com/opentdf/platform/protocol/go from 0.17.0 to
0.21.0 in /service
([opentdf#3220](opentdf#3220))
([e63add2](opentdf@e63add2))
* **deps:** bump github.com/opentdf/platform/protocol/go from 0.21.0 to
0.22.0 in /service
([opentdf#3248](opentdf#3248))
([1ebce73](opentdf@1ebce73))
* **deps:** bump github.com/opentdf/platform/protocol/go from 0.22.0 to
0.23.0 in /service
([opentdf#3271](opentdf#3271))
([3338b8e](opentdf@3338b8e))
* **deps:** bump github.com/opentdf/platform/protocol/go from 0.23.0 to
0.24.0 in /service
([opentdf#3321](opentdf#3321))
([78e6022](opentdf@78e6022))
* **deps:** bump github.com/opentdf/platform/protocol/go from 0.24.0 to
0.25.0 in /service
([opentdf#3333](opentdf#3333))
([3940bf8](opentdf@3940bf8))
* **deps:** bump github.com/opentdf/platform/sdk from 0.13.0 to 0.16.0
in /service ([opentdf#3356](opentdf#3356))
([5617077](opentdf@5617077))
* **deps:** bump
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp from
1.42.0 to 1.43.0 in /service
([opentdf#3282](opentdf#3282))
([046374a](opentdf@046374a))
* **deps:** bump go.opentelemetry.io/otel/sdk from 1.42.0 to 1.43.0 in
/service ([opentdf#3281](opentdf#3281))
([56b33f2](opentdf@56b33f2))
* **deps:** bump google.golang.org/grpc from 1.77.0 to 1.79.3 in
/service ([opentdf#3176](opentdf#3176))
([3289502](opentdf@3289502))
* **deps:** remove direct github.com/docker/docker dependency
([opentdf#3229](opentdf#3229))
([2becb27](opentdf@2becb27))
* **deps:** upgrade testcontainers-go to resolve vulns
([opentdf#3299](opentdf#3299))
([72c6f9b](opentdf@72c6f9b))
* **ers:** include standard JWT claims in claims mode entity resolution
([opentdf#3196](opentdf#3196))
([6d50da1](opentdf@6d50da1))
* **ers:** ldap multi-strategy ers
([opentdf#3117](opentdf#3117))
([d3aaf1a](opentdf@d3aaf1a))
* **policy:** deprecate ListAttributeValues in favor of existing
GetAttribute ([opentdf#3108](opentdf#3108))
([7e17c2d](opentdf@7e17c2d))
* **policy:** make obligation trigger uniqueness client-aware
([opentdf#3114](opentdf#3114))
([9265bc3](opentdf@9265bc3))
* **policy:** omit empty attribute values from create responses
([opentdf#3193](opentdf#3193))
([d298378](opentdf@d298378))
* **policy:** only require namespace on GetAction if no id provided
([opentdf#3144](opentdf#3144))
([10d0c0f](opentdf@10d0c0f))
* **policy:** Optional namespace on actions protos, NamespacedPolicy
feature flag ([opentdf#3155](opentdf#3155))
([c20f039](opentdf@c20f039))
* **policy:** order List* results by created_at
([opentdf#3088](opentdf#3088))
([ea90ac2](opentdf@ea90ac2))
* **sdk:** normalize issuer URL before OIDC discovery
([opentdf#3261](opentdf#3261))
([61f98c9](opentdf@61f98c9))
* **sdk:** reclassify KAS 400 errors — distinguish tamper from
misconfiguration
([opentdf#3166](opentdf#3166))
([f04a385](opentdf@f04a385))
* **sdk:** remove testcontainers from consumer dependency graph
([opentdf#3129](opentdf#3129))
([f17dcdd](opentdf@f17dcdd))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com>
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/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants