Skip to content

Commit 712e185

Browse files
fix(security): stamp platform default permission sets managed_by: 'platform' so os meta resync reconciles them (#8692) (#9129)
`bootstrapPlatformAdmin` seeded the default permission sets without writing `managed_by`, so the value fell to the declaration's `defaultValue: 'admin'`. `os meta resync` reconciles only platform-owned rows, so every shipped default set took the skip branch (measured: resynced 0 / resyncSkipped 8) and each skip was logged as an "intentional override" for a row no admin had touched. Implements the maintainer ruling of 2026-08-15 (Option A): - the seed insert stamps `managed_by: 'platform'` explicitly, matching `bootstrap-builtin-positions.ts` and `bootstrap-system-capabilities.ts`; - FORWARD ONLY -- no migration, no restamp of existing 'admin' rows, since a stored 'admin' cannot be told apart from a real Setup takeover and rewriting it could silently overwrite admin edits on the next resync; - the skip warn drops its "(intentional override)" claim of intent; - the seeder docblock records what pre-ruling installs carry and why they keep the skip; - two comments claiming the posture "keeps the platform defaults env-authored -- the posture bootstrapDeclaredPermissions relies on" are removed: measured false, since bootstrapDeclaredPermissions special-cases only 'package'. The #8804 pin suite now asserts both sides: a fresh install stores 'platform' and resyncs every set, and a pre-ruling 'admin' row is still skipped with its content intact. Claude-Session: https://claude.ai/code/session_01Y26DJEHSBhhAQ6wwfsHNza Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2420641 commit 712e185

3 files changed

Lines changed: 306 additions & 90 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
"@objectstack/plugin-security": patch
3+
---
4+
5+
fix(security): platform default permission sets are stamped `managed_by: 'platform'`, so `os meta resync` stops skipping every one of them (#8692)
6+
7+
<!-- adr-0087: not-required (no-migration-prescription) One column value added to
8+
one seeder's INSERT, plus a reworded warn line. Nothing authorable is renamed,
9+
retired or tombstoned, so there is no conversion to register — and the ruling
10+
this implements explicitly prescribes NO migration for existing rows (see
11+
below), which is the opposite of a migration prescription rather than an omitted
12+
one. -->
13+
14+
`bootstrapPlatformAdmin` seeded the default permission sets
15+
(`admin_full_access` / `member_default` / `viewer_readonly` …) **without writing
16+
`managed_by`**, so the value fell to the declared `defaultValue: 'admin'` on
17+
`sys_permission_set`. `os meta resync` only reconciles rows the platform still
18+
owns (`managed_by` absent or `'platform'`), so the platform's own default sets
19+
took the skip branch — **measured on a real engine: `resynced 0` /
20+
`resyncSkipped 8`, every shipped set**, each one logged as an *"intentional
21+
override"* for a row no admin had ever touched.
22+
23+
That is the exact inverse of what the resync flag was built for (#2705:
24+
*"reconcile the row to the shipped dist so a dev source edit takes effect
25+
without `--fresh`"*). The command could not perform, for the rows it names in
26+
its own help text, the one job it exists to do.
27+
28+
**The seed insert now stamps `managed_by: 'platform'` explicitly**, which also
29+
puts this seeder in line with its two siblings in the same package —
30+
`bootstrap-builtin-positions.ts` and `bootstrap-system-capabilities.ts` both
31+
stamp `'platform'` rather than inheriting a default. A fresh install's default
32+
sets are now platform-owned, and a resync reconciles all of them. Admin-takeover
33+
protection is unchanged in shape and becomes *real* rather than nominal: a set
34+
an admin takes over in Setup is stamped `'admin'` by the projection path, so
35+
platform-seeded and admin-authored rows finally carry **different** values
36+
instead of the same one.
37+
38+
**Forward-stamp only — existing rows are deliberately NOT migrated.** A stored
39+
`'admin'` is indistinguishable between "the old seeder's field default" and "an
40+
administrator took this set over in Setup". Restamping legacy rows to
41+
`'platform'` would make genuine admin customizations reconcilable and could
42+
silently overwrite them on the next `os meta resync`, so pre-existing rows keep
43+
the skip permanently and by decision. Report, don't rewrite. A legacy install
44+
that wants its platform defaults reconciled has to re-own the rows deliberately
45+
(or re-seed with `--fresh`) — an operator's choice, not one a boot makes for
46+
them. The seeder's docblock records this so the next reader finds a decision
47+
rather than a mystery.
48+
49+
**The skip warning stops claiming intent.** It read
50+
`… row is admin-owned (intentional override)`; on any pre-existing install that
51+
sentence is false, because the only writer may have been this same seeder one
52+
call earlier. It now reads `… row is admin-owned` — provenance and action, no
53+
claim about anybody's intent.
54+
55+
Two comments asserting that the insert-once posture *"keeps the platform
56+
defaults env-authored — the posture `bootstrapDeclaredPermissions` relies on"*
57+
are removed: that reliance was measured false. `bootstrapDeclaredPermissions`
58+
special-cases only `managed_by === 'package'`; every other value — `'platform'`
59+
included — falls to the same `skippedEnvAuthored` branch, so its behaviour is
60+
identical before and after this change.
61+
62+
The pin suite added by the measurement round now asserts both sides of the line
63+
the ruling drew: a fresh install stores `'platform'` and resyncs everything, and
64+
a pre-ruling `'admin'` row is still skipped with its content intact.

0 commit comments

Comments
 (0)