Skip to content

fix(station): index EditPermission policies under the permission resource - #649

Open
MRmarioruci wants to merge 1 commit into
mainfrom
fix/editpermission-policy-resource-index
Open

fix(station): index EditPermission policies under the permission resource#649
MRmarioruci wants to merge 1 commit into
mainfrom
fix/editpermission-policy-resource-index

Conversation

@MRmarioruci

@MRmarioruci MRmarioruci commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Change

Approval policies are selected through a resource index: a policy is filed under the keys its specifier produces, and at evaluation time policies are looked up by the keys the operation produces. The two sides have to agree.

RequestSpecifier::EditPermission(Resource(R)) filed the policy under R, while RequestOperation::EditPermission only ever emits Resource::Permission(Update). Both scopes now index under Permission(Update).

migration.rs also rebuilds the request policy resource index on upgrade. The index is written once when a policy is inserted, so correcting the mapping alone would leave existing policies filed under the old keys. The rebuild is idempotent and O(stored policies).

Tests

  • edit_permission_specifier_indexes_under_the_operation_resource — both scopes map to Permission(Update).
  • edit_permission_specifier_never_matches_an_unrelated_operation — round-trip invariant: every key a specifier indexes under is emitted by its own operation, and none by an unrelated one.
  • edit_permission_policy_is_not_returned_for_the_target_resource — repository level.

cargo test -p station --lib passes (397). Clippy warning count unchanged from baseline; cargo fmt clean.

Behaviour notes for review

  1. Granular scope now behaves as Any. EditPermission(Resource(R)) and EditPermission(Any) index identically, so a rule intended for one resource now matches every permission-change request. Deciding the fate of the granular form — implement real two-sided scoping via a dedicated key, or reject it at validation — is left as follow-up.
  2. Already-approved requests are unaffected. Status is persisted; the rebuild only changes future evaluations.

Follow-up

Generalising the round-trip invariant to a table over every RequestSpecifier variant would be worthwhile, but it would also flag SetDisasterRecovery / SystemUpgrade / SystemRestore, which deliberately share System(Upgrade) and would need an explicit allowance.

…urce

RequestSpecifier::EditPermission(Resource(R)) indexed the policy under R
itself rather than under Resource::Permission(Update). The EditPermission
operation only ever emits Permission(Update), so the granular form never
governed permission changes, and because the resource index is the sole
policy selector it was instead returned for any operation whose resource
is R. With OR-combined evaluation that turned a rule about who may change
a permission into an additional, weaker approval path for the operations
on that resource.

Index both scopes under Permission(Update), and rebuild the request policy
resource index on upgrade so policies already stored under the old keys are
refiled. Correcting the mapper alone would leave existing entries pointing
at the wrong resources.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@MRmarioruci
MRmarioruci marked this pull request as ready for review August 6, 2026 13:53
@MRmarioruci
MRmarioruci requested a review from a team as a code owner August 6, 2026 13:53
@MRmarioruci
MRmarioruci requested a lite review from Copilot August 6, 2026 13:53
@zeropath-ai

zeropath-ai Bot commented Aug 6, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to ab053f2.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► core/station/impl/src/mappers/request_policy.rs
      Modify EditPermission handling to map to Update permission, with explanatory comment
► core/station/impl/src/migration.rs
      Add post_run to rebuild request policy resource index on migration, and implement rebuild_request_policy_resource_index() routine
► core/station/impl/src/repositories/request_policy.rs
      Update tests to reflect new RequestSpecifier and ResourceSpecifier imports and behavior; add test ensuring edit permission policy is not returned for target resource

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 correctness/security issue in Station approval-policy selection where EditPermission(Resource(...)) policies were indexed under the target resource instead of the EditPermission operation’s resource key (Permission(Update)), causing them to (a) not govern permission changes and (b) accidentally become an extra approval path for unrelated operations on that resource. Also ensures existing persisted policies are re-indexed on upgrade.

Changes:

  • Update RequestSpecifier::EditPermission(_) resource indexing to always file under Resource::Permission(PermissionResourceAction::Update).
  • Rebuild the request-policy resource index on every upgrade to correct existing stored index entries.
  • Add unit/repository tests to assert the indexing invariant and prevent unrelated-operation matches.

Reviewed changes

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

File Description
core/station/impl/src/mappers/request_policy.rs Fix EditPermission specifier resource mapping and add tests asserting correct indexing/invariant behavior.
core/station/impl/src/migration.rs Add post_run() upgrade hook to rebuild the request policy resource index from stored policies.
core/station/impl/src/repositories/request_policy.rs Add repository-level regression test ensuring EditPermission policies don’t match the target resource bucket.

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

Comment on lines +65 to +73
fn rebuild_request_policy_resource_index() {
let policies = REQUEST_POLICY_REPOSITORY.list();

REQUEST_POLICY_REPOSITORY.clear_indexes();

for policy in &policies {
REQUEST_POLICY_REPOSITORY.add_entry_indexes(policy);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants