EmDash 1.0: The Stable CMS With a Secure Plugin Registry ![rw-book-cover](https://blog.cloudflare.com/_emdash/api/media/file/01M3D0T7XHPBZM8YB0PX5W78EQ.png) 🔗 **Source:** [EmDash 1.0: The Stable CMS With a Secure Plugin Registry](https://blog.cloudflare.com/emdash-cms-plugin-registry/) > [!note]+ Document Notes > tags: [emdash-cms, plugin-security, plugin-registries, atproto, wordpress-alternatives] > author: Cloudflare > source: The Cloudflare Blog > reference: https://blog.cloudflare.com/emdash-cms-plugin-registry/ > date created: 2026-09-29 10:29 > > > [!info] Generated analysis — not the author's words. Sections below are machine-written > > from the captured source. Only text inside `> [!quote]` blocks is verbatim from the author. > > Do not quote or attribute any other line to the named author. > > # 🏷️ Title: EmDash 1.0: the stable CMS with a secure plugin registry > <!-- deep-read:sections start --> ## 🧭 Table of contents - [📝 Summary](#-summary) - [📖 Main content](#-main-content) - [🗒️ Notes](#️-notes) - [📚 References](#-references) - [🗣️ Paraphrase](#️-paraphrase) - [📰 Newsletter](#-newsletter) - [✅ Action items](#-action-items) - [🧪 Hypotheses](#-hypotheses) - [📊 Methodology](#-methodology) - [❓ Questions](#-questions) - [🔮 Future research](#-future-research) - [💡 Implications](#-implications) - [🧠 Learning styles assessment](#-learning-styles-assessment) - [📊 Accessibility assessment](#-accessibility-assessment) - [🌍 DEIB assessment](#-deib-assessment) - [✅ Logical validity](#-logical-validity) - [🛡️ DARVO analysis](#️-darvo-analysis) - [🎯 Conclusion](#-conclusion) - [🔄 Refactor appendix](#-refactor-appendix--emdash-10-the-stable-cms-with-a-secure-plugin-registry) ## 📝 Summary - **What happened.** The Cloudflare Blog announced EmDash 1.0 on 2026-09-28 (¶2): a free, MIT-licensed CMS built on Astro, plus a decentralized plugin registry built on AT Protocol and a sandboxed plugin model. The captured text carries no byline, so the author is recorded as Cloudflare. The post also announces an alpha of EmDash Build, an AI site builder (¶56). - **The claim.** Cloudflare says a WordPress-style plugin runs in the same PHP process as the whole application, with direct database, filesystem, and network access (¶30), while an EmDash sandboxed plugin gets only private storage plus abilities the plugin declares and the site administrator approves (¶31). The registry claim is that publishers keep their identity and signed release records, and EmDash verifies each release independently of the catalog (¶19 to ¶25). - **Why it matters.** It's a worked design for the plugin-trust problem that WordPress.org and every plugin marketplace share. Two separable ideas appear: capability-gated runtime isolation, and a publisher-owned signed package record that any catalog can index. - **Key stakeholders.** Cloudflare (author, EmDash's maintainer, and seller of the hosting products the post recommends), Noah Pham (named second maintainer, ¶14), the 175+ contributors (¶12), Avulux and Empress (named adopters, ¶8 and ¶17), plugin authors and site owners, and hosting platforms courted as partners (¶55). - **Risks and tradeoffs.** This is vendor content. Cloudflare sells Workers, Workers for Platforms, Dynamic Workers, Workers AI, and Sandbox containers, and the post names each of them as part of the EmDash story (¶10, ¶23, ¶50, ¶52, ¶59). The security comparison targets WordPress specifically and comes with no test, audit, or incident data. The registry supports free plugins only today (¶26). - **Bottom line.** The mechanism claims (per-plugin isolation, declared capabilities, signed records checked against publisher commits) are specific and checkable against the open-source code. The comparative claims (stability, security, "safer") are assertions in this source. Treat the design as a serious proposal, not as evidence that it works at ecosystem scale. ## 📖 Main content **The launch framing.** The post opens by answering a doubt: EmDash was announced on April 1, and some people took it for an April Fools' joke (¶0 and ¶1). ¶2 states it was not, and calls 1.0 "stable, free, and open source." ¶5 and ¶6 explain the 1.0 label as a response to adopters who asked for confidence in stability, security, upgrade safety, and maintenance commitment. The five-month work list covers data safety, migrations, editorial workflows, localization, plugin security, performance, and reliability of the admin, API, MCP, and media surfaces. **Evidence offered for production readiness.** Two named cases. Avulux converted a custom microsite and quotes its Director of Innovation and Systems (¶8 and ¶9). The Cloudflare Blog itself migrated in August under a "Customer Zero" approach (¶10), with stated load figures of millions of pageviews per week and spikes to 5,000 requests per second. The features that came out of that migration (KV object caching, Hyperdrive adapter, Workers Cache compatibility) are Cloudflare products, so the production evidence and the sales surface overlap. **Community and licensing.** MIT license (¶11), more than 175 contributors and more than 1,800 commits at time of writing (¶12), 25 translated languages (¶13), an intern-turned-second-maintainer (¶14), and a Discord with over 800 members (¶15). ¶12 also says the project is built so agents "can help the human developers, rather than being overwhelmed by them," with no mechanism described. **The registry design.** ¶19 argues that traditional registries bundle three roles: publisher account, authoritative package record, and discovery catalog. That makes one company the gatekeeper for identity and distribution. EmDash splits them (¶20). Publishers sign package and release records with an Atmosphere account and store them in their own account (¶22). The EmDash catalog is one index among possible others. It applies default content moderation to names, descriptions, links, and images, and moderation can hide material from the catalog without touching the release (¶21). Cloudflare hosts the default aggregator, and a labeler that uses Workers AI to moderate descriptions. It open-sources both, along with an Astro live content loader (¶23). **Verification.** ¶25 gives the checking sequence. Atproto repositories use signed Merkle Search Trees, so an inclusion proof ties the release record to a signed commit from the publisher's account. EmDash then checks checksum, package name, version, requested access, and required build provenance, and confirms the downloaded bundle matches the signed record. ¶24 says there is no central controller that can take over or remove plugins, which ¶21's catalog-level moderation qualifies: the catalog can hide a listing, the record survives elsewhere. **Runtime isolation.** ¶30 describes the WordPress model as plugins sharing one PHP process with the database, filesystem, and network, so a contact-form plugin "can technically read unpublished posts, modify another plugin, or send data anywhere." ¶31 and ¶32 describe the EmDash alternative and compare it to installing a mobile app: the site shows what a plugin wants before it runs. The ¶33 to ¶48 table pairs four example plugins with what each could do, what it might need, and what it cannot do. ¶49 says abilities are independent and enforced by the runtime. ¶50 says isolation works on Cloudflare (Dynamic Workers through Worker Loader) and on Node.js (a separate workerd process). **Platforms and EmDash Build.** ¶51 to ¶55 pitch EmDash as a content layer for hosting and site-builder companies running each customer site as a Worker in Workers for Platforms, with plugin marketplaces either curated or running against the full registry (¶54). ¶56 to ¶59 introduce EmDash Build, an alpha AI site builder: each project gets a Cloudflare Sandbox container, an agent built on the Agents SDK, and change tracking through Artifacts as git commits. **Uncertain or contested in this source.** - No paid-plugin support yet (¶26). Cloudflare says it aims to add it and is "watching" the Atproto Spaces Alpha. - The security comparison to WordPress (¶30) describes the default PHP execution model. The text doesn't mention WordPress.org's plugin review, and it offers no exploit statistics. - "Stable" and "secure" are not defined by any audit, threat model, or bug-bounty result in the captured text. The linked plugin sandbox documentation (see References) is the place to look. - The mobile-app comparison (¶32) describes a permission prompt model. The text doesn't say what wording or granularity the admin sees, or how users are protected against approving everything. ## 🗒️ Notes #### 📄 ¶0-¶2 The launch and the April Fools' doubt - The April 1 announcement of EmDash as the "spiritual successor to WordPress" drew conference chatter, and some doubted it was real (¶0, ¶1). - 1.0 is described as stable, free, open source, and built on Astro, aimed at production sites, agency "vibe-coding" platforms, and hosting companies (¶2). #### 📄 ¶3-¶4 What 1.0 combines - Three roles: developers build in Astro, editors use the admin, agents work through the API, CLI, or built-in MCP server (¶3). - The plugin registry is decentralized, and site owners install plugins from inside EmDash (¶4). #### 📄 ¶5-¶9 Stability commitments and the Avulux case - Prospective adopters said "let me know when it is 1.0" and wanted stability, security, upgrade safety, and a maintenance commitment (¶5). - Five months of work with contributors and production users targeted data safety, migrations, editorial workflows, localization, plugin security, performance, and admin, API, MCP, and media reliability (¶6, ¶7). - Avulux converted a custom microsite in under a day using EmDash Agent Skills (¶8). Its quoted director says WordPress had become slow and hard for the team to update (¶9). One customer quote, supplied by the vendor. #### 📄 ¶10 The Cloudflare Blog as Customer Zero - Migration in August. Stated load: millions of pageviews a week, spikes to 5,000 RPS of legitimate traffic, sporadic DDoS. - Features "spawned" by the migration: optional KV object caching, Hyperdrive database adapter, Workers Cache compatibility. #### 📄 ¶11-¶15 License and community - MIT license, justified by editor reliance and freedom from vendor lock-in and changing business priorities (¶11). - More than 175 contributors, more than 1,800 commits, 25 languages, Noah Pham (intern to second maintainer, 80+ changes), Discord with 800+ members (¶12 to ¶15). - Contribution paths named include translation, docs, testing, design, triage, and answering questions (¶15). #### 📄 ¶16-¶17 Ecosystem - Theme companies, plugin shops, agencies, and platforms build on EmDash (¶16). One named quote from Empress's founder on multisite (¶17). #### 📄 ¶18-¶24 Registry design and the decentralization argument - Publishers publish sandboxed plugins. Site owners discover, inspect, and install them (¶18). - Traditional registries combine account, package record, and catalog. Suspension, delisting, rule changes, or shutdown strand the publisher's identity and history (¶19). - EmDash separates plugin from catalog so other services can index the same publications and apply their own policies (¶20). - Default moderation covers names, descriptions, links, and images, and can hide material without rewriting a release or erasing the publication (¶21). - Built on AT Protocol. Publishers sign with an Atmosphere account, and records live in the publisher's account (¶22). - Cloudflare hosts default services and open-sources the aggregator, the Workers AI labeler, and the Astro loader (¶23). - Claim of no central controller and a preference for security "baked into code" over trust in an authority or code of conduct (¶24). #### 📄 ¶25-¶27 Verification chain and paid plugins - Signed Merkle Search Trees give an inclusion proof from release record to the publisher's signed commit. EmDash then checks checksum, name, version, requested access, and required build provenance, and matches the bundle to the signed record (¶25). - Free plugins only today. Paid plugins are an aim under the same decentralized model, and the Atproto Spaces Alpha is being watched (¶26). - Authors publish without asking EmDash's permission, and site owners see what a plugin may do before running it (¶27). #### 📄 ¶28-¶32 The plugin security problem and the sandbox answer - Plugins save rebuilding integrations and let experts share practice, and agents raise reuse value because a plugin captures generated, tested, maintained work (¶28, ¶29). - The concern: plugins are unwritten code beside valuable data. In WordPress they run in the same PHP process with access to the database, filesystem, and network, and trust is placed in the author and in future updates (¶30). - EmDash sandbox: isolated runtime, private storage only, no access to content, media, users, secrets, environment, filesystem, or network unless declared and approved (¶31). - Framed as installing a mobile app: capabilities shown before the plugin runs (¶32). #### 📄 ¶33-¶48 Capability table - Four examples (¶37 to ¶48): search indexing (needs content read and the search host; cannot edit articles or contact other hosts), image optimization (needs media read and manage; cannot read user content), publishing notifications (needs publish observation and email; cannot change published content), configurable webhooks (selected events and public destinations; cannot reach private networks or other plugins' storage). - Column headers are "could", "might need to", "still cannot" (¶34 to ¶36). The captured text flattens the table into one cell per paragraph. #### 📄 ¶49-¶50 Independence of abilities and platform support - Abilities are independent: media access doesn't expose users or unpublished content, and one allowed host doesn't open the network. The runtime enforces the boundary (¶49). - Cloudflare deployment uses a Dynamic Worker per plugin through Worker Loader. Node.js deployment starts workerd as a separate process with one isolated service per plugin. Manifests and capability-gated APIs match on both (¶50). #### 📄 ¶51-¶56 Hosting platforms and EmDash Build - Companies building site-creation products can run each customer's site as a Worker in Workers for Platforms, use the admin, the API and CLI, or an agent on the MCP server (¶51 to ¶53). Example: a bakery owner asking an agent to change opening hours (¶53). - Sandboxed plugins let a platform offer extensions across many customer sites. Marketplaces can expose the whole registry or a pre-approved set (¶54). - Cloudflare seeks hosting partners (¶55) and open-sources an alpha of EmDash Build (¶56). #### 📄 ¶57-¶59 EmDash Build mechanics - Problem stated: after a chat-driven first draft, one-line changes force you back to the prompt to "roll the dice" or burn credits (¶57). - EmDash Build produces an EmDash site with server-rendered Astro pages, a database, media storage, and an admin. The agent builds a content model from the brief and fills it through the MCP server (¶58). - Each project gets a Cloudflare Sandbox container. Artifacts tracks changes as git commits. Publishing moves content to a production site in the host's Workers for Platforms namespace (¶59). #### 📄 ¶60-¶64 Getting started - Playground site, CLI or dashboard install (the code block is not captured), and a plugin-authoring guide (¶60 to ¶63). - Discord invitation aimed at translators, triage, designers, and marketers as well as engineers (¶64). ## 📚 References The link list from the captured markup includes these anchors. The linked pages weren't opened for this analysis, so descriptions come from the anchor text and the sentence around it. - [Introduced EmDash on April 1](https://blog.cloudflare.com/emdash-wordpress/): the original announcement (¶0). - [Cloudflare Blog migration to EmDash](https://blog.cloudflare.com/cloudflare-blog-uses-emdash/): Customer Zero write-up (¶10). - [EmDash on GitHub](https://github.com/emdash-cms/emdash): source and MIT license (¶11). - [EmDash Agent Skills](https://github.com/emdash-cms/emdash/tree/main/skills): the skills Avulux used (¶8). - [Avulux](https://avulux.com/): the named adopter (¶8). - [KV object caching](https://docs.emdashcms.com/deployment/object-cache/), [Hyperdrive adapter](https://docs.emdashcms.com/deployment/database/#hyperdrive), [Workers Cache](https://docs.emdashcms.com/deployment/cloudflare/#workers-cache): the features credited to the migration (¶10). - [EmDash plugin registry](https://plugins.emdashcms.com/): the catalog (¶18). - [AT Protocol](https://atproto.com/) and [Atmosphere](https://atmosphereaccount.com/): the identity and record layer (¶22). - [The aggregator](https://github.com/emdash-cms/emdash/tree/main/apps/aggregator), [the labeler service](https://github.com/emdash-cms/emdash/tree/main/apps/labeler), [the Astro live content loader](https://github.com/emdash-cms/emdash/tree/main/packages/registry-loader): the open-sourced registry services (¶23). These are the primary sources for checking the moderation and verification claims. - [Atproto Spaces Alpha](https://atproto.com/blog/atproto-spaces-alpha): the paid-plugin watch item (¶26). - [Dynamic Worker](https://developers.cloudflare.com/dynamic-workers/?cf_page=emdash-cms-plugin-registry%2F), [workerd](https://github.com/cloudflare/workerd), [plugin sandbox documentation](https://docs.emdashcms.com/deployment/plugin-sandbox/): the isolation mechanism (¶50). The sandbox documentation is the primary source for the capability model. - [Workers for Platforms](https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/?cf_page=emdash-cms-plugin-registry%2F): the hosting-platform product (¶52). - [build.emdashcms.com](http://build.emdashcms.com) and [emdash-build code](https://github.com/emdash-cms/emdash-build): the EmDash Build alpha (¶56). - [Playground](https://try.emdashcms.com/) and [first plugin guide](https://docs.emdashcms.com/plugins/creating-plugins/your-first-plugin/) (¶60, ¶63). - [Discord](https://discord.gg/YY9vBaQRYt) (¶15, ¶64). - Ecosystem links in the list: [Lexington Themes](https://lexingtonthemes.com/templates/astro-emdash-templates), [Urumi](https://urumi.ai/otta-is-the-ecommerce-plugin-for-cloudflares-em-dash), [Empress](http://tryempress.dev). - Claims with no link in the captured markup: the 175 contributors and 1,800 commits figures (¶12), the 5,000 RPS and millions of pageviews figures (¶10), the "less than a day" Avulux migration (¶8, only the Agent Skills link is present), and the WordPress plugin execution description (¶30). ## 🗣️ Paraphrase Cloudflare says EmDash is real, released, and now stable enough to trust. Its evidence is a customer that moved a microsite in a day, its own blog running on it since August, and a contributor base of 175 people. The headline change is how plugins get trusted. A conventional registry is one company holding your account, your package, and the storefront. EmDash pulls those apart. Authors sign their releases on an AT Protocol account they own. The EmDash catalog is a convenience layer that can hide listings but can't rewrite or delete a release. Before installing, EmDash checks the signature chain, the checksum, the version, the permissions requested, and any required build provenance. The second change is what a plugin can do once installed. Cloudflare contrasts its model with WordPress, where a plugin shares the application's process and can reach the database, files, and network. In EmDash, each plugin runs isolated with private storage, and gets extra abilities only when it declares them and the administrator approves. The post compares this to installing a phone app. Cloudflare also uses the launch to promote hosting partnerships and an AI site builder that runs on its own products. Paid plugins aren't supported yet. ## 📰 Newsletter **A CMS launch with a plugin-security argument worth reading even if you never run EmDash.** Cloudflare shipped EmDash 1.0 on September 28, an MIT-licensed CMS built on Astro, and paired it with a plugin registry on AT Protocol. The part that matters for WordPress people is how it handles plugin trust. Each plugin runs in an isolated runtime with private storage, declares the abilities it wants, and gets them only after the site administrator approves. The registry keeps publisher identity and signed release records with the publisher, and EmDash checks checksum, version, requested access, and build provenance before installing. Read it with two hats on. The design ideas (capability declarations shown before install, publisher-signed releases, a catalog that can hide a listing but not erase a release) are concrete and map to open questions in the WordPress.org plugin directory. The comparison to WordPress is Cloudflare's, and Cloudflare sells the hosting products EmDash is tuned for. The post offers no exploit data behind its "safer" framing, and it says outright that paid plugins aren't supported yet. Links: [the announcement](https://blog.cloudflare.com/emdash-cms-plugin-registry/), [plugin sandbox docs](https://docs.emdashcms.com/deployment/plugin-sandbox/), [AT Protocol](https://atproto.com/). ## ✅ Action items #### DevRel - Developer advocacy: write a comparison talk on capability-declared plugins versus in-process plugins. Use the ¶33 to ¶48 table as the outline and test each row against a real WordPress plugin. - Education: run an office-hours session on reading a plugin's requested permissions before installing, using the mobile-app analogy from ¶32. - Developer experience: prototype what a capability manifest for a WordPress plugin would look like, and publish the sketch as a discussion starter. No existing WordPress manifest format is claimed here. - Developer marketing: don't repeat "safer than WordPress plugins" from this source without a citation. It is a vendor comparison in ¶30 with no data. - Community management: label this link in shared channels as vendor content so the WordPress comparison isn't passed around as an audit result. - Internal/external/cross-project: ask the EmDash maintainers for the threat model behind the sandbox and any third-party review of it. #### OSPO - Policy and governance: decide whether a signed, publisher-owned release record is a requirement worth writing into any plugin-distribution policy you own. - License compliance: the code is MIT (¶11). Check the license of each registry service (aggregator, labeler, loader) in its own repo before reuse. - Security management: study the ¶25 verification chain (inclusion proof, checksum, name, version, requested access, provenance) as a checklist for plugin intake. Add the questions of who can approve capabilities and how updates re-trigger approval. - Software inventory: a plugin that declares abilities gives you an inventory field for free. Record what a machine-readable capability list would add to an SBOM entry for a plugin. - Developer support: draft guidance for reviewers on what "requested access" should look like for common plugin types, mirroring the four examples in the table. - Community engagement: track whether other catalogs index the EmDash registry, since ¶20 and ¶23 invite it. - Strategic alignment: add a KPI for the share of plugins whose behavior matches their declared purpose, if any such declaration exists. #### Community - Maintainers: a maintainer of a large plugin can list the abilities the plugin uses today. That list is the manifest it would need under a capability model. - Contributors: a first-issue candidate is auditing one small plugin's real filesystem, network, and database calls against its readme. - Sponsors: paid plugins are future work (¶26). A sponsor interested in funding trusted commercial distribution can track that item. - Ecosystem: run a cross-project drill on a compromised-plugin scenario and compare what each model would contain. #### WordPress - Core: no direct action. This source describes a different CMS. Nearest relevance: whether core could expose any capability boundary between plugins. - Core Performance: none. The post gives no per-plugin isolation overhead figure, so the cost of process or worker separation is unmeasured in this source. - Core AI: ¶12 and ¶29 describe agents as contributors and plugin consumers. Note that agent-installed plugins raise the value of pre-install permission review. - **Core Program Team:** flag this as a competitive reference for plugin-security discussions, and note the source is vendor-authored. - Mobile: none. - Playground: a Playground demo that shows a plugin's outbound requests and file reads would teach the ¶30 concern concretely. - Community: none. - Training: add a lesson comparing in-process trust to capability-gated trust, using ¶30 to ¶32 as the contrast. - Marketing: none. - Support: none. - Design: the admin approval screen is the security control in ¶31. A UX audit of comparable WordPress permission prompts (application passwords, for example) applies. The post shows no EmDash screen in the captured text. - Documentation: document what a WordPress plugin can access by default, in plain language, since ¶30 states it as fact and readers will look for the .org answer. - Photos: none. - TV: none. - Polyglots: ¶13 reports 25 translated languages. Compare with WordPress locale coverage if you need a benchmark. No further action from this source. - Accessibility: none from this source. The EmDash admin's accessibility isn't discussed in the captured text. - Meta: study ¶19 to ¶25 for the WordPress.org directory: account, package record, and catalog are bundled there too (per the ¶19 description of traditional registries). Ask what signed, publisher-held records would change for delisting and account recovery. - CLI: none. - Hosting: note the Workers for Platforms pitch (¶52 to ¶54). Hosts compare it to their own multisite and managed-plugin offerings. - Tide: the ¶25 checks (checksum, version, requested access, provenance) overlap with what an automated plugin scanner reports. Compare the checks to Tide's. - Openverse: none. - Themes: none. The post doesn't describe theme isolation. - Plugins: primary fit. Review team and security liaisons can use the table in ¶33 to ¶48 and the ¶25 chain as a comparison for the current review model. #### The WPOCC - Programs: none directly. A fellowship could fund an independent review of capability-gated plugin models. - Projects: a documentation sprint on what plugins can access today. - Funding experiments: ¶26 says paid plugins should let publishers "make money." A WPOCC experiment could fund plugin security work that a decentralized registry would otherwise leave to marketplaces. ### FAIR - Technical independence: ¶19 to ¶22 describe a publisher-held signing identity and records that any catalog can index. That is the closest match to FAIR's provenance and signature goals in this source. Compare the two designs directly. - Policies and covenants: ¶21 separates hiding a listing from deleting a release. That's a usable policy distinction for FAIR moderation rules. - Productized governance artifacts: a scorecard row for "who holds the authoritative package record" and "can another catalog index it" comes straight from ¶19 and ¶20. ## 🧪 Hypotheses 1. A capability-gated plugin runtime blocks the plugin-originated data exfiltration and cross-plugin tampering paths that ¶30 describes, when the plugin has not been granted the network or content ability. 2. Site administrators approve requested capabilities without reading them at a high rate, so the mobile-app-style prompt in ¶32 reduces risk less than the isolation itself does. 3. Publisher-held signed release records (¶22, ¶25) reduce the time to detect a tampered package download compared with a catalog-held copy, because the client verifies against the publisher's commit. 4. Isolated plugin execution adds measurable latency per plugin call versus in-process execution, with a larger penalty on Node.js (a separate workerd process, ¶50) than on Cloudflare. 5. The plugin-security gap between EmDash and WordPress narrows when WordPress sites apply a mature review and hardening stack, so ¶30's contrast overstates the practical difference for well-maintained sites. 6. Catalog-level moderation with a decentralized record store (¶21) produces a hard-to-resolve conflict when the same malicious release is hidden by one catalog and indexed by another. ## 📊 Methodology - **H1.** Build four plugins matching the ¶37 to ¶48 rows. Run each in the sandbox and in a normal in-process runtime. Attempt every "still cannot" action (read user content, edit articles, reach private networks, read another plugin's storage) and record which succeed. Publish the harness. - **H2.** A usability study with 30 site administrators. Show approval prompts for plugins requesting escalating permissions, including one clearly excessive request. Measure approval rate, time on screen, and recall of what was granted. - **H3.** Simulate a compromised catalog that swaps a release bundle. Measure whether EmDash's ¶25 checks reject the swap, and how quickly a client using catalog-held checksums would detect it. - **H4.** Microbenchmark a hook-heavy plugin at 1, 10, and 50 calls per request in three configurations (Cloudflare Dynamic Worker, Node with workerd, in-process baseline). Report p50 and p95 latency. - **H5.** Compare a matched sample of plugins by known-vulnerability history and required capability set, and estimate how many past WordPress plugin vulnerabilities would have been contained by a declared-capability model. Use public vulnerability databases, not vendor claims. - **H6.** A tabletop exercise with two catalogs and one disputed release, run by a governance group. Record the decisions and the record-level consequences. - **Controls throughout.** Fix the plugin code across arms and pre-register what counts as contained. ## ❓ Questions - What is the exact set of capabilities EmDash defines, and how granular is the network ability (host, port, method)? - When a plugin update adds a capability, does the site administrator re-approve, and does the update block until they do? - How does the labeler that uses Workers AI (¶23) decide what to hide, and what is its false-positive path for publishers? - What happens to installed plugins if a catalog hides a listing (¶21)? Does the site keep running, and does it still receive updates? - How is "required build provenance" (¶25) defined and enforced, and which attestation formats does it accept? - What is the isolation overhead per plugin call on Cloudflare and on Node.js? - Who audited the sandbox, and is any third-party review public? - How would the registry handle publisher key loss or account compromise, given records live in the publisher's own account (¶22)? ## 🔮 Future research - **Capability models for CMS plugins.** The post shows one design. There's no comparative study of capability granularity across CMS ecosystems, and the ¶33 table would seed one. - **Approval-prompt effectiveness.** The mobile-app analogy (¶32) invites evidence from app-permission research, but that work isn't cited in the post. - **Decentralized moderation.** ¶21 and ¶24 hold two ideas together: no central controller, and default catalog moderation. Research is open on how multiple catalogs with differing policies affect users. - **Paid distribution.** ¶26 defers commercial plugins. How signed, decentralized records interact with licensing and payment is unresolved in this source. - **Agent-installed plugins.** ¶29 says agents can install proven solutions. Threat modeling for an agent that approves its own capability requests is absent from the text. ## 💡 Implications - **Practice.** A plugin author can be asked to declare access up front. Reviewers and site owners then compare purpose and request, which is cheaper than reading code. The ¶33 table is a template for that comparison. - **Policy.** Splitting the account, the record, and the catalog (¶19, ¶20) turns delisting from a total loss into a catalog-level decision. Any directory operator can ask what it would look like to publish its own policies against portable records. - **Security.** Runtime-enforced boundaries (¶49) shift trust from the author's intent to the runtime. That moves risk to the runtime's own correctness, which ¶24's "baked into code" phrasing puts at the center. The post gives no audit evidence. - **Education.** The four-row table (could, might need to, cannot) is a compact way to teach least privilege to plugin developers. - **Funding.** ¶26 ties the security model to a future paid marketplace and says anyone should be able to run one. Funding for independent registries and moderators is implied and not addressed. - **Vendor literacy.** The post pairs a genuine design contribution with product placement for Workers, Dynamic Workers, Workers AI, Sandbox, Artifacts, and Workers for Platforms. Readers should separate the two. ## 🧠 Learning styles assessment - **Reading level estimate.** Flesch-Kincaid Grade Level of roughly grade 12 on the prose paragraphs, Flesch Reading Ease near 40 (long sentences, product and protocol terms such as Merkle Search Trees, Dynamic Worker, Worker Loader, workerd). Estimate from sampling the text, not a computed score. #### 👀 Visual learners - Present: the captured text includes a three-column capability table (¶33 to ¶48) and references a code block and a dashboard screenshot (¶61, ¶62). None of those images or code lines are captured, so the assessment can't confirm them. - Improve: add an architecture diagram of publisher account, signed record, aggregator, and installing site. The account, package, and catalog split is the central idea and needs one. #### 🔊 Aural learners - Present: no audio version is referenced in the captured text. - Improve: a 3-minute audio summary of the registry split and the sandbox rules. #### 🗣️ Verbal learners - Present: the mobile-app analogy (¶32) and the traditional-registry three-role definition (¶19) explain the ideas in plain words. - Improve: define Merkle Search Tree, inclusion proof, and Dynamic Worker on first use. ¶25 assumes the reader knows them. #### 🧩 Kinesthetic learners - Present: links to a playground site, an install path, and a first-plugin guide (¶60 to ¶63). - Improve: a copy-paste sample plugin manifest in the post itself, so readers can try a capability declaration without leaving the page. #### 🧠 Logical learners - Present: ¶25 lists the verification checks in order, and the ¶33 table pairs abilities with limits. - Improve: state the threat model. The reader gets mechanisms without knowing which attackers each one stops. #### 🧑‍🤝‍🧑 Social learners - Present: a Discord invitation with 800+ members (¶15, ¶64) and contributor thanks (¶13, ¶14). - Improve: a public discussion thread for the security model where researchers can challenge it. #### 🧘‍♀️ Solitary learners - Present: linked docs and a plugin guide allow self-paced study. - Improve: a short self-check, for example "Which of your installed plugins need network access?" #### 🌿 Naturalistic learners - Present: nothing explicit. - Improve: none needed for this topic. A note on the compute cost of one isolated worker per plugin would touch the environmental angle and isn't in the text. ## 📊 Accessibility assessment #### Screen reader semantics - Present: the captured text keeps paragraph order and shows link text that carries meaning (for example "plugin sandbox documentation"). Heading elements aren't visible in the capture, so heading structure is unknown. - Improve: the capability table is flattened into one paragraph per cell in the capture (¶33 to ¶48). Whether it is a real HTML table with headers can't be confirmed. WCAG 1.3.1 (Info and Relationships) applies if it isn't. Two links have bare-ish text ("Discord" and "explore the code"), which is borderline for 2.4.4 (Link Purpose in Context) and passes only with the surrounding sentence. #### Keyboard navigation - Present: not assessable from captured text. - Improve: verify that the embedded install snippet and any tabs are keyboard operable (2.1.1). The capture doesn't show them. #### Contrast and readability - Present: unknowable from text. I can't see the page styling. - Improve: check 1.4.3 on code blocks and table cells, which is where dark themes usually fail. #### Text resizing and reflow - Present: the capture shows no fixed-size text elements, but that says nothing about layout. - Improve: a wide three-column table needs to reflow at 320 CSS pixels (1.4.10). Test it. #### Media and captions - No media referenced in the captured text. ¶62 refers to "the Cloudflare dashboard below" and the capture shows no image or alt text for it, so whether a screenshot is present and described is unknown (1.1.1). #### Forms and interactions - Present: the post links to a demo and playground. No form appears in the captured text. - Improve: the EmDash Build demo and the admin approval prompt in ¶31 are the interactions that matter. Their accessibility isn't described in the source and is not assessable here. #### Standards reference - Candidate gaps against WCAG 2.2 AA, each unverified: **1.3.1** (table semantics for ¶33 to ¶48), **1.1.1** (alt text for the dashboard image referenced in ¶62 and any code-as-image), **2.4.4** (short link text such as "Discord"), **1.4.10** (table reflow). These need a check against the rendered page. ## 🌍 DEIB assessment #### Cultural breadth - Present: 25 languages (¶13), with "from Arabic to Ukrainian" as the range. Contributors and adopters named span several countries, though locations aren't stated. - Improve: the examples (bakery, contact-form plugin) are Western small-business scenarios. Add a multilingual or right-to-left plugin example, since translation is a claimed strength. #### Inclusive language - Present: the post uses plain, second-person language and invites non-coders (¶15, ¶64). - Improve: "vibe-coding platform" and "spiritual successor" are jargon and metaphor. "Best friend" in ¶8 anthropomorphizes agents. Low severity. #### Neurodiversity support - Present: short paragraphs, a table for the core comparison, and a consistent announcement-to-mechanism-to-getting-started order. - Improve: the middle of the article crosses from registry to sandbox to hosting to an AI builder. Clear subheads would reduce the load. The capture doesn't show which headings exist. #### Representation - Present: contributors are credited by handle (¶13), Noah Pham by name (¶14), and two customers by name and role (¶9, ¶17). - Improve: ¶13 lists four GitHub handles without names. No independent security voice appears anywhere in the post. #### Psychological safety - Present: the post welcomes non-code contributions and newcomers explicitly (¶15, ¶64). - Improve: the comparison to WordPress (¶9, ¶30) casts one community's ecosystem as a maintenance burden. A note acknowledging the WordPress security team's work would lower the defensiveness readers from that community may feel. ## ✅ Logical validity Source type: vendor announcement and advocacy. Cloudflare authors and maintains the project and sells the platform products the post recommends. The persuasive frame (WordPress problem, EmDash answer) is the structure of the piece. #### Strong reasoning - **Analytical decomposition, ¶19.** Splitting a registry into account, package record, and catalog explains precisely how a suspension or shutdown strands a publisher. The premise is checkable, and the proposed fix in ¶20 follows from it. - **Mechanism specificity, ¶25.** The post lists what is verified (inclusion proof, checksum, name, version, requested access, provenance). A claim with named steps can be tested against the open-source code. - **Capability independence, ¶49.** The table in ¶33 to ¶48 gives concrete could, need, and cannot cases, and the closing statement that the runtime enforces boundaries is a testable claim. - **Honest scoping, ¶26.** The post says paid plugins aren't supported and names the dependency it's waiting on, which limits overclaiming about marketplaces. #### Fallacies - **Unsupported comparison, ¶30.** "With WordPress, plugins run inside the same PHP process as the rest of the application" is an accurate description of the default PHP model as a mechanism. It becomes a weak argument when it stands in for a security comparison, since the post shows no exploit rates, review process comparison, or incident data. Fix: state the model difference and cite vulnerability data for both ecosystems. - **Straw target, ¶30 and ¶9.** "Site owners must trust that it will not" ignores the review, monitoring, and hardening controls that surround WordPress plugins. The quote from Avulux (¶9) adds a maintenance-burden anecdote. Fix: name the controls being compared against. - **Anecdote as evidence, ¶8 and ¶9.** One customer, supplied by the vendor, converting a microsite in under a day supports "possible," not "typical." Fix: report median migration effort across customers. - **False dilemma, ¶24.** "rather than trusting any central authority or code of conduct" sets code against governance, while ¶21 and ¶23 describe a catalog with moderation and a hosted default service. The post relies on both. Fix: state which decisions are protocol-enforced and which remain operator policy. - **Undisclosed interest, throughout.** The commercial stake in Workers, Workers for Platforms, Dynamic Workers, Workers AI, Sandbox, and Artifacts (¶10, ¶23, ¶50, ¶52, ¶59) is visible in the text, but the post doesn't frame the security claims as coming from a party that sells the runtime. Fix: a one-line disclosure near the security section. - **Undefined success terms, ¶5 and ¶6.** "stable" and "secure" carry the announcement but have no stated criteria. Fix: publish the release criteria and any external review. #### Tone of voice - Confident, promotional, and celebratory. Second person and first-person plural throughout ("we are releasing," "we believe"). Enthusiasm peaks in the closing product and partner sections (¶51 to ¶56), where the register shifts from engineering explanation to sales invitation ("reinventing with EmDash," ¶55). The middle of the article (¶19 to ¶25 and ¶30 to ¶50) is the most technical and the most carefully worded. ## 🛡️ DARVO analysis Not applicable to this source. DARVO describes a response to accusation or criticism, and this post is a product announcement with no accuser or dispute. The nearest match is ¶1 and ¶5, where the post names doubts about whether EmDash was a joke and whether it was mature enough, and answers both with facts rather than deflection. **Deny:** the "April Fools" doubt is denied directly (¶2), and no accusation is minimized. **Attack:** no critic or competitor is attacked, though WordPress's plugin model is criticized as a design (¶30). **Reverse victim/offender:** no such move appears. ## 🎯 Conclusion EmDash 1.0's most useful contribution is a design for plugin trust that separates three things traditional registries bundle: publisher identity, the authoritative release record, and the catalog. It couples that with a runtime where a plugin's abilities are declared, approved by an administrator, and enforced outside the plugin's control. The verification chain in ¶25 and the capability table in ¶33 to ¶48 are specific enough to test. The comparative claims are weaker. The WordPress contrast in ¶30 describes a default execution model, not measured outcomes. "Stable" and "secure" have no published criteria in the captured text. Cloudflare authors the post and sells most of the infrastructure it names. **Next steps for readers:** read the [plugin sandbox documentation](https://docs.emdashcms.com/deployment/plugin-sandbox/) and the registry services' source for the real capability list and threat model. Compare the ¶25 checks against your own plugin intake process. If you run a plugin directory, list what would break if one company suspended your publishers' accounts tomorrow. ## 🔄 Refactor Appendix — EmDash 1.0: the stable CMS with a secure plugin registry > Density: 2–5 Literature atoms (H1 pad), 0–3 Permanent candidates (H4 pad). > Emitted: 4 Literature, 2 Permanent. Resonance filter applied: the community-size and > EmDash Build claims were dropped as promotional or off-topic for the security thread. > > Konik claim-header rules: present tense, declarative, ≤10 words, searchable, unique. > > Atomicity: one declarative sentence per atom. "and"/"also" → split. > > Tag pool: #bmf · #addendum · #xref · #articleseed · #storystem · #share · #aphorisms ### 📚 Literature Split Pad #### [H1] Sandboxed plugins gain abilities only through admin approval > [!quote] [¶31] > It gains additional abilities only when they are declared by the plugin and approved by the site administrator. **Context & use**: - ¶31, the core statement of the EmDash sandbox model, after the ¶30 description of WordPress in-process plugins. - The approval step is the human control. The post shows no prompt design, so the effect on real approvals is unmeasured. **Tags**: #xref #articleseed <!-- atomicity: 1 idea ✓ --> #### [H2] The runtime enforces plugin boundaries, not plugin authors > [!quote] [¶49] > These boundaries are enforced by the runtime, not left to the plugin author’s good intentions. **Context & use**: - ¶49, after the ¶33 to ¶48 table of could, need, and cannot cases. - This moves the trust question from author intent to runtime correctness. Any evaluation has to test the runtime, and the post cites no audit. **Tags**: #xref <!-- atomicity: 1 idea ✓ --> #### [H3] Decentralized publishing still verifies every release > [!quote] [¶25] > Decentralized publishing does not mean accepting unverified code. **Context & use**: - ¶25, opening the list of checks: inclusion proof, checksum, name, version, requested access, build provenance. - Useful as a checklist for any plugin intake process, independent of atproto. **Tags**: #xref #share <!-- atomicity: 1 idea ✓ --> #### [H4] One company holding identity and distribution is gatekeeping > [!quote] [¶19] > That is convenient, but it also makes one company the gatekeeper for both identity and distribution. **Context & use**: - ¶19, the diagnosis of traditional registries that the whole registry design answers. - Apply as a question to the WordPress.org directory: which of account, package record, and catalog does the operator hold, and what happens to a publisher if any is lost? **Tags**: #xref #articleseed <!-- atomicity: 1 idea ✓ --> ### 🧠 Atomic Split Pad #### [P1] Declare, approve, enforce **Claim** (one sentence, Courtney's voice): A plugin is safest to install when it declares the access it needs, an administrator approves that access, and the runtime enforces the result. **Evidence pointer**: [[#H1]] · [[#H2]] **Scope & conditions**: Holds when the runtime is correct, approvals are informed, and updates that add capabilities trigger re-approval. Breaks when administrators approve every prompt by habit, when the declared list is too coarse to mean anything, or when the runtime has an escape bug. The source doesn't state how updates are handled. **Links**: - [[Plugin security review]] — because extends - [[Least privilege]] — because applies-in CMS plugins - [[WordPress plugin directory review]] — because contrasts on where the control sits, at review time versus at runtime <!-- atomicity: 1 idea ✓ --> #### [P2] Separate the record from the catalog **Claim** (one sentence, Courtney's voice): A plugin registry stays trustworthy for publishers when the signed release record lives with the publisher and the catalog only indexes it. **Evidence pointer**: [[#H3]] · [[#H4]] **Scope & conditions**: Applies where publishers can hold and back up a signing identity. Breaks when a publisher loses a key, when two catalogs disagree on moderation, or when users rely on one catalog by default. The source describes a hosted default catalog run by the same company that builds the CMS. **Links**: - [[Supply chain provenance]] — because evidence-for - [[FAIR package manager]] — because extends - [[Centralized directory governance]] — because contrasts on who holds the authoritative record <!-- atomicity: 1 idea ✓ --> ### ✏️ Fleeting Queue - [F1] Read the plugin sandbox docs and list the real capability names and granularity: https://docs.emdashcms.com/deployment/plugin-sandbox/ #fleeting #inbox - [F2] Open question: does a capability-adding plugin update require fresh admin approval? ¶31 does not say #fleeting #inbox - [F3] Compare the ¶25 verification chain to the FAIR package manager checks and note gaps #fleeting #inbox - [F4] Article seed: "What a WordPress plugin manifest would need to declare" using the ¶33 to ¶48 table as the starting point #fleeting #inbox #articleseed - [F5] Check the labeler source to see how the Workers AI moderation decides what to hide (¶23): https://github.com/emdash-cms/emdash/tree/main/apps/labeler #fleeting #inbox ### → Things 3 (max 2 actions) - [ ] Read the EmDash plugin sandbox docs and extract the capability list, plugin security research, 30 min #things - [ ] Draft a side-by-side of the EmDash ¶25 verification chain versus current WordPress.org plugin intake checks, WordPress plugin security #things <!-- deep-read:sections end --> 📄 **Full text:** [[Full Document Contents/Articles/EmDash 1.0 The Stable CMS With a Secure Plugin Registry.md|EmDash 1.0: The Stable CMS With a Secure Plugin Registry by Cloudflare]] ## Highlights - Traditional plugin registries usually combine three roles: they provide the publisher’s account, hold the authoritative package record, and operate the catalog where users discover it. That is convenient, but it also makes one company the gatekeeper for both identity and distribution. If an account is suspended, a listing is removed, the rules change, or the service shuts down, publishers cannot take the same identity and release history somewhere else. ([View Highlight](https://read.readwise.io/read/01m3psd0px9jehvz6c9xt1v7x1)) - Note: [H4] One company holding identity and distribution is gatekeeping - Tags: atom/literature/h3 - Decentralized publishing does not mean accepting unverified code. Atproto repositories use signed Merkle Search Trees, so an inclusion proof connects the exact release record to a signed commit from the publisher’s account. EmDash can therefore verify the record independently instead of trusting the catalog’s copy. It then checks the plugin’s checksum, package name, version, requested access, and any required build provenance, and confirms that the downloaded bundle matches the signed record. ([View Highlight](https://read.readwise.io/read/01m3pscxxqga0vaa0sxvx4nt37)) - Note: [H3] Decentralized publishing still verifies every release - Tags: atom/literature/h3 - Sandboxed EmDash plugins use a different model. Each plugin runs in an isolated runtime with access to its own private storage, but not to the site’s content, media, users, secrets, environment, filesystem, or network. It gains additional abilities only when they are declared by the plugin and approved by the site administrator. ([View Highlight](https://read.readwise.io/read/01m3pscrzwckjrkay20nn69j89)) - Note: [H1] Sandboxed plugins gain abilities only through admin approval - Tags: atom/literature/h1 - The important part is that these abilities are independent. Giving a plugin access to media does not also expose users or unpublished content. Allowing it to contact one service does not open the rest of the network. These boundaries are enforced by the runtime, not left to the plugin author’s good intentions. ([View Highlight](https://read.readwise.io/read/01m3pscvh6ske5nk59d3gy88dz)) - Note: [H2] The runtime enforces plugin boundaries, not plugin authors - Tags: atom/literature/h2