Skip to content

Security Architecture — Whitepaper

Guiding principle: not "secure", but provably secure. We never claim a protection layer that isn't real, active and verifiable. Honesty over marketing.

This document describes how enconf isolates customers from one another on a shared server, how we make that isolation verifiable, and — just as important — where the physical limits are.


The one hard truth

100% isolation on a shared kernel is physically impossible. This holds for every single-server hosting panel (Plesk, cPanel, DirectAdmin, CloudPanel …), not just enconf. A local kernel privilege-escalation CVE, a MariaDB CVE or a PHP-binary CVE affects, in principle, every tenant of the same instance. True hard isolation exists only with a dedicated VM or container per customer.

So "nobody gets to the basics" means, honestly:

  1. Defense in depth — every layer must be broken individually.
  2. Verifiability — every layer is verified active and visible to the customer.
  3. Timely patching — the indivisible basics (kernel, MariaDB, PHP, Postfix/Dovecot) are updated as fast as possible.

Point 2 is our claim: provably secure, not claimed secure.


Defense in depth — the active layers

Every row corresponds to a real, system-verifiable mechanism. They are brought up to date on existing sites too, via an idempotent migration on updates.

Process & filesystem isolation

Layer What it does
One Linux user per website Own UID/GID; standard Unix DAC. Other sites cannot read the files.
Webroot 0710 user:www-data Owner full, Nginx may traverse, everyone else 0 — no cd from outside.
PHP-FPM pool per website PHP runs as the site's identity, no shared www-data.
open_basedir PHP is confined to home + its own /tmp + system PHP.
disable_functions exec, system, shell_exec, proc_open, popen, all pcntl_* and more blocked.
FFI disabled ffi.enable=0 — closes the FFI::cdef→libc bypass of disable_functions.
Per-user /tmp/<user> 0700 Own path for sessions/uploads — no cross-tenant leak via shared /tmp.
AppArmor profile per customer Own profile per PHP-FPM; switchable per server between complain and enforce mode, with automatic fallback on a burst of false positives.
systemd slice per customer MemoryMax / CPUQuota / TasksMax / IO — applies to new and existing sites.

Database & secrets

Layer What it does
Per-customer MariaDB/PostgreSQL grants GRANT … ON customer_db.* strictly — no global rights, no cross-DB queries.
Panel secrets 0600 root:root JWT_SECRET, DB_PASSWORD, AGENT_TOKEN are not readable by customer PHP.

Network & mail

Layer What it does
nftables SMTP egress block Only root/Postfix may reach port 25 outbound — no direct-to-MX spam from customer processes.
GeoIP filter with lock-out safety Country blocks with an allowlist for the admin/controller IP.
fail2ban Brute-force protection for SSH, FTP, mail and panel login.
Nginx upload .php block .php in upload directories is not executed — closes the most common WordPress hack pattern.

Kernel hardening

kernel.kptr_restrict, kernel.dmesg_restrict, yama.ptrace_scope, unprivileged_bpf_disabled, bpf_jit_harden, perf_event_paranoid are set. User namespaces are deliberately left enabled, since rootless containers/gVisor need them.


Verifiability — the decisive difference

Security you cannot see is, to a customer, indistinguishable from marketing. So enconf makes the isolation visible and continuously checked:

  • Per-customer security score: each customer sees, in their dashboard, an isolation score that shows per website which protection layers (dedicated PHP process, open_basedir, disable_functions, FFI off, sealed-off directory, AppArmor, resource limits …) are actually active — every row read back live from the server, not claimed.
  • Security Advisor (admin): server-wide audit checklist, SBOM (CycloneDX), a live CVE feed, and an evidence & export section for customers who are themselves manufacturers.
  • Central SIEM log forwarding: security-relevant logs are forwarded fleet-wide over TLS to a collector.

Supply chain & patch discipline

  • SBOM + live CVE feed (OSV / Debian security tracker) report vulnerable components proactively.
  • Signed APT repository (GPG-signed release metadata) for authentic updates.
  • Reproducible builds + checksums: packages are built deterministically (-trimpath, fixed timestamps), so rebuilding from source yields byte-identical artifacts; a SHA256SUMS list is published per release. Anyone can verify their install independently — not "trust us", but check for yourself.
  • Vendor repos pinned with key self-heal.
  • Automatic OS security updates (unattended-upgrades).
  • Evidence & export section supports customers who are themselves manufacturers of a product with digital elements with their EU Cyber Resilience Act supply-chain evidence (incident register, SBOM, CVE cross-check, export) — it is a tool, not a certification, and not relevant to most customers (see Security Advisor).

What we deliberately do NOT do

  • No on-server WAF. A WAF belongs upstream at the edge/reverse proxy, not on the hosting server. On-server WAFs are fragile in practice and create a false sense of security. WAF protection happens exclusively upstream.
  • No claimed isolation without verification. Every row of the security score must correspond to a real, checked mechanism.

Limits — named honestly

These points are architectural and cannot be fixed by panel layers; they affect every single-kernel system equally:

  • Kernel — all customers share one kernel. A local privesc CVE affects all.
  • MariaDB/PostgreSQL process — one instance per server.
  • PHP binary — all pools of the same version share the same code.
  • Postfix/Dovecot/PowerDNS — one instance each for all domains.

The mitigation is the same as at any serious provider: timely updates of the indivisible basics. Anyone who needs true kernel isolation runs customers in dedicated VMs or containers — enconf optionally offers rootless container isolation (gVisor) as a stronger tier for untrusted workloads.


This whitepaper is maintained alongside the security model. Current as of: see changelog.