CairnControl manages your CairnServer through a scoped API token — never a root shell, never a key to the box. A small audited broker is the only privileged process, and it accepts four operations over a fixed table of directories — so a compromised panel writes a file nothing is running, not a file that is live.
Sites
3
Apps
2
Pools
1
Firewall awaiting confirmation
reverts in 01:13
The architecture
Most of what a hosting panel does is write a config file and reload a service. Cairn takes that seriously: the privileged surface is four operations over a fixed table of directories, not a root process that runs arbitrary commands.
cairn-broker
root
The only process that writes to /etc. Around 2,000 lines of Rust — small enough to review in one sitting. Authenticates callers with SO_PEERCRED, authorises them against a default-deny matrix.
Workers
unprivileged
cairn-web, cairn-mail, cairn-php and friends render config and ask the broker to commit it. They can write a file, but cannot make a service adopt it.
cairn-api
the HTTP surface
Holds the reload grant and no config knowledge. This is what CairnControl talks to — over the network, with a scoped bearer token.
POST /v1/sites takes a name, hostnames and a kind. Never a path, never file contents. Every path in a rendered file is composed by the worker from operator config.
This is not a validation rule that could be bypassed — there is no field for a path to arrive in.
# what the panel sends { "name": "classpay", "hostnames": ["classpay.co.uk"], "kind": "proxy" } # what it cannot send, in any code path # "path": "/etc/caddy/..." # "caddyfile": "root * /"
What you get
Provision Caddy virtual hosts — proxy, static or PHP. Cairn renders the file, commits it atomically and reloads. A broken change can never half-apply.
Containers as systemd Quadlet units. Name it, pin an image, and the unit is written and started for you.
Postfix domains managed as data, not as a config file you hand-edit at 2am.
A PHP-FPM pool per site, each running as its own user, so one site's code cannot read another's.
Whole-state rulesets that apply provisionally and roll back after two minutes unless you confirm — so locking yourself out is survivable.
Every action is gated by a scope. Issue a token that can list sites but not touch the firewall, and it genuinely cannot.
Security
Not "enterprise-grade security" — specific claims you can check in the source.
Workers render; the API reloads.
A compromised worker produces a bad file that nothing is running, rather than a bad file that is live.
Writes are attributable.
The broker uses setfsuid, so files land owned cairn:<service> mode 0640. Anything owned otherwise was written out of band — and cairn-monitor says so.
The panel is a client, not a component.
CairnControl holds no config knowledge and never runs on the managed box. Its blast radius is exactly the scopes on its token.
Atomic commits.
O_TMPFILE plus renameat2. A config file is either the old one or the new one, never a half-written one.
Pricing
Paid begins when you run other people's. Every limit is a number you can count — no seat maths, no feature matrix, no calling sales to find out what it costs.
Your own box, your own apps
Free
When you run other people's
Coming soon
We run it for you
Talk to us