Skip to content

feat(authz): Namespaced policy in decisioning#3226

Open
elizabethhealy wants to merge 21 commits intomainfrom
dspx-2753-namespaced-policy-decisioning
Open

feat(authz): Namespaced policy in decisioning#3226
elizabethhealy wants to merge 21 commits intomainfrom
dspx-2753-namespaced-policy-decisioning

Conversation

@elizabethhealy
Copy link
Copy Markdown
Member

@elizabethhealy elizabethhealy commented Mar 31, 2026

Proposed Changes

This pull request introduces a namespaced policy evaluation model to the Policy Decision Point (PDP). The primary goal is to resolve ambiguities in access decisioning where action names might overlap across different namespaces. By threading a new NamespacedPolicy configuration through the PDP, the system can now enforce strict namespace equality for actions and subject mappings, ensuring a fail-closed and deterministic authorization process suitable for staged migration.

Highlights

  • Namespaced Policy Enforcement: Introduced a NamespacedPolicy feature flag to enforce strict namespace ownership in access decisioning, preventing cross-namespace action matches.
  • Deterministic Action Resolution: Implemented namespace-aware action matching logic that resolves actions within specific evaluation contexts, with explicit identity precedence (ID > Name+Namespace > Name).
  • Subject Mapping Filtering: Added logic to filter out unnamespaced subject mappings when the NamespacedPolicy mode is enabled.
  • Conflict Resolution: Added defensive logic to EvaluateSubjectMappingsWithActions to handle and log action name collisions deterministically.

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

  • New Features
    • Add optional strict, namespace-aware authorization (EnforceNamespacedEntitlements) enforcing per-namespace action matching with ID → name+namespace → name precedence and fail-closed behavior.
  • Bug Fixes
    • Deterministic deduplication of conflicting actions to avoid silent overwrites; direct entitlements are merged rather than replaced.
  • Documentation
    • Added ADR and deployment template describing namespaced decisioning.
  • Tests
    • Expanded unit and BDD tests covering namespaced decisioning scenarios and matching semantics.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

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
📝 Walkthrough

Walkthrough

Adds a feature-flagged namespaced subject-mapping decision model: config flag, PDP/JIT plumbing, namespaced indexing/filtering, namespace-aware action matching and merging, deduplication/logging for conflicting actions, tests, BDD scenarios, and an ADR documenting semantics and rollout.

Changes

Cohort / File(s) Summary
Architecture ADR
adr/decisions/2026-03-30-namespaced-subject-mappings-decisioning.md
New ADR specifying namespaced decisioning semantics, identity precedence (id → name+namespace → name), fail-closed rules, feature-flag behavior, and rollout notes.
Service config & wiring
service/authorization/v2/config.go, service/authorization/v2/authorization.go
Added EnforceNamespacedEntitlements config field and threaded the flag into JustInTimePDP construction and logging.
PDP core & indexing
service/internal/access/v2/pdp.go, service/internal/access/v2/just_in_time_pdp.go
PDP and JIT constructors accept namespaced flag; subject mappings filtered at build time, registered-resource values indexed by namespaced and legacy FQNs, direct entitlements merged (not overwritten) with namespace hydration, and namespaced-aware action deduplication added.
Evaluation logic
service/internal/access/v2/evaluate.go
Resource evaluation now accepts namespacedPolicy; introduced isRequestedActionMatch, rule-scoped variants for ALL_OF/ANY_OF/HIERARCHY, and strict-mode fail-closed behavior when required namespaces cannot be resolved.
PDP & evaluation tests
service/internal/access/v2/evaluate_test.go, service/internal/access/v2/pdp_test.go, service/internal/access/v2/helpers_test.go
Updated tests to pass namespaced flag, added extensive namespaced-mode unit tests, and small test fixture updates.
Subject mapping dedupe & tests
service/internal/subjectmappingbuiltin/subject_mapping_builtin_actions.go, service/internal/subjectmappingbuiltin/subject_mapping_builtin_actions_test.go
Action deduplication now detects conflicts, logs warnings, and deterministically prefers actions (prefers non-empty IDs/namespaces); tests added/updated to validate behavior.
BDD & test resources
tests-bdd/features/namespaced-decisioning.feature, tests-bdd/cukes/steps_subjectmappings.go, tests-bdd/cukes/resources/platform.namespaced_policy.template
Added BDD scenarios for strict namespaced decisioning, step helpers to create namespaced condition sets/mappings, and a platform template enabling namespaced entitlement enforcement.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant AuthService as Authorization Service
participant JIT_PDP as JustInTimePDP
participant PDP
participant Registry as RegisteredResourceIndex
participant SubjectMapping as SubjectMappingsStore

Client->>AuthService: Decision request (action id/name, resource attrs)
AuthService->>JIT_PDP: NewJustInTimePDP(..., allowDirectEntitlements, namespacedPolicy)
AuthService->>JIT_PDP: GetDecision(request)
JIT_PDP->>PDP: Evaluate(resource, request, namespacedPolicy)
PDP->>Registry: Lookup registered-resource values (namespaced & legacy FQNs)
PDP->>SubjectMapping: Filter subject mappings (skip unnamespaced if strict)
PDP->>PDP: isRequestedActionMatch(action, requiredNamespace)
PDP-->>JIT_PDP: Decision (PERMIT/DENY)
JIT_PDP-->>AuthService: Decision
AuthService-->>Client: Response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

comp:policy, docs

Suggested reviewers

  • c-r33d
  • jakedoublev

Poem

🐰
I hopped through code with tiny paws,
Namespaces stitched into rules and laws.
Actions choose their proper home,
No more wandering places to roam.
Hooray — decisions find their cause!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 clearly summarizes the main change: introducing a namespaced policy evaluation model to the authorization decisioning system, which is the core focus of this PR.

✏️ 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-2753-namespaced-policy-decisioning

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 introduces a namespaced policy evaluation model to the Policy Decision Point (PDP). The primary goal is to resolve ambiguities in access decisioning where action names might overlap across different namespaces. By threading a new NamespacedPolicy configuration through the PDP, the system can now enforce strict namespace equality for actions and subject mappings, ensuring a fail-closed and deterministic authorization process suitable for staged migration.

Highlights

  • Namespaced Policy Enforcement: Introduced a NamespacedPolicy feature flag to enforce strict namespace ownership in access decisioning, preventing cross-namespace action matches.
  • Deterministic Action Resolution: Implemented namespace-aware action matching logic that resolves actions within specific evaluation contexts, with explicit identity precedence (ID > Name+Namespace > Name).
  • Subject Mapping Filtering: Added logic to filter out unnamespaced subject mappings when the NamespacedPolicy mode is enabled.
  • Conflict Resolution: Added defensive logic to EvaluateSubjectMappingsWithActions to handle and log action name collisions deterministically.

🧠 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 strict and clear, Policy doubts disappear. Actions matched with care, Security beyond compare.

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
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.554433ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 395.392321ms
Throughput 252.91 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.837164037s
Average Latency 407.036478ms
Throughput 122.44 requests/second

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review

This pull request implements namespaced subject mapping decisioning in the PDP, as outlined in the newly added ADR. It introduces a NamespacedPolicy feature flag to control the enforcement of strict namespace ownership during access evaluation. The core logic includes a centralized action-matching helper and updated evaluation paths for attribute rules. Feedback focuses on the transition to uniform case-insensitive action name matching and suggests more robust logging or error handling when resolving action name collisions during subject mapping evaluation.

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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.928477ms
Throughput 258.45 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.111521964s
Average Latency 399.3757ms
Throughput 124.65 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

X-Test Failure Report

opentdfplatformB2MWHF.dockerbuild

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 399.245747ms
Throughput 250.47 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.721397139s
Average Latency 405.954345ms
Throughput 122.79 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 196.070008ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 393.140224ms
Throughput 254.36 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.796006383s
Average Latency 416.225723ms
Throughput 119.63 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 206.206272ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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.864314ms
Throughput 262.56 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.471782036s
Average Latency 412.725819ms
Throughput 120.56 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 203.173319ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 383.684246ms
Throughput 260.63 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.367541483s
Average Latency 411.964684ms
Throughput 120.87 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (2)
service/internal/access/v2/pdp.go (2)

297-326: ⚠️ Potential issue | 🟠 Major

Keep registered-resource action candidates ID/namespace-aware here too.

This loop still filters on GetName() and deduplicates by name, but the common matcher now supports Action.Id and namespace-aware comparisons. Requests that identify the action by ID, or registered-resource values that carry same-name actions in multiple namespaces, can be denied based on iteration order before getResourceDecision ever runs.

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

In `@service/internal/access/v2/pdp.go` around lines 297 - 326, The loop that
builds entitledFQNsToActions deduplicates and matches actions only by name
(using aav.GetAction().GetName() and slices.ContainsFunc comparing GetName()),
which ignores Action.Id and namespaces and can produce wrong ordering/denials;
update the matching and deduplication to be ID+namespace-aware: when reading
aav.GetAction() (aavAction) and comparing to the Decision Request action
(action), compare both Id and namespace (or use a composite key like
action.GetId()+":"+action.GetNamespace()) instead of GetName(); likewise replace
the slices.ContainsFunc check with a comparison on Id+namespace (or maintain
actionsList as a map keyed by that composite key and convert back to
[]*policy.Action) so entitledFQNsToActions stores unique actions by ID+namespace
before calling getResourceDecision (preserve use of entitledFQNsToActions,
getResourceDecision, entityRegisteredResourceValue.GetActionAttributeValues,
aav.GetAction, action, and p.namespacedPolicy in your changes).

102-157: ⚠️ Potential issue | 🟠 Major

Don't mutate caller-owned Value.SubjectMappings while building the PDP index.

The builder stores references to policy objects returned from the store/cache and then mutates their SubjectMappings fields in place. When using EntitlementPolicyCache, the cache returns the same slice and object references across builds; mutations persist in the cached data. A prior non-strict build can leave legacy mappings attached to cached values, and a later strict build will evaluate stale mappings that should have been skipped. Clone the value or clear SubjectMappings before populating the lookup to ensure each PDP build operates on independent data.

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

In `@service/internal/access/v2/pdp.go` around lines 102 - 157, The code mutates
caller-owned policy.Value objects (specifically Value.SubjectMappings) while
building the PDP index (see allEntitleableAttributesByValueFQN, mappedValue, and
the block that appends to SubjectMappings), which can leak into cached data; fix
by cloning the attribute value (or creating a fresh value instance) before
assigning or clearing SubjectMappings and before appending mappings so you never
modify objects returned from the store/cache; update the branch that handles
existing entries and the branch that calls getDefinition to use the cloned value
(or reset SubjectMappings) and attach the clone to the new
attrs.GetAttributeValuesByFqnsResponse_AttributeAndValue entry to ensure each
PDP build has independent SubjectMappings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@adr/decisions/2026-03-30-namespaced-subject-mappings-decisioning.md`:
- Around line 30-36: The ADR currently contradicts itself about whether the
request action is unnamespaced: update the decision text so there is a single
normative request-action contract and remove the conflicting statement; choose
one model (either keep "request action remains unnamespaced" and restrict the
precedence list to contextual/derived matching, or adopt the explicit request
shapes `action.id`, `action.name + action.namespace`, `action.name` as the
normative request contract) and rewrite the paragraph around "Request-action
identity precedence" to match that single choice, ensuring all references to
action.id, action.name, and action.namespace in the document are consistent with
the chosen contract.

In `@service/internal/access/v2/evaluate.go`:
- Around line 82-91: The loop that computes requiredNamespaceID for each
regResValue AAV uses accessibleAttributeValues (a filtered map) and leaves
requiredNamespaceID empty when an AAV isn’t present, allowing
isRequestedActionMatch(...) to silently skip instead of denying in strict mode;
fix by resolving the namespace from the unfiltered value→attribute lookup used
elsewhere (the full value->attribute map) when computing requiredNamespaceID for
regResValue.GetActionAttributeValues(), and if that lookup still fails while the
AAV is otherwise a candidate for the requested action and
namespacedPolicy/strict mode is enabled, return a deny (fail-closed) rather than
continuing; update the logic around requiredNamespaceID,
isRequestedActionMatch(action, requiredNamespaceID, aav.GetAction(),
namespacedPolicy), and the strict-mode path accordingly and add a mixed-AAV
strict-mode regression test that ensures a resource with multiple AAVs is denied
when any AAV’s namespace cannot be resolved.

In `@service/internal/access/v2/helpers_test.go`:
- Around line 396-399: The fixture `valueRestricted` is inconsistent because its
SubjectMapping uses `exampleSecretFQN` instead of the intended
`exampleRestrictedFQN`; update the call to `createSimpleSubjectMapping` inside
the `valueRestricted` declaration so the subject FQN argument is
`exampleRestrictedFQN` (not `exampleSecretFQN`) to correctly represent the
restricted fixture and ensure `populateHigherValuesIfHierarchy` tests exercise
the intended hierarchy.

In `@service/internal/subjectmappingbuiltin/subject_mapping_builtin_actions.go`:
- Around line 147-159: The current selection only checks presence of a Namespace
but doesn't prefer the one with an ID (Namespace.Id) when both have namespaces;
update the logic around existingNS/candidateNS so that if both existingHasNS and
candidateHasNS are true you choose the action whose Namespace.GetId() is
non-empty (prefer candidate if it has an ID, otherwise prefer existing if it has
an ID, otherwise fall back to existing); adjust the branch that returns
existing/candidate to inspect Namespace.GetId() before returning to ensure the
action with an actual namespace ID is chosen.

---

Outside diff comments:
In `@service/internal/access/v2/pdp.go`:
- Around line 297-326: The loop that builds entitledFQNsToActions deduplicates
and matches actions only by name (using aav.GetAction().GetName() and
slices.ContainsFunc comparing GetName()), which ignores Action.Id and namespaces
and can produce wrong ordering/denials; update the matching and deduplication to
be ID+namespace-aware: when reading aav.GetAction() (aavAction) and comparing to
the Decision Request action (action), compare both Id and namespace (or use a
composite key like action.GetId()+":"+action.GetNamespace()) instead of
GetName(); likewise replace the slices.ContainsFunc check with a comparison on
Id+namespace (or maintain actionsList as a map keyed by that composite key and
convert back to []*policy.Action) so entitledFQNsToActions stores unique actions
by ID+namespace before calling getResourceDecision (preserve use of
entitledFQNsToActions, getResourceDecision,
entityRegisteredResourceValue.GetActionAttributeValues, aav.GetAction, action,
and p.namespacedPolicy in your changes).
- Around line 102-157: The code mutates caller-owned policy.Value objects
(specifically Value.SubjectMappings) while building the PDP index (see
allEntitleableAttributesByValueFQN, mappedValue, and the block that appends to
SubjectMappings), which can leak into cached data; fix by cloning the attribute
value (or creating a fresh value instance) before assigning or clearing
SubjectMappings and before appending mappings so you never modify objects
returned from the store/cache; update the branch that handles existing entries
and the branch that calls getDefinition to use the cloned value (or reset
SubjectMappings) and attach the clone to the new
attrs.GetAttributeValuesByFqnsResponse_AttributeAndValue entry to ensure each
PDP build has independent SubjectMappings.
🪄 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: 40e86ab6-c264-4bb2-9f3a-45f77facf7bb

📥 Commits

Reviewing files that changed from the base of the PR and between 99a8147 and 26740fd.

📒 Files selected for processing (15)
  • adr/decisions/2026-03-30-namespaced-subject-mappings-decisioning.md
  • docs/namespaced-subject-mappings-decisioning-plan.md
  • service/authorization/v2/authorization.go
  • service/authorization/v2/config.go
  • service/internal/access/v2/evaluate.go
  • service/internal/access/v2/evaluate_test.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_test.go
  • service/internal/subjectmappingbuiltin/subject_mapping_builtin_actions.go
  • service/internal/subjectmappingbuiltin/subject_mapping_builtin_actions_test.go
  • tests-bdd/cukes/resources/platform.namespaced_policy.template
  • tests-bdd/cukes/steps_subjectmappings.go
  • tests-bdd/features/namespaced-decisioning.feature

@github-actions
Copy link
Copy Markdown
Contributor

X-Test Failure Report

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 425.711707ms
Throughput 234.90 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.165398514s
Average Latency 419.919515ms
Throughput 118.58 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 194.763155ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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.503988ms
Throughput 258.73 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.769552371s
Average Latency 396.022769ms
Throughput 125.72 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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.890733ms
Throughput 257.14 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.323767225s
Average Latency 399.57637ms
Throughput 124.00 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (2)
service/internal/access/v2/pdp.go (2)

103-116: ⚠️ Potential issue | 🟠 Major

Avoid mutating caller-owned Value.SubjectMappings.

allEntitleableAttributesByValueFQN stores the original attr.GetValues() pointers, and Line 146 appends straight into those shared slices. If the same attribute objects are reused for another PDP build — plausible on the cached NewJustInTimePDP path — a legacy build can leave unnamespaced mappings attached and a later strict build will still evaluate them even though Lines 130-140 skip them. Repeated constructors also accumulate duplicates. Please clone/reset the policy.Values before wiring mappings and add a regression that builds legacy then strict PDPs from the same inputs.

Suggested fix
+import "google.golang.org/protobuf/proto"
...
 		for _, value := range attr.GetValues() {
+			valueCopy := proto.Clone(value).(*policy.Value)
+			valueCopy.SubjectMappings = nil
 			mapped := &attrs.GetAttributeValuesByFqnsResponse_AttributeAndValue{
-				Value:     value,
+				Value:     valueCopy,
 				Attribute: attr,
 			}
-			allEntitleableAttributesByValueFQN[value.GetFqn()] = mapped
+			allEntitleableAttributesByValueFQN[valueCopy.GetFqn()] = mapped
 		}
...
-		mappedValue.SubjectMappings = []*policy.SubjectMapping{sm}
+		mappedValue = proto.Clone(mappedValue).(*policy.Value)
+		mappedValue.SubjectMappings = []*policy.SubjectMapping{sm}

Also applies to: 130-146, 154-159

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

In `@service/internal/access/v2/pdp.go` around lines 103 - 116, The code mutates
caller-owned Value objects (attr.GetValues()) by reusing their pointers in
allEntitleableAttributesByValueFQN and later appending to Value.SubjectMappings;
to fix, create deep copies of each policy.Value (or at minimum copy the Value
struct and reset/clone its SubjectMappings slice) before storing/inspecting them
in allEntitleableAttributesByValueFQN and before any code that appends mappings
(refer to allEntitleableAttributesByValueFQN, attr.GetValues(), and
Value.SubjectMappings), so the original attribute definitions are never
modified; also add a regression test that constructs a legacy PDP then a strict
PDP from the same input (exercise NewJustInTimePDP reuse path) to ensure
mappings are not accumulated across builds.

314-345: ⚠️ Potential issue | 🟠 Major

Preserve ID/namespace action variants for registered-resource subjects.

By the time Line 344 calls getResourceDecision, this map has already filtered and deduped entityRegisteredResourceValue.GetActionAttributeValues() on Action.Name alone. That drops same-name actions that differ only by namespace or ID, so strict mode — or any request with an explicit namespace/ID — can incorrectly deny when the kept variant is not the matching one. Use isRequestedActionMatch(..., false) for the prefilter and keep distinct ID -> Name+Namespace -> Name variants until evaluation. Please add a regression with two same-name RR actions on the same value FQN.

Suggested fix
 		aavAction := aav.GetAction()
-		if action.GetName() != aavAction.GetName() {
+		if !isRequestedActionMatch(ctx, l, action, "", aavAction, false) {
 			l.DebugContext(ctx, "skipping action not matching Decision Request action", slog.String("action_name", aavAction.GetName()))
 			continue
 		}
...
-		if !slices.ContainsFunc(actionsList, func(a *policy.Action) bool {
-			return a.GetName() == aavAction.GetName()
-		}) {
-			actionsList = append(actionsList, aavAction)
-		}
+		// Preserve distinct ID / namespace variants so downstream evaluation can
+		// apply the full action-identity precedence.
+		actionsList = append(actionsList, aavAction)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@service/internal/access/v2/pdp.go` around lines 314 - 345, The current
prefilter over entityRegisteredResourceValue.GetActionAttributeValues collapses
actions by Action.Name into entitledFQNsToActions, losing distinct ID/namespace
variants; change the prefilter to call isRequestedActionMatch(..., false) when
deciding which ActionAttributeValues to keep, and stop deduping solely by name —
preserve distinct variants (e.g., keep actions keyed by their ID or
Name+Namespace as well as Name) so getResourceDecision can pick the exact match;
update the construction of entitledFQNsToActions to store multiple variants per
attrValFQN (not just unique names) and ensure getResourceDecision still consumes
the new structure, then add a regression test that creates two
registered-resource actions with the same Name but different ID/namespace on the
same attribute FQN to verify strict/namespace-specific requests choose the
correct variant.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@service/internal/access/v2/pdp.go`:
- Around line 103-116: The code mutates caller-owned Value objects
(attr.GetValues()) by reusing their pointers in
allEntitleableAttributesByValueFQN and later appending to Value.SubjectMappings;
to fix, create deep copies of each policy.Value (or at minimum copy the Value
struct and reset/clone its SubjectMappings slice) before storing/inspecting them
in allEntitleableAttributesByValueFQN and before any code that appends mappings
(refer to allEntitleableAttributesByValueFQN, attr.GetValues(), and
Value.SubjectMappings), so the original attribute definitions are never
modified; also add a regression test that constructs a legacy PDP then a strict
PDP from the same input (exercise NewJustInTimePDP reuse path) to ensure
mappings are not accumulated across builds.
- Around line 314-345: The current prefilter over
entityRegisteredResourceValue.GetActionAttributeValues collapses actions by
Action.Name into entitledFQNsToActions, losing distinct ID/namespace variants;
change the prefilter to call isRequestedActionMatch(..., false) when deciding
which ActionAttributeValues to keep, and stop deduping solely by name — preserve
distinct variants (e.g., keep actions keyed by their ID or Name+Namespace as
well as Name) so getResourceDecision can pick the exact match; update the
construction of entitledFQNsToActions to store multiple variants per attrValFQN
(not just unique names) and ensure getResourceDecision still consumes the new
structure, then add a regression test that creates two registered-resource
actions with the same Name but different ID/namespace on the same attribute FQN
to verify strict/namespace-specific requests choose the correct variant.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1045d389-d60a-4d33-94dc-8c2d747a43ac

📥 Commits

Reviewing files that changed from the base of the PR and between e03b0e5 and 7ef6a6e.

📒 Files selected for processing (4)
  • service/internal/access/v2/evaluate.go
  • service/internal/access/v2/evaluate_test.go
  • service/internal/access/v2/pdp.go
  • service/internal/access/v2/pdp_test.go

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 381.328778ms
Throughput 262.24 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.852719192s
Average Latency 396.516987ms
Throughput 125.46 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

AllowDirectEntitlements bool `mapstructure:"allow_direct_entitlements" json:"allow_direct_entitlements" default:"false"`

// enforce strict namespaced policy evaluation behavior in access decisioning
NamespacedPolicy bool `mapstructure:"namespaced_policy" json:"namespaced_policy" default:"false"`
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is currently a seperate feature flag under service.authorization.namespaced_policy, should it be seperate? or should we figure out a way to rely on the service.policy.namespaced_policy flag?

maybe namespaced_policy and namespaced_decisioning are seperate features?

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.

Good question. In my mind, they are different settings (require administration of the policy constructs with namespaces, drive entitlement resolution via namespaces), but one feature: namespaced policy. Are there any global/temporary config locations for cross-cutting features like this, or temporary features?

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.

Also, I'm wondering if to us they're separate features because of service boundaries and intent, but to customers/admins they might really more like key management (crossing KAS and policy) where the real goal is to rely on namespaces everywhere or to not. 🤔

Copy link
Copy Markdown
Member Author

@elizabethhealy elizabethhealy Apr 7, 2026

Choose a reason for hiding this comment

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

ya my thought is from a consumer standpoint, theyre probably the same. but then maybe thats something we do in the charts at deployment time? from a dev standpoint i like the separate flags, i think we had something similar with key_managment? like a top level key_managment flag and one within services.kas


The normative request-action contract supports three request shapes. During evaluation, matching is always applied per namespace context (derived from the rule/value being evaluated), not globally.

Request-action identity precedence is explicit:
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.

Confirming, this is the GetDecisionRequest? If so, the action name has historically been required at the protovalidation level and the id ignored.

Copy link
Copy Markdown
Member Author

@elizabethhealy elizabethhealy Apr 7, 2026

Choose a reason for hiding this comment

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

correct. with namespaced decisioning, because we can have multiple actions with the same name, we now allow id/namesapce to specify a namespaced action and use a stricter order to avoid ambiguity:

  • action.id first (if provided)
  • otherwise action.name
  • and if action.namespace is provided, it further scopes the match

so same proto shape, but evaluation is now namespace-aware and deterministic when the action id is sent. ill update the ADR with some clarity on the proto requirements.

AllowDirectEntitlements bool `mapstructure:"allow_direct_entitlements" json:"allow_direct_entitlements" default:"false"`

// enforce strict namespaced policy evaluation behavior in access decisioning
NamespacedPolicy bool `mapstructure:"namespaced_policy" json:"namespaced_policy" default:"false"`
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.

Good question. In my mind, they are different settings (require administration of the policy constructs with namespaces, drive entitlement resolution via namespaces), but one feature: namespaced policy. Are there any global/temporary config locations for cross-cutting features like this, or temporary features?


if namespacedPolicy {
ns := sm.GetNamespace()
if ns == nil || (ns.GetId() == "" && ns.GetFqn() == "") {
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.

Just validating - potentially skipping some Subject Mappings here is safe because a user would only be granted less entitlements, therefore failing closed instead of open, right?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yep exactly. When namespacedPolicy is enabled, skipping unnamespaced SMs is fail-closed behavior: we only reduce the set of candidate entitlements, which can only keep decision the same or move PERMIT -> DENY, never DENY -> PERMIT.

So this cannot grant extra access; it can only be stricter.


namespaceName := namespaceNameFromPolicyNamespace(rr.GetNamespace())

fullyQualifiedValue := identifier.FullyQualifiedRegisteredResourceValue{
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.

How should these states be handled?

  1. Auth service flag requires namespacing all the policy. Unnamespaced Registered Resources still exist. Request comes in for https://reg_res/example_rr_name/value/value.
  2. Auth service flag requires namespacing all the policy. All Registered Resources have been moved into namespaces, like https://example.com/reg_res/example_rr_name/value/value. Request comes in for https://reg_res/example_rr_name/value/value.
  3. Auth service flag is off and therefore does not require namespacing all the policy. A Registered Resource is namespaced, like https://example.com/reg_res/example_rr_name/value/value. Request comes in for https://reg_res/example_rr_name/value/value.

Maybe we need an expected behavior matrix to match against the implementation/tests?

Copy link
Copy Markdown
Member Author

@elizabethhealy elizabethhealy Apr 7, 2026

Choose a reason for hiding this comment

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

  1. in that scenario we don’t reject the RR just because it’s unnamespaced. (do you think we should?)
    Flow is: resolve the RR value FQN, evaluate each RR AAV, derive required namespace from the AAV’s attribute value context, in strict mode (EnforceNamespacedEntitlements=true), only allow AAV actions whose namespace matches that required namespace (otherwise fail/deny).
    So enforcement is at the AAV/action matching layer, not an upfront “RR must be namespaced” check.

1A: EnforceNamespacedEntitlements=true + namespaced RR FQN request, flow is: resolve RR value by the namespaced RR FQN, evaluate RR AAVs for requested action, derive required namespace from each AAV’s attribute-value context, enforce strict namespace match for action evaluation per AAV, return permit/deny from those namespace-scoped results.
And since RR create/update already enforces AAV namespace consistency with the RR namespace, this path stays aligned.

  1. assuming they've done the migration/pruning (and the old un-namespaced RRs no longer exist in the db)
    Flow: request uses legacy/global RR FQN (https://reg_res/...), all RR data is now namespaced-only, lookup for legacy FQN won’t resolve a registered resource value (bc it doesnt exist), decision returns deny / not-found path (fail-closed), not permit fallback.

2A: if they havent pruned the un-namespaced RRs, then this behaves like 1.

  1. If https://reg_res/example_rr_name/value/value does not exist in the db (ie migration/pruning has taken place) then fail/deny. If it does still exist in the db (no pruning yet) -- then we match the existing behavior -- PDP resolves RR value using legacy/global FQN key (https://reg_res/...) if present. AAV action matching is name-based legacy behavior (no strict namespace requirement). Rules evaluate as before; decision can permit/deny based on entitlement/rule match.
    So: legacy RR requests continue to work in non-strict mode, assuming legacy RR entries exist in memory.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@adr/decisions/2026-03-30-namespaced-subject-mappings-decisioning.md`:
- Around line 62-66: The Consequences bullets are stylistically repetitive —
three items start with "🟩 **Good**, because..."; reword at least two of these
to vary sentence openings while preserving meaning (for example start one with
"Provides ..." or "Enables ..." and another with "Allows ..." or "Ensures ..."),
and optionally adjust the negative bullets for parallelism (e.g., change "🟥
**Bad**, because..." to "However, ..." or "Drawback: ...") so the section reads
less repetitive without changing technical content; update the lines containing
the "🟩 **Good**, because" and "🟥 **Bad**, because" bullets accordingly.

In `@service/internal/access/v2/pdp.go`:
- Around line 203-222: The function namespaceNameFromPolicyNamespace silently
ignores parse errors; update it to emit a trace-level log when identifier.Parse
returns an error so failures are observable during rollout: in
namespaceNameFromPolicyNamespace, after calling
identifier.Parse[*identifier.FullyQualifiedAttribute](ns.GetFqn()), if err !=
nil call the appropriate trace logger (e.g., process or package logger
accessible at call site) to log the error and the failing FQN, then continue
returning "" to preserve fail-closed behavior; ensure you reference
namespaceNameFromPolicyNamespace and identifier.Parse in your change.
🪄 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: b0ebccf2-5ff7-4e45-894c-7302717eebf8

📥 Commits

Reviewing files that changed from the base of the PR and between eb7dd89 and ca09e51.

📒 Files selected for processing (8)
  • adr/decisions/2026-03-30-namespaced-subject-mappings-decisioning.md
  • service/authorization/v2/authorization.go
  • service/authorization/v2/config.go
  • service/internal/access/v2/evaluate.go
  • service/internal/access/v2/pdp.go
  • service/internal/subjectmappingbuiltin/subject_mapping_builtin_actions.go
  • service/internal/subjectmappingbuiltin/subject_mapping_builtin_actions_test.go
  • tests-bdd/cukes/resources/platform.namespaced_policy.template

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 423.153354ms
Throughput 236.32 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.909126217s
Average Latency 397.014279ms
Throughput 125.28 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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.255426ms
Throughput 251.73 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.315830555s
Average Latency 401.73786ms
Throughput 124.02 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 398.309243ms
Throughput 251.06 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.230817371s
Average Latency 400.104974ms
Throughput 124.28 requests/second

@cshamrick cshamrick self-requested a review April 9, 2026 13:49
cshamrick
cshamrick previously approved these changes Apr 9, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 384.817745ms
Throughput 259.86 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.04881316s
Average Latency 409.467947ms
Throughput 121.81 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

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

See the workflow run for details.

@elizabethhealy elizabethhealy requested a review from cshamrick April 9, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants