Repository navigation
Commit e078506
Part of #15204
Clause-②: no
Stage **4** of #15204 (stage plan 6094501866): `verify` provisions its
RLS probe persona through the registry, not a set row. Claimed in the
amendment 6106681412. The card stays open; its other stages are
untouched here.
## What changes
`packages/verify/src/rls.ts`, `provisionRlsProbePersona`:
- **Before:** it found or created a `sys_permission_set` row named
`verify_rls_probe`. When the row was missing, it minted one with the
probe's object permissions and RLS serialized into row columns, then
granted it.
- **After:** it mints no permission set.
1. It asks the **security catalog**, through
`securityCatalogReaderOf(ql).resolve('permission', 'verify_rls_probe')`.
That is the read the authorization resolver itself uses (ADR-0131
D3/D4). `rlsProbeSecurity(config)` registers the set at boot. A stack
booted without it now fails here, loudly, instead of granting a name
that resolves to nothing.
2. It **reads** the id of the `sys_permission_set` row the boot already
seeded for that registered set.
`sys_user_permission_set.permission_set_id` is still a required column
(it goes in stage 8 or C7b), and the platform derives the grant's name
from it and refuses a disagreement (`grant-permission-set-name.ts`).
This is no transition piece: no new read or write is added for an
intermediate state. It is the one remaining existing read, narrowed from
find-or-create to find.
3. It writes the one grant, carrying both columns as before.
- Either missing piece (no catalog entry, or no seeded row) throws and
writes nothing. `objectstack verify --rls` already turns any
provisioning failure into `probe.degraded` plus a hard failure, so
neither case can pass as a weaker persona.
## Measured before building (`origin/main` `9f5eca52b`)
- **The boot seeds the row.** `SecurityPlugin` passes
`options.defaultPermissionSets` (which `rlsProbeSecurity` extends with
the probe set) as `bootstrapPermissionSets` to `bootstrapPlatformAdmin`
at `kernel:ready`. That function inserts a row for every bootstrap set
it does not find (`bootstrap-platform-admin.ts` around line 873).
- A real `bootStack(showcase, { security: rlsProbeSecurity(config) })`
held exactly one `verify_rls_probe` row afterwards: organization null,
`managed_by: platform`.
- **The catalog serves the set.** On the same boot,
`securityCatalogReaderOf(ql).resolve('permission', 'verify_rls_probe')`
answered an entry with 24 objects and 24 `rowLevelSecurity` rules. The
control, an unregistered name, answered undefined.
- **Multi-tenant was not measured.** A multi-tenant boot needs the
enterprise `@objectstack/organizations` package, which this repository
cannot load. The PR's CI is not shown to cover it either: no test drives
`verify --rls` end to end.
## Verification
All at `72cc4a67c8`:
- **Build:** `pnpm --filter '@objectstack/example-showcase^...' --filter
'@objectstack/cli...' build` exited 0, as did the
`@objectstack/dogfood^...` build.
- **Unit tests:** `pnpm --filter @objectstack/verify test` passed 29
files, 236 tests. `pnpm --filter @objectstack/verify typecheck` was
clean, including `check:test-typecheck`.
- **`rls-persona-grant.test.ts`, rewritten.** It pins four cases: the
registered set is granted by name with the seeded row's id and no set
row is inserted; no seeded row refuses and writes nothing; a row with no
catalog entry refuses and writes nothing; no catalog bound refuses and
writes nothing.
- **Reverse verification (one-off, not kept):**
- `main`'s `rls.ts` was restored under the new test with `git restore
--source=9f5eca52b`. The mutant held `genId('ps')` once and
`securityCatalogReaderOf` zero times. The result was **3 failed, 1
passed**: every refusal case went red, and the seeded-row case stays
green because `main` also reuses a found row.
- Restored with `git checkout HEAD`. Blob `edefdfbc2589` matched HEAD,
and `git diff HEAD` was empty.
- **End to end:** `objectstack verify --app ./objectstack.config.ts
--rls --json` was run on `examples/app-showcase`, twice on `main`'s code
and twice on this branch.
- All four runs had `hardFailures: 0` and a probe that was not degraded
(`grantedObjects: 24`).
- All four had identical totals: 264 objects, 38 consistent, 0 holes,
131 member-visible, 62 probe-blocked, 33 skipped.
- All four had identical per-object and per-position statuses.
- The only difference was one run's probe target for `showcase_invoice`,
adopted rather than created after an admin create answered 400. The
second run on this branch created it again, so this is run-to-run noise.
- **Dogfood suite, in full** (`pnpm --filter @objectstack/dogfood test`;
its files import `@objectstack/verify`): 245 files passed, 1 skipped;
1977 tests passed, 9 skipped; exit 0.
- **Gates:** `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --ran FILE` derived 61; 60 ran green and 1 is
NOT MEASURED. That one is `check:dual-build-cjs-loads`, which exited 3
(PREREQUISITE NOT MET: it needs a whole-repo build) and is left to CI.
## Landing order with S5c
#22802 (#15196 S5c, comments only) edits the comment this PR replaces.
Branching rules forbid stacked series, so this branch is cut from
`main`, not from S5c. Whichever of the two lands second takes one
textual conflict in `provisionRlsProbePersona`'s comment block, resolved
by keeping this PR's text. #22802 also corrects `rlsProbeSecurity`'s
docblock, which this PR leaves untouched for that reason.
## Acceptance notes
- **Carried by stage 6b-2:** this read depends on the boot seeding a
`sys_permission_set` row for every registered bootstrap set
(`bootstrapPlatformAdmin`). Stage 6b deletes "platform-admin
materialization". If 6b-2 lands before stage 8 or C7b drops the
`permission_set_id` requirement, it must carry this read along with the
other grant writers that read a seeded id. Otherwise `verify --rls`
reports a degraded persona, loudly, which is the failure mode this PR
chose over minting.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01M5baMwzrfukawVWc496yxD)_
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9814035 commit e078506
3 files changed
Lines changed: 143 additions & 69 deletions
File tree
- .changeset
- packages/verify/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
6 | | - | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
7 | 8 | | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
15 | 21 | | |
16 | 22 | | |
17 | 23 | | |
18 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
19 | 31 | | |
20 | 32 | | |
21 | 33 | | |
| |||
33 | 45 | | |
34 | 46 | | |
35 | 47 | | |
36 | | - | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
37 | 67 | | |
38 | 68 | | |
39 | 69 | | |
40 | 70 | | |
41 | 71 | | |
| 72 | + | |
42 | 73 | | |
43 | 74 | | |
44 | 75 | | |
45 | 76 | | |
46 | 77 | | |
47 | 78 | | |
48 | 79 | | |
| 80 | + | |
49 | 81 | | |
50 | 82 | | |
51 | 83 | | |
52 | 84 | | |
| 85 | + | |
53 | 86 | | |
54 | 87 | | |
55 | 88 | | |
56 | 89 | | |
57 | 90 | | |
58 | | - | |
| 91 | + | |
59 | 92 | | |
60 | 93 | | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
| 94 | + | |
68 | 95 | | |
69 | | - | |
70 | | - | |
71 | | - | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
72 | 102 | | |
| 103 | + | |
73 | 104 | | |
74 | | - | |
75 | | - | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
76 | 129 | | |
77 | 130 | | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
83 | 135 | | |
84 | 136 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| 82 | + | |
82 | 83 | | |
83 | 84 | | |
84 | 85 | | |
| |||
299 | 300 | | |
300 | 301 | | |
301 | 302 | | |
302 | | - | |
| 303 | + | |
303 | 304 | | |
304 | | - | |
| 305 | + | |
305 | 306 | | |
306 | 307 | | |
307 | 308 | | |
| |||
401 | 402 | | |
402 | 403 | | |
403 | 404 | | |
404 | | - | |
405 | | - | |
406 | | - | |
407 | | - | |
408 | | - | |
409 | | - | |
410 | | - | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
411 | 415 | | |
412 | | - | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
413 | 419 | | |
414 | 420 | | |
415 | 421 | | |
| |||
441 | 447 | | |
442 | 448 | | |
443 | 449 | | |
444 | | - | |
445 | | - | |
446 | | - | |
447 | | - | |
448 | | - | |
449 | | - | |
450 | | - | |
451 | | - | |
452 | | - | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
453 | 472 | | |
454 | 473 | | |
455 | | - | |
| 474 | + | |
456 | 475 | | |
457 | | - | |
458 | | - | |
459 | | - | |
460 | | - | |
461 | | - | |
462 | | - | |
463 | | - | |
464 | | - | |
465 | | - | |
466 | | - | |
467 | | - | |
468 | | - | |
469 | | - | |
470 | | - | |
471 | | - | |
472 | | - | |
473 | | - | |
474 | | - | |
475 | | - | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
476 | 481 | | |
477 | 482 | | |
478 | 483 | | |
| |||
481 | 486 | | |
482 | 487 | | |
483 | 488 | | |
484 | | - | |
| 489 | + | |
485 | 490 | | |
486 | 491 | | |
487 | 492 | | |
| |||
0 commit comments