todo: plugin permissions on by default for every role

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-22 00:22:25 +00:00
co-authored by Claude Fable 5
parent 78f9331b89
commit a01ae73a1f
2 changed files with 68 additions and 32 deletions
@@ -0,0 +1,36 @@
---
id: multi-user/a-plugin-s-permission-should-be-on-for-every
title: "A plugin's permission should be on for every role by default, off only on request"
theme: multi-user
status: open
created: 2026-08-22
date_source: stated
order: 21
---
**A plugin's permission should be on for every role by default, off only on request.** The owner's call,
2026-08-22. Installing a plugin should make it reachable by every role; taking it away from a role is
then a deliberate act. Today the opposite is true: install a plugin and nobody but the owner can see it
until someone grants it, role by role.
**This inverts a default that two files argue for explicitly, so it needs his decision on the record —
which this is.** `permissions/schema.ts` states it plainly: *"A MISSING ROW MEANS NO ACCESS. There is no
row that denies; absence denies… an empty table is a platform where members can reach nothing but their
own account, which is the correct state for a server that has just been installed."* And
`authorize.ts` opens with *"the failure mode of a permissive default is not a bug report — it is someone
else's session."* Both were written about the platform's own surface, not about plugins, which is the
distinction this item turns on.
Two facts that bound how far the change reaches, both from `authorize.ts`:
- **It can only ever mean `app` (and `confined`) permissions.** `execution` and `admin` are stripped even
when a row grants them, and `confined` is dropped for an account with no Linux user. A plugin declares
`app`, so the blast radius is the grantable surface and nothing below it.
- **There is no way to represent "no" today.** An opt-out model needs one — either a negative row, or
grants written for every role at install time so that absence keeps its current meaning. The second
needs no resolver change and keeps the table readable as the whole truth; it does mean a role added
later starts with nothing until backfilled. **Which of the two is his call, not mine.**
Related and unresolved: `multi-user/a-plugin-s-settings-routes-are-reachable-by` — a plugin granted to a
Member already exposes its `/_config`, and making plugins on-by-default makes that reachable by default
too. These two should land together, or the second stops being a latent hole and becomes an open one.