feat: add display kiosk host
This commit is contained in:
@@ -9,7 +9,9 @@ Related: [ADR 0006](../architecture/decisions/0006-versioned-capabilities-and-co
|
||||
(module database access), [ADR 0020](../architecture/decisions/0020-module-runtime-and-migration-execution-hardening.md)
|
||||
(module routing/lifecycle and migration execution),
|
||||
[ADR 0032](../architecture/decisions/0032-native-module-realtime-transport.md)
|
||||
(native module realtime), and
|
||||
(native module realtime),
|
||||
[ADR 0033](../architecture/decisions/0033-display-kiosk-host-contract.md)
|
||||
(authenticated display hosting), and
|
||||
[Module development](../module-development/README.md).
|
||||
|
||||
## Installed modules are trusted compiled backend code
|
||||
@@ -47,6 +49,7 @@ cooperative. None of them constrains a module that is not:
|
||||
| Permission declarations and the composed registry | Which permissions *this* module's own routes may name, checked when Core mounts them |
|
||||
| Route validation, overlap rejection, body limits | Deterministic, unambiguous HTTP routing and request bounds |
|
||||
| Scoped realtime channels, publishers, and subscriptions | Correct module-local state wiring, permission enforcement, and finite fanout — not process isolation |
|
||||
| Display declaration, permission, and exact publication record | Correct role selection and normal authorization for an eligible/running module — not browser isolation |
|
||||
| `Object.freeze` on contexts and services | Prevents accidental mutation; a module can still reach the underlying objects |
|
||||
| The `ModuleDatabase` facade | A typed, ergonomic surface — not a privilege reduction, since `execute` is arbitrary SQL |
|
||||
| Capability registry | Explicit inter-module wiring, not access control |
|
||||
@@ -155,6 +158,27 @@ shell owns the container, the loading state, and every error, so a failing modul
|
||||
rather than the shell. None of that is containment: once imported, a module UI is ordinary same-realm
|
||||
JavaScript, exactly as described above.
|
||||
|
||||
### A display page is authorized; its artifact bytes are not authority
|
||||
|
||||
Manifest version 6 binds a display artifact to one permission declared by the same module
|
||||
([ADR 0033](../architecture/decisions/0033-display-kiosk-host-contract.md)). The declaration rejects
|
||||
a `public` baseline: the current display host requires an ordinary authenticated cookie principal,
|
||||
and public/device identity is not approximated with an anonymous exception. Both the stable
|
||||
`/display/<module-id>` page and `/api/v1/module-displays/<module-id>` descriptor evaluate that exact
|
||||
permission through the normal Core evaluator. Client permission hints remain presentation only.
|
||||
|
||||
The versioned display artifact is anonymous code just like primary UI code. It is served only from
|
||||
the frozen eligible/running publication registry, by exact module identity and version, and never
|
||||
falls back to primary UI or opens the module directory. Fetching it grants no module HTTP, realtime,
|
||||
storage, or data authority. Disabled and dependency-blocked modules receive no page, descriptor, or
|
||||
artifact route; this is operational exposure control, not sandboxing.
|
||||
|
||||
The full-viewport host is a separate same-realm surface, not an iframe or containment boundary. It
|
||||
uses normal cookie authorization, the same scoped API/realtime context, and opaque signed object URLs
|
||||
without logging, proxying, extending, or re-signing them. It does not invoke the browser Fullscreen
|
||||
API. Display inventory, device credentials, public principals, variants, and targeting are deferred
|
||||
rather than silently granted.
|
||||
|
||||
### Dashboard arrangement is not an access control
|
||||
|
||||
Dashboard groups and placements are presentation configuration
|
||||
|
||||
Reference in New Issue
Block a user