EmDash Security Settings: What’s Missing & How to Compensate

EmDash CMS offers a modern architecture but ships with critical security gaps. Here's what's missing and how to compensate.

By Central
EmDash security settings page shows 'Not available yet' for key controls, leaving users to patch gaps manually.
Highlights
  • EmDash has no built-in spending cap, risking high costs from DDoS attacks on serverless billing.
  • Plugin sandboxing only works on Cloudflare's paid plan; self-hosted setups lose all isolation.
  • Passkey authentication fails on localhost and cannot be shared across team members easily.

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 “Not available yet” for items like self-signup domains, API token management, and user role granularity. The core security pitch—sandboxed plugins via dynamic workers—works only on Cloudflare’s paid plan. Self-host the CMS on a Node.js server, and that isolation disappears entirely. If you’re evaluating EmDash for production, you need to know what’s absent and how to patch the gaps yourself.

The Missing Security Controls in EmDash

No Spending Cap for Serverless Billing

EmDash runs on Cloudflare Workers, 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 per second each can rack up 26 billable requests in a month—potentially costing thousands. Cloudflare’s 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.

The most urgent missing feature is a spending cap. The most dangerous is the self-hosted plugin sandbox absence.

Plugin Sandbox Only on Cloudflare Paid Plan

The headline feature—plugins running in isolated V8 isolates—requires Cloudflare’s paid Workers plan. On the free tier, plugins run “in-process” 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’re not paying $5/month, the security model collapses.

Passkey Authentication but No Fallback for Localhost

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 “Page Not Found” error when the magic link fallback didn’t work on Linux. Passkeys also cannot be shared across team members easily—no role-based delegation for multi-user staging environments.

No IP-Based Access Controls or Two-Factor Authentication

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.

No Granular User Roles Beyond the Default

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’re stuck with the four defaults—no way to give a contributor read-only access to media or restrict an editor from publishing.

How to Compensate for EmDash’s Security Gaps

Use Cloudflare’s WAF and Rate Limiting

Since EmDash runs on Cloudflare infrastructure, you can layer Cloudflare’s own security products on top. Set up a WAF rule to block requests from countries you don’t serve. Configure rate limiting per URL pattern—for example, limit /admin/*codecodecode to 10 requests per minute per IP. This won’t stop a distributed attack, but it will reduce the blast radius. Enable Bot Management (paid) to filter out automated threats.

Implement a Spending Alert via Cloudflare’s API

Cloudflare does not 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’s 10 million requests is generous—a typical blog with 100,000 visits per month uses about 3% of that. But if you’re running custom plugins or heavy API calls, monitor closely.

Self-Host Only for Non-Critical Sites

If you need the plugin sandbox, you must pay for Cloudflare’s Workers paid plan. For development or low-risk personal projects, self-hosting on Node.js is acceptable—but acknowledge that plugins run without isolation. For production, accept the $5/month cost. It’s cheaper than a managed WordPress host (WP Engine starts at $20/month), but the lock-in is real.

Use Cloudflare Access for Admin Authentication

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’s IP range can reach the /admincodecodecode route. This compensates for the missing IP-based controls. Setup takes 15 minutes and costs nothing for the first 50 users.

Set Up External Monitoring for Failed Logins

EmDash doesn’t log failed authentication attempts in the UI, but you can capture them at the Cloudflare level. Use Cloudflare’s 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.

Plan for the Missing Ecosystem

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’s CAPTCHA alternative). For SEO, rely on the native SEO fields—title, meta description, canonical URL—that ship out of the box. Avoid adding custom code until the plugin sandbox is fully available.

Accept the Trade-Off: Less Complexity for Less Control

EmDash’s 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’s own security layer, external monitoring, and a strict policy of never running untrusted plugins on the free tier.

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—if you’re willing to build the missing pieces yourself.

Questions answered
  • What security controls are missing in EmDash?EmDash lacks a spending cap, plugin sandbox on free/self-hosted tiers, IP-based access controls, two-factor authentication, audit logs, and granular user roles.
  • How can you compensate for missing security in EmDash?Use Cloudflare's WAF for rate limiting, set up spending alerts via Cloudflare's dashboard, and implement external monitoring with Logpush for intrusion detection.
Share This Article