Skip to content

security(service-settings, service-messaging, service-datasource, plugin-webhooks): plumbing reads and writes reach the engine with no principal and no system opt-in — the services-lane producers of #21908's closure #21913

Description

@objectstack-fleet

Why now. #21908 closes the principal-less hand-off in the security middleware: a non-system engine context with no principal will be denied (403 PERMISSION_DENIED, the seat's verdict on #21908). The measure-first round (6003676228) found the producers that reach the hand-off today. Each must take a route before the deny lands, or the deny breaks it. This card is one slice, a seat-owned sub-issue of #21908 with its domain and priority (domain:services seat 1, #6021, session_011K3zqE8Pv1Evw5hc8tZCnN).

Part of #21908.

The route for every producer here: the explicit system opt-in that exists today (isSystem: true on the engine call's context). ⛔ No new elevation API. ⛔ No change to what any door authorizes.

The trap to measure, per producer: an isSystem context short-circuits the gates the hand-off still runs before next(): package-managed, system-row, curated-capability, audience-anchor, engine-owned, and the delegated-administration gate. Moving a producer is neutral today only if none of those gates fires on its calls. Measure that per producer (an instrumented run is fine; commit nothing of it). A producer on which a gate fires is reported, not moved.

The producers (rows of 6003676228, positions on origin/main cab63967):

  • Row 7: service-settings src/settings-service.ts SettingsService.loadRows (sys_setting). It is on every REST request's execution-context build (localization), at boot, and on the audit write locale.
  • Row 8: SettingsService.upsertRow and the audit write in src/settings-service-plugin.ts.
  • Row 11: service-datasource loadDatasourceRows (boot). By static read, also src/datasource-admin-plugin.ts (sys_metadata) and src/datasource-secret-binder.ts (sys_secret).
  • Row 12: plugin-webhooks src/auto-enqueuer.ts AutoEnqueuer.doRefresh, and src/redeliver-guard.ts createWebhookRedeliverGuard (static).
  • Row 13: service-messaging src/sql-outbox.ts / src/sql-http-outbox.ts claim / claimDigest / reapExpired (background ticks).
  • Row 14: the emit fan-out, which covers src/messaging-service.ts writeEvent, src/inbox-channel.ts send / writeDeliveredReceipt, src/preference-resolver.ts loadRows and src/recipient-resolver.ts resolveEmail.

Not in this slice: rows 15 (listInbox / readReceiptStates) and 16 (StorageMetadataStore.createFile). Those act on the caller's own rows from a request door, and their posture waits for the maintainer's ruling (the seat's verdict on #21908).

Done when: each producer above passes the explicit system opt-in, or is reported with the gate that fires on it. An instrumented run of the dogfood suite and a booted dev composition records no principal-less context from these functions. The packages' suites are unchanged, and the isSystem census page is current.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsdomain:servicespriority:p1High: required for production / M2security

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions