Skip to content

Commit 09e4b0e

Browse files
claude[bot]claude
andauthored
docs(comments): retire the present-tense elevation gate at the seven sites #13903 scoped (#14049)
Comment-only. The #11663 platform-admin re-anchor (leg L4) retired the walled platform-admin elevation gate: `bootstrapPlatformAdmin` writes no grant row under a walled posture and elevates nobody, it reports. Standing is derived per request at `resolve-authz-context.ts` §6b-config. Each site is corrected on its own reading, not by a sweep: two named a mechanism that no longer runs, one was stale only in its NAME (the reasoning it carries is still correct and survives verbatim in substance), and the two already-past-tense sites in `platform-admin-service.ts` are deliberately untouched. Claude-Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs Co-authored-by: Claude <noreply@anthropic.com>
1 parent 4bb09e8 commit 09e4b0e

6 files changed

Lines changed: 81 additions & 32 deletions

File tree

packages/core/src/security/platform-admin.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,14 @@ export interface PlatformAdminEmailConfig {
114114
*
115115
* It exists so that no consumer ever has a reason to split {@link raw} a
116116
* second time. Two readers need the as-typed form and neither may re-parse
117-
* to get it: the elevation gate's by-email `sys_user` lookup queries the
118-
* verbatim spelling alongside the normalized one (an imported/legacy row may
119-
* not be stored lowercased, and a driver `where` is an exact match), and the
120-
* walled boot diagnostic quotes the addresses back to the operator, who
121-
* should see what they wrote.
117+
* to get it: the platform-admin STANDING surface's by-email `sys_user`
118+
* lookup queries the verbatim spelling alongside the normalized one (an
119+
* imported/legacy row may not be stored lowercased, and a driver `where` is
120+
* an exact match) — that lookup is `resolvePlatformAdminStanding` in
121+
* plugin-security's `platform-admin-service.ts`, which inherited the
122+
* two-spelling discipline from the elevation gate the #11663 re-anchor
123+
* (leg L4) retired — and the walled boot diagnostic quotes the addresses
124+
* back to the operator, who should see what they wrote.
122125
*/
123126
readonly declaredSpellings: readonly string[];
124127
/** What the operator actually typed, when the variable was set to anything. */
@@ -284,9 +287,16 @@ export function matchesConfiguredPlatformAdmin(
284287
* and exported, because the row-and-verified predicate above is not the shape
285288
* every reader of `OS_PLATFORM_OWNER_EMAIL` needs:
286289
*
287-
* - the elevation gate (`plugin-security/bootstrap-platform-admin.ts`) must
288-
* keep the two halves SEPARATE — its `walled_owner_not_registered` and
289-
* `walled_owner_not_verified` diagnostics are different answers;
290+
* - the walled platform-admin STANDING surface must keep the two halves
291+
* SEPARATE — `resolvePlatformAdminStanding`
292+
* (`plugin-security/platform-admin-service.ts`, reported at boot by
293+
* `bootstrap-platform-admin.ts`) answers `registered` and `verified` as two
294+
* independent per-entry fields, so the operator's log can tell "not
295+
* registered yet" apart from "registered, NOT verified". ⚠️ That reason
296+
* predates the #11663 re-anchor and survives it: the pair used to be the
297+
* retired elevation gate's `walled_owner_not_registered` /
298+
* `walled_owner_not_verified` reasons — the mechanism moved, the need to
299+
* keep the halves apart did not;
290300
* - the creation-time operator stamp (`plugin-auth`) is handed an email
291301
* STRING by better-auth, before any row exists to read;
292302
* - the Layer 0 wall bypass takes a fast negative on the session's

packages/plugins/plugin-auth/src/last-admin-guard.test.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,9 +1609,20 @@ describe('[#5978] reverse verification: without the guard, the third path locks
16091609
// "Who is a platform admin" is resolved BY NAME: `resolveAdminUserIds` looks
16101610
// the permission set up as `where: { name: 'admin_full_access' }` and only then
16111611
// reads the grants pointing at its id. So the row named `admin_full_access` is
1612-
// itself part of the administrator evidence, and deleting it — or calling it
1613-
// something else — un-makes every platform admin in one write while `sys_user`,
1614-
// `sys_member` and `sys_user_permission_set` all stay exactly as they were.
1612+
// itself part of the GRANT-anchored administrator evidence, and deleting it —
1613+
// or calling it something else — un-makes every grant-anchored platform admin
1614+
// in one write while `sys_user`, `sys_member` and `sys_user_permission_set` all
1615+
// stay exactly as they were.
1616+
//
1617+
// ⚠️ Not "every platform admin": since the #11663 re-anchor (L2) standing has a
1618+
// SECOND anchor this write cannot reach — a config-anchored administrator (a
1619+
// declared `OS_PLATFORM_OWNER_EMAIL` address on a VERIFIED `sys_user` row) is
1620+
// derived at `resolve-authz-context.ts` §6b-config without reading this row at
1621+
// all, and `resolveAdminUserIds` counts it through the resolver's own
1622+
// predicate. Where one stands these refusals are re-priced away and the write
1623+
// is PERMITTED (pinned in `last-admin-guard.re-pricing.test.ts`). This file
1624+
// declares no owner emails, so the grant anchor is the whole population here
1625+
// and the refusals below are the live price.
16151626
//
16161627
// The block pins the same five things each earlier path did, plus the one this
16171628
// path adds: the guard must NOT go quiet on every other path afterwards.

packages/plugins/plugin-auth/src/walled-owner-operator-stamp.test.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,33 @@
88
*
99
* 1. **The pure decision matrix** (`shouldStampOwnerVerifiedAtCreation`) —
1010
* every bound of the contract as a direct call: walled family only,
11-
* declared-owner match only (compared the way the elevation gate
12-
* compares), operator-provisioned creation only (operator class, or the
13-
* bootstrap carve-out; provider and non-bootstrap self-serve NEVER).
11+
* declared-owner match only (compared the way the platform-admin
12+
* derivation compares), operator-provisioned creation only (operator
13+
* class, or the bootstrap carve-out; provider and non-bootstrap
14+
* self-serve NEVER).
1415
* 2. **The store probe** (`probeWalledOwnerAccountState`) over a REAL
15-
* `ObjectQL` engine — the same backend the elevation gate reads, so the
16+
* `ObjectQL` engine — the same backend the derivation reads, so the
1617
* probe's answers are measured against real driver representations, not
1718
* a fake's.
1819
* 3. **The wiring, end to end** — real better-auth pipeline over the real
1920
* engine (the `audience-bootstrap-seam` harness shape): the declared
2021
* owner's operator-provisioned row is BORN `email_verified`, and every
2122
* "never" cell of the matrix stays unverified through the same pipeline.
2223
* The verified read-back uses the shared [#11343] allow-list
23-
* (`isEmailVerifiedUserRow`) — the predicate the elevation gate itself
24-
* refuses on — so a green here IS "the elevation gate would accept this
25-
* row", without booting plugin-security.
24+
* (`isEmailVerifiedUserRow`) — the predicate the derivation itself
25+
* refuses on — so a green here IS "`resolve-authz-context.ts` §6b-config
26+
* would resolve PLATFORM_ADMIN for this row", without booting
27+
* plugin-security.
28+
*
29+
* ⚠️ The mechanism this file's prose used to name — the walled platform-admin
30+
* ELEVATION GATE — is RETIRED (#11663 leg L4): `bootstrapPlatformAdmin` writes
31+
* no grant row under a walled posture and elevates nobody, it reports.
32+
* Standing is derived PER REQUEST instead, and the implementation this file
33+
* covers says the same ([#11973] note in `walled-owner-operator-stamp.ts`:
34+
* "the invariant is enforced at the derivation site … rather than by an
35+
* elevation write; the stamp's value is unchanged"). One `it()` title below
36+
* still names the gate; correcting a title is an executable change, not a
37+
* comment fix, so it is left for the card that can price it.
2638
*/
2739

2840
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
@@ -88,8 +100,9 @@ const walledWithOwner = (owner = OWNER, posture = 'isolated') => {
88100
* `OS_PLATFORM_OWNER_EMAIL` takes one address OR a list (#11663 Choice 2B).
89101
* Before this card the stamp compared a candidate against the operator's WHOLE
90102
* raw value as one address, so under a list no member was ever stamped — the
91-
* account was born unverified and the elevation gate then refused it
92-
* (`walled_owner_not_verified`), silently.
103+
* account was born unverified, so the per-request derivation
104+
* (`resolve-authz-context.ts` §6b-config) resolved it non-admin and the walled
105+
* boot log reported it "registered, NOT verified", silently.
93106
*/
94107
const SECOND_OWNER = 'ops@corp.example';
95108
const OWNER_LIST = `${OWNER}, ${SECOND_OWNER}`;
@@ -392,8 +405,8 @@ describe('#12751 — probeWalledOwnerAccountState over a real ObjectQL engine',
392405
expect((await signUp(manager, SECOND_OWNER)).status).toBe(200);
393406
expect(await probeWalledOwnerAccountState(engine as never)).toBe('owner-unverified');
394407

395-
// One verified member is all the elevation gate needs, so it is all the
396-
// probe reports — the gate's own three outcomes, mirrored.
408+
// One verified member is all the derivation needs, so it is all the probe
409+
// reports — the standing surface's own outcomes, mirrored.
397410
const row = await userRow(engine, SECOND_OWNER);
398411
await engine.update(
399412
'sys_user',
@@ -440,8 +453,8 @@ describe('#12751 — the stamp lands through the REAL creation pipeline', () =>
440453
expect(res.status, `owner bootstrap sign-up refused: ${await res.clone().text()}`).toBe(200);
441454

442455
const row = await userRow(engine, OWNER);
443-
// Read back through the elevation gate's own predicate: a `true` here is
444-
// "bootstrapPlatformAdmin would elevate this row", representation
456+
// Read back through the derivation's own predicate: a `true` here is
457+
// "§6b-config would resolve PLATFORM_ADMIN for this row", representation
445458
// included.
446459
expect(
447460
isEmailVerifiedUserRow(row),

packages/plugins/plugin-security/src/platform-owner-wall-bypass.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@
3434
* (`normalizePlatformAdminEmail`: trim, then lowercase) — identical in effect to
3535
* the `String(email).trim().toLowerCase()` this used to spell inline.
3636
*
37-
* `walled-owner-operator-stamp.ts` (plugin-auth) and the elevation gate ask the
38-
* same parser for the same reason. The sites MUST agree — an account the stamp
39-
* verifies is one the gate must elevate and the wall must recognise.
37+
* `walled-owner-operator-stamp.ts` (plugin-auth) and the platform-admin
38+
* DERIVATION (`resolve-authz-context.ts` §6b-config, through
39+
* `matchesConfiguredPlatformAdmin`) ask the same parser for the same reason.
40+
* The sites MUST agree — an account the stamp verifies is one the derivation
41+
* must resolve `PLATFORM_ADMIN` for and the wall must recognise. Before the
42+
* #11663 re-anchor the third site was the elevation gate, which conferred that
43+
* standing by a WRITE; the agreement requirement is unchanged by its
44+
* retirement.
4045
*
4146
* Fail-closed by construction, both directions the ruling pins:
4247
* - no declared owner (env unset/blank, or a list REFUSED for an unparseable

packages/plugins/plugin-security/src/security-plugin.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5819,8 +5819,11 @@ export class SecurityPlugin implements Plugin {
58195819
* 4. The authoritative answer is the `sys_user` ROW (system-context by-id
58205820
* read, memoized per request-context like `__rlsMembershipStaged` /
58215821
* `__preImage`): {@link isVerifiedPlatformOwnerRow} = the canonical
5822-
* declared-owner email match (the elevation gate's twin,
5823-
* `platform-owner-wall-bypass.ts`) AND the #11343 verified-email
5822+
* declared-owner email match (`platform-owner-wall-bypass.ts`, shared
5823+
* with the platform-admin standing surface — it was extracted as the
5824+
* elevation gate's twin, and since the #11663 re-anchor retired that
5825+
* gate its opposite number is the per-request derivation at
5826+
* `resolve-authz-context.ts` §6b-config) AND the #11343 verified-email
58245827
* allow-list (`isEmailVerifiedUserRow` — absent-means-unverified).
58255828
* Missing row / unreadable store ⇒ `false`.
58265829
*

packages/types/src/env.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,16 @@ export function resolveTenancyPosture(): TenancyPosture {
165165
* The env variable naming the deployment's PLATFORM OWNER account
166166
* (#11184, the framework leg of cloud#1509).
167167
*
168-
* Exported as a constant so every message that refuses over it (the walled
169-
* boot guard in plugin-auth, the elevation refusal in plugin-security's
170-
* `bootstrapPlatformAdmin`) names exactly one spelling.
168+
* Exported as a constant so every message that names it quotes exactly one
169+
* spelling: the walled boot guard in plugin-auth, and plugin-security's
170+
* `bootstrapPlatformAdmin` — its fail-closed backstop for an undeclared or
171+
* refused config, and the config-derived standing it logs beside it.
172+
*
173+
* ⚠️ That second site is no longer an ELEVATION refusal. Since the #11663
174+
* platform-admin re-anchor (leg L4) the walled `bootstrapPlatformAdmin` writes
175+
* no grant row and elevates nobody — it reports. Standing is derived PER
176+
* REQUEST at `resolve-authz-context.ts` §6b-config, from a declared address
177+
* held on a VERIFIED `sys_user` row.
171178
*/
172179
export const PLATFORM_OWNER_EMAIL_ENV = 'OS_PLATFORM_OWNER_EMAIL';
173180

0 commit comments

Comments
 (0)