Files
captoys/potluck/.agents/skills/creating-plugins/references/sandbox-boundaries.md
T
dckc 4b4ef8fea6 capsite: potluck, a fresh EmDash site (cloudflare:blog out of the box)
pnpm create emdash@latest potluck --pm pnpm --install --yes, per
https://docs.emdashcms.com/ ("Create your first EmDash site"); the
--yes defaults are cloudflare + blog. Replaces the old madmode/
starter (never committed).

Generated-by: create-emdash 1.2.0, run by Claude Opus 5.5
2026-10-07 19:57:43 -05:00

44 lines
3.6 KiB
Markdown

# Sandbox boundaries
Registry plugins run against a capability-gated host API, not the complete trusted EmDash runtime. Design within exported authoring types and do not infer an API from internal repositories or admin routes.
## Transport limits
- `ctx.http.fetch()` preserves binary requests and responses across both runners, but complete bodies are buffered and limited to 8 MiB of decoded bytes.
- Declared plugin route bodies are buffered with a 1 MiB default and 8 MiB author maximum. Raw route responses are buffered to 8 MiB.
- Media byte reads default to 10 MiB and cannot request more than 16 MiB.
- Neither test host reproduces deployed CPU, memory, or subrequest limits.
## Trusted-only surfaces
- `page:fragments` is accepted by shared authoring types but excluded from sandbox registration. Use validated `page:metadata`; raw HTML, scripts, and styles require a trusted native plugin.
- React admin code, Astro render components, build-time integrations, host bindings, Node built-ins, TCP sockets, and direct database access require trusted site code.
- Custom Portable Text definitions and Astro renderers remain native-only. Registry packages can use the declarative admin surfaces that the CLI serializes.
## Content and schema limits
- Schema access is read-only. Plugins cannot create, alter, attach, or delete collection definitions through `ctx.schema`.
- Content writes do not expose permanent deletion.
- Publication policy hooks can reject publish, schedule, and unpublish, but cannot transform the action or restore content.
- Publication and restore actions require separate capabilities and opaque revisions.
- Public URL resolution never returns previews.
## Taxonomy, redirect, comment, and media limits
- Taxonomy writes cannot manage definitions, attachments, term updates or deletion, or replace all assignments.
- Redirect writes cannot set host-owned fields and remain subject to host validation.
- Comment administration excludes trashed comments and linked user-account IDs. It cannot hard-delete or bulk-replace statuses.
- Media metadata writes cannot upload, replace, move, or delete files. Byte reads and content hashes require separate authority.
## Routes and admin UI
- `public: true` removes host authentication. It does not create a restricted public view; validate requests and return the minimum data.
- Raw routes use `pluginResponse()`, an allowlisted set of representation/download/redirect headers, host-owned caching and security headers, and no active same-origin browser content. They cannot back MCP tools.
- Credential, cookie, Cloudflare Access, proxy authorization, and EmDash CSRF headers never cross declared route-header boundaries.
- Saved-entry panels and actions receive canonical saved identity and version. Ordinary panel load and typing never send unsaved state. An explicit interaction can receive only extension-selected draft fields with `admin.editor-draft:read`, and can propose an atomic whole-field patch with the independent `admin.editor-draft:patch` capability. The host validates and previews a patch but never saves it automatically. Use capability-gated APIs to read saved content.
- `routeCtx.ui` carries host-attested admin locale, direction, and surface. Manifest labels remain static strings; the host does not consume plugin translation catalogs.
## Runner-only methods are not portable
Methods absent from public authoring types are not part of the registry contract even if one wrapper contains them. Write against `SandboxedPlugin` and exported context types, then test the feature through both bridges when behavior is runner-sensitive.