{"id":98092,"date":"2026-10-13T03:02:00","date_gmt":"2026-10-13T07:02:00","guid":{"rendered":"https:\/\/overcentral.com\/en\/?p=98092"},"modified":"2026-09-29T08:08:10","modified_gmt":"2026-09-29T12:08:10","slug":"emdash-security-settings-missing-compensate-98092","status":"publish","type":"post","link":"https:\/\/overcentral.com\/en\/emdash-security-settings-missing-compensate-98092\/","title":{"rendered":"EmDash Security Settings: What\u2019s Missing &amp; How to Compensate"},"content":{"rendered":"<p>EmDash CMS launched as a spiritual successor to WordPress, but its security settings are far from complete. In the playground version 0.1.0, the security settings page displays \u201cNot available yet\u201d for items like self-signup domains, API token management, and user role granularity. The core security pitch\u2014sandboxed plugins via dynamic workers\u2014works only on Cloudflare\u2019s paid plan. Self-host the CMS on a Node.js server, and that isolation disappears entirely. If you\u2019re evaluating EmDash for production, you need to know what\u2019s absent and how to patch the gaps yourself.<\/p>\n<h2>The Missing Security Controls in EmDash<\/h2>\n<h3>No Spending Cap for Serverless Billing<\/h3>\n<p>EmDash runs on <a href=\"https:\/\/workers.cloudflare.com\/\" target=\"_blank\" rel=\"noopener noreferrer\" data-iacss-external=\"1\">Cloudflare Workers<\/a>, D1 database, R2 storage, and KV. Each page view can hit four separate billing meters simultaneously. The paid plan starts at $5\/month with 10 million requests, but after that you pay $0.30 per additional million requests plus CPU time. There is no built-in spending cap. A DDoS attack of 10,000 IPs making one request <a href=\"https:\/\/overcentral.com\/en\/meta-launches-zgateway-proxy-handles-1-billion-ops-per-second\/\" title=\"Meta Launches ZGateway Proxy, Handles 1 Billion Ops Per Second\" data-iacss-internal=\"1\">per second<\/a> each can rack up 26 billable requests in a month\u2014potentially costing thousands. Cloudflare\u2019s own forum confirms: you cannot set a global request limit. Rate limiting via WAF rules is per-endpoint, not a global cap. A distributed bot attack from thousands of different IPs goes right through.<\/p>\n<h3>Plugin Sandbox Only on Cloudflare Paid Plan<\/h3>\n<p>The headline feature\u2014plugins running in isolated V8 isolates\u2014requires Cloudflare\u2019s paid Workers plan. On the free tier, plugins run \u201cin-process\u201d with no sandbox. Self-host on your own hardware, and there is no sandbox support at all. You lose the one architectural advantage over WordPress. If you\u2019re not paying $5\/month, the security model collapses.<\/p>\n<h3>Passkey Authentication but No Fallback for Localhost<\/h3>\n<p>EmDash uses passkey authentication by default, eliminating passwords and brute-force vectors. But the passkey is bound to the device and browser. For developers running multiple local instances (common in agencies), the passkey system fails. The demo video showed a reviewer getting a \u201cPage Not Found\u201d error when the magic link fallback didn\u2019t work on Linux. Passkeys also cannot be shared across team members easily\u2014no role-based delegation for multi-user staging environments.<\/p>\n<h3>No IP-Based Access Controls or Two-Factor Authentication<\/h3>\n<p>The security settings page in the playground is empty. There is no way to restrict admin access by IP address, no support for TOTP (time-based one-time passwords) beyond the passkey, and no audit log for failed login attempts. For any site with sensitive content, these are table-stakes features.<\/p>\n<h3>No Granular User Roles Beyond the Default<\/h3>\n<p>EmDash ships with administrator, editor, author, and contributor roles. You cannot create custom roles or assign granular permissions to specific content types. In WordPress, plugins like Members or User Role Editor solve this. In EmDash, you\u2019re stuck with the four defaults\u2014no way to give a contributor read-only access to media or restrict an editor from publishing.<\/p>\n<h2>How to Compensate for EmDash\u2019s Security Gaps<\/h2>\n<h3>Use Cloudflare\u2019s WAF and Rate Limiting<\/h3>\n<p>Since EmDash runs on Cloudflare infrastructure, you can layer Cloudflare\u2019s own security products on top. Set up a WAF rule to block requests from countries you don\u2019t serve. Configure rate limiting per URL pattern\u2014for example, limit <code>\/admin\/*<\/code>codecodecode to 10 requests per minute per IP. This won\u2019t stop a distributed attack, but it will reduce the blast radius. Enable Bot Management (paid) to filter out automated threats.<\/p>\n<h3>Implement a Spending Alert via Cloudflare\u2019s API<\/h3>\n<p>Cloudflare <a href=\"https:\/\/overcentral.com\/en\/rascal-does-not-dream-trailer-release-80139\/\" title=\"Rascal Does Not Dream Drops Trailer for Final Film\" data-iacss-internal=\"1\">does not<\/a> offer a native spending cap, but you can monitor usage via the API. Set up a cron job that checks your Workers usage daily and sends a Slack alert if it exceeds a threshold. For small sites, the free tier\u2019s 10 million requests is generous\u2014a typical blog with 100,000 visits per month uses about 3% of that. But if you\u2019re running custom plugins or heavy API calls, monitor closely.<\/p>\n<h3>Self-Host Only for Non-Critical Sites<\/h3>\n<p>If you need the plugin sandbox, you must pay for Cloudflare\u2019s Workers paid plan. For development or low-risk personal projects, self-hosting on Node.js is acceptable\u2014but acknowledge that plugins run without isolation. For production, accept the $5\/month cost. It\u2019s cheaper than a managed WordPress host (WP Engine starts at $20\/month), but the lock-in is real.<\/p>\n<h3>Use Cloudflare Access for Admin Authentication<\/h3>\n<p>Cloudflare Access (formerly Argo Tunnel) can sit in front of your EmDash admin panel. It provides SSO, device posture checks, and IP whitelisting. You can require that only users from your company\u2019s IP range can reach the <code>\/admin<\/code>codecodecode route. This compensates for the missing IP-based controls. Setup takes 15 minutes and costs nothing for the first 50 users.<\/p>\n<h3>Set Up External Monitoring for Failed Logins<\/h3>\n<p>EmDash doesn\u2019t log failed authentication attempts in the UI, but you can capture them at the Cloudflare level. Use Cloudflare\u2019s Logpush to send request logs to an external service (S3, Datadog, or your own server). Filter for HTTP 401 or 403 responses on the admin path. Set an alert if more than 10 failures occur in 5 minutes. This gives you a basic intrusion detection system.<\/p>\n<h3>Plan for the Missing Ecosystem<\/h3>\n<p>The biggest security risk is not in the CMS itself but in the absence of plugins. EmDash has zero third-party plugins. Every form, SEO tool, or caching system must be custom-built or ported. For now, use the built-in forms plugin, which includes Turnstile integration (Cloudflare\u2019s CAPTCHA alternative). For SEO, rely on the native SEO fields\u2014title, meta description, canonical URL\u2014that ship out of the box. Avoid adding custom code until the plugin sandbox is fully available.<\/p>\n<h3>Accept the Trade-Off: Less Complexity for Less Control<\/h3>\n<p>EmDash\u2019s missing security settings are a consequence of its early stage. The architecture is sound: sandboxed plugins, passkey auth, serverless scaling. But the gaps are real. The most urgent missing feature is a spending cap. The most dangerous is the self-hosted plugin sandbox absence. Until Cloudflare adds these, compensate with Cloudflare\u2019s own security layer, external monitoring, and a strict policy of never running untrusted plugins on the free tier.<\/p>\n<p>EmDash is not production-ready for security-sensitive sites. But for a greenfield project where you control the infrastructure and accept the vendor lock-in, it offers a cleaner foundation than WordPress\u2014if you\u2019re willing to build the missing pieces yourself.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>EmDash CMS launched as a spiritual successor to WordPress, but its security settings are far from complete. In the playground version 0.1.0, the security settings page displays \u201cNot available yet\u201d for items like self-signup domains, API token management, and user role granularity. The core security pitch\u2014sandboxed plugins via dynamic workers\u2014works only on Cloudflare\u2019s paid plan. [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":100395,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/cards.overcentral.com\/cards\/en\/98092.png","fifu_image_alt":"EmDash Security Settings: What\u2019s Missing &amp; How to Compensate","footnotes":""},"categories":[31],"tags":[],"class_list":["post-98092","post","type-post","status-publish","format-standard","has-post-thumbnail","category-technology"],"fifu_image_url":"https:\/\/cards.overcentral.com\/cards\/en\/98092.png","fifu_image_alt":"EmDash Security Settings: What\u2019s Missing &amp; How to Compensate","_links":{"self":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98092","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/comments?post=98092"}],"version-history":[{"count":1,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98092\/revisions"}],"predecessor-version":[{"id":100396,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98092\/revisions\/100396"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/media\/100395"}],"wp:attachment":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/media?parent=98092"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/categories?post=98092"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/tags?post=98092"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}