Repository navigation
Tech-debt batch 22: permissions.manage can no longer grant what it does not hold (#687) - #700
Merged
Merged
Conversation
…687) A permissions.manage holder could grant any registered key, to anyone including itself. Role and user grant writes now refuse keys the actor does not hold and refuse edits to more privileged accounts (unscoped admins and in-process callers are unrestricted), with a refusal reason. User-grant cache eviction moves into PermissionService so every caller gets cross-worker invalidation on commit; the endpoint helper is deprecated for removal in 0.1.0. Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
…ctor (#687) Role writes checked only the added keys, so a delegated manager could strip keys from a more privileged role. Refuse the admin role and any role whose effective permissions the actor does not fully hold. Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
A refusal was a PermissionDenied naming permissions.manage, which the actor holds. It is now a plain 403 with the reason on the API, and a form error on the Inertia view routes that UserEdit/RoleEdit toast instead of the generic save-failed message. Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
Deploying simple-module-python with
|
| Latest commit: |
0d423d8
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://f9c835a4.simple-module-python.pages.dev |
| Branch Preview URL: | https://tech-debt-b22-permissions-es.simple-module-python.pages.dev |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tech-debt batch 22 (from the 2026-10-28 scan).
Closes #687
What changed
Delegated grant writes are bounded by the actor's own access (
permissions/write_safety.py). Apermissions.manageholder who is not an unscoped admin:adminrole, or any role holding a key the actor lacks (whether keeping or stripping it).Unscoped admins and in-process callers (no request) are unrestricted. The same class of fix users:
users.managecan grantadmin; no last-admin guard on disable/demote #624 made forusers.manage.Refusals carry a reason. The API returns a 403 with the reason in
detail. The Inertia view routes return it as a form error, which UserEdit and RoleEdit show as the toast instead of the generic "save failed". This is a plain 403, notPermissionDenied, because the actor does holdpermissions.manage.Grant-cache eviction lives in the service.
PermissionService.set_user_permissionsevicts the user-grant cache on commit (cross-worker through the bus) for every caller, not just the two endpoints.permissions.deps.invalidate_grants_on_commitis deprecated,remove_in="0.1.0", and listed intest_deprecation_expiry.Known limits, left as-is deliberately:
users.managecan grantadmin; no last-admin guard on disable/demote #624's.Verification
make lint✓ ·make test-js✓ ·make test-py✓ (6375 passed, 39 skipped)PermissionDenied; both fixed.CHANGELOG.md[Unreleased]conflicted with Tech-debt batch 21: password reset revokes all credentials; admin create/invite after commit (#686 #692) #699; resolved as the union of both entries.https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4