Extend the read-only treatment to OAuth2 clients and write-intent GETs
CI / full-gate (push) Successful in 2m42s
CI / full-gate (push) Successful in 2m42s
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
## Unfinnished work
|
||||
|
||||
- [ ] Deleting a group orphans its permission grants. `groupsDelete` removes every `Group:<name>#members` tuple, but nothing removes `Permission:X#granted@Group:<name>#members` — so re-creating a group with the same name silently restores every permission it used to hold. Pre-existing (the same orphan was reachable via the old Permissions screen), but granting to a group is now a one-click flow on the group's own page, which raises the odds a lot. Raised by the stability review 2026-08-05.
|
||||
- [ ] Guard the group paths to self-lockout, or accept them explicitly. The self-revoke guard covers only your own *direct* grants on the Users screen; unticking a permission on a group you belong to, removing yourself from that group, or deleting it can all still strip your own effective access with no warning. Same scope the deleted Permissions screen had, and recorded in AGENTS.md as a known gap — the robust fix is a "last effective holder" check, which needs a reverse Keto query. Raised by the stability review 2026-08-05.
|
||||
- [ ] The permission picker has no concurrency baseline, so two operators editing the same user/group silently discard each other's change (standard lost-update on a set-based form — and the natural "two of us are onboarding the new hire" workflow produces exactly it). Sketch: post the rendered set as a hidden baseline; if it no longer matches Keto, re-render with "this changed while you had the page open" rather than applying. Fits the existing "the form is the whole truth" model instead of fighting it. Raised by the product review 2026-08-05.
|
||||
- [ ] A grant whose plugin was uninstalled is invisible and unremovable in the GUI. `grantDiff` deliberately never revokes an undeclared name (so an unrelated save can't drop it), but nothing *shows* it either — so it can't be audited or cleaned, and reinstalling that plugin silently reactivates access nobody remembers granting. Sketch: a read-only "held, but no installed plugin offers this" list with a remove action. Raised by the product review 2026-08-05.
|
||||
- [ ] A plugin may gate a route on a permission it never declares — declaring stays optional on purpose (mandatory declaration would warn on the legitimate cross-plugin sharing case). The cost is a dead end: the picker is built from declarations only, so that route is ungrantable from the GUI with no boot error, no warning, and a permanent 403 as the operator's only clue. Sketch: a discovery *warning* (not an error) naming the gated-but-undeclared permission. Raised by the product review 2026-08-05.
|
||||
|
||||
Reference in New Issue
Block a user