DEV Community

Cover image for ‎Let clients edit. Not break. — building a permission-first CMS
emmi-dev12
emmi-dev12

Posted on

‎Let clients edit. Not break. — building a permission-first CMS

The problem every CMS has

Every CMS makes the same bet: hand the client the whole dashboard and hope they don't move a section, pick a neon-green heading, or delete the layout on the way out.

I got tired of taking that bet. So I built Castor — a CMS where you decide exactly what each client can change, and the system enforces it.

The one-liner: Let clients edit. Not break.

They change the words and the photos in the browser. They can't move a section, choose a colour that isn't yours, or touch the code.

Free, open source (AGPL-3.0), self-hosted. Live editor demo: https://castorcms.vercel.app

Most CMSes are binary. This one isn't.

In most tools a field is either editable or it isn't — and "editable" usually means the client gets everything.

Castor is per-capability. Each of these is an independent switch, with its own allowed range:

  • text
  • images
  • links
  • text colour
  • section colours
  • spacing

Any combination is valid. Set it per site, and a single page can override the site's defaults. You're not picking a tier — you're drawing a line exactly where you want it.

The client may edit The client may never touch
The words, the photos The layout
Links and buttons The structure
Colours you allow Anything off-brand
Spacing you allow The code

The part I'm actually proud of: the Guardian

The permission switches are the UI. The enforcement is a separate, deterministic (no AI) policy engine I call the Guardian.

Every edit passes through it before it touches the draft. It validates against the per-capability permissions server-side — so even if the editor UI is wrong, or tampered with in the browser, an out-of-bounds edit still doesn't save.

The rule I held myself to: never trust the client UI alone to prevent an out-of-bounds edit. The line lives on the server.

Draft → Publish → Rollback

Nothing a client does is public until they explicitly publish.

  • Edits land in a private draft.
  • Publishing snapshots the whole site.
  • Rollback moves the live pointer to any past version — one click.

The client can experiment freely; the live site stays exactly as it was until someone presses Publish.

Already have a site? Import it.

Drag a ZIP of HTML/CSS/JS onto the dashboard and it becomes editable. Imported pages render in a sandboxed iframe, so their own JavaScript still runs — but can't reach cookies or another client's site.

How it fits together

YOU (local)                    MongoDB Atlas         YOUR CLIENT (any browser)
  Admin dashboard  ─build/import─▶ shared database ◀─edit─  /edit/<slug>
  - set permissions per site                              • inline edit, in the page
  - master editor, full control                           • Draft → Publish
       │                                                  • can't break the layout
       └────────────── public site: your-app/<slug> ──────────────┘
Enter fullscreen mode Exit fullscreen mode

One Next.js app, two modes. Site-building, importing, and structural editing run only locally; the deployed instance serves just the password-gated editor and the public sites. Both share one MongoDB Atlas database, so a site you build on your machine is instantly editable at its hosted link.

Content model: Site → Pages → Sections → Slots. A section is a typed block (hero, text, features, testimonials, faq, gallery, form, cta, footer, or an imported page); a slot is one editable value.

Stack

Next.js 16 (App Router) · TypeScript · Tailwind · MongoDB Atlas · deployed on Vercel. The whole thing runs on free tiers.

Why AGPL, not "source-available"

Because the whole pitch is trust.

Use it, modify it, run it commercially for as many clients as you like — free. The one condition: anything you build on it, including a version you host as a service, stays open under the same licence. You can't take Castor closed-source.

That's deliberate positioning, not just a licence checkbox: it competes with hosted page-builders on cost, and with closed source-available tools on trust.

What it doesn't do (yet)

It's early and does one thing on purpose — guarded content editing for content sites. So, honestly:

  • Content sites, not apps. It renders content from a database; it doesn't run your framework. Build your React/Next project first, then import the output.
  • Imported ZIP sites are frozen — every word is editable, but they won't restructure or pick up renderer improvements.
  • Images are referenced by URL — no built-in upload/host step yet.
  • One owner — a single admin password, no team roles yet.
  • Undo/redo covers content, not structural changes.

Try it

I'd love feedback on the permission model specifically. If you build sites for clients: where would you want to draw the line — and what's the first thing you'd try to break?

Top comments (0)