Your server, our hardening
Managed VPS instances run on dedicated Hetzner servers provisioned through our cloud-init pipeline. Every server boots with a locked-down security configuration — no manual steps, nothing to forget.
Zero exposed ports
UFW firewall denies all incoming traffic except SSH (key-only, no passwords). The OpenClaw gateway binds to 127.0.0.1 and is accessible only through a Cloudflare Tunnel — an outbound-only connection from the server to Cloudflare's edge. There are no listening ports for scanners to find.
Cloudflare Tunnel with token auth
All gateway traffic routes through a managed Cloudflare Tunnel. The tunnel itself requires a 256-bit token for setup, and the management API behind it requires a separate bearer token for every request. The tunnel token is encrypted with AES-256-GCM before it ever hits our database.
Gateway token encrypted at rest
Your gateway authentication token is generated with 256 bits of entropy from crypto.getRandomValues(), encrypted with AES-256-GCM using a PBKDF2-derived key (100,000 iterations), and stored encrypted. It's decrypted only when we need to talk to your server.
SSH hardened from first boot
Password authentication is disabled in cloud-init before the server is reachable. Root login requires a key. fail2ban bans IPs after 5 failed attempts for an hour. This isn't optional or configurable — it's baked into every provision.
Automatic security updates
unattended-upgrades is configured from day one. Security patches apply automatically. OS packages are cleaned weekly. You don't have to remember to update — and neither do we.
Management API locked behind auth
The VPS management API (restart, logs, health checks) lives behind the Cloudflare Tunnel at a restricted path. Every request requires bearer token authentication. The health endpoint is the only exception — and it returns nothing sensitive.
Custom domain DNS verification
Before we route traffic to your custom domain, we verify the CNAME record via DNS-over-HTTPS. No spoofed domains, no DNS rebinding. Your domain must resolve to us before we accept it.
Shared security baseline
These apply to every Ekuri deployment regardless of tier.
AES-256-GCM encryption for stored secrets
Gateway tokens, tunnel tokens, and the control-plane copies of BYOK credentials are encrypted before storage using AES-256-GCM with PBKDF2-derived keys, random salts, and random IVs. BYOK credentials are also written to the user's dedicated VPS for runtime use, but plaintext secrets are never stored in D1, KV, or source control.
Constant-time comparisons everywhere
JWT signatures, webhook signatures, internal auth tokens, gateway tokens — every security-critical string comparison uses timing-safe functions. This isn't just the auth layer. It's every worker, every endpoint.
CORS allowlist + origin validation
No Access-Control-Allow-Origin: *. We maintain an explicit origin allowlist. State-changing requests (POST, PUT, DELETE) with a cross-origin Origin header are rejected at the middleware level.
Secure session management
Sessions use JWT with HS256, backed by Cloudflare KV for revocation. Cookies are HttpOnly, Secure, SameSite=Lax. Deleted accounts are denylisted. Each session has a unique jti — logging out one device doesn't nuke all your sessions.
Secrets passed via environment, not code
API keys, gateway tokens, and auth secrets are injected through environment variables — never interpolated into shell scripts, never in URLs, never in command-line arguments. Cloudflare Workers secrets are encrypted at rest by Cloudflare.
Accountability, monitoring, and incident response
Hardening only matters if we can detect failures, audit privileged access, and explain what happens when something goes wrong. These controls are public because we expect them to be checked.
30-second health checks with automatic restart
Managed VPS health is checked every 30 seconds over HTTPS through Cloudflare. If a gateway becomes unhealthy, we restart it automatically. If it fails repeatedly, the team receives an alert and the current status remains visible in the dashboard and help flows.
Break-glass admin access is time-boxed and audited
SSH is disabled by default. When emergency admin access is required, the access path is logged with timestamps and reason codes, and temporary credentials auto-revoke after one hour. We document this in our Terms and Privacy Policy.
Retention, export, backup, restore, and deletion are user-visible
Users can choose 30, 90, 365, or indefinite retention, export their data from the dashboard, create and restore encrypted backups, and delete all data or the entire account. The lifecycle is public and documented in our Terms and Privacy Policy.
Public disclosure policy with response targets
We publish a real security.txt and a public security disclosure policy. Current targets: acknowledge reports within 48 hours, provide weekly status updates for accepted reports, and notify affected customers within 72 hours of confirming a material customer-data incident.
Build, dependency, and release hygiene
We publish inspectable artifacts instead of asking for blind trust. Reviewers can verify these directly from the site and the public repository.
Source and infrastructure code are public
Our Pages Functions, VPS worker, manage-api service, and deployment configuration live in the public ekuriai/ekuri repository. Lockfiles are committed for the web app and both workers so releases are tied to specific dependency trees.
CI runs on every push and pull request
Our public CI workflow installs dependencies, runs typechecks, executes tests, performs runtime dependency audits for the app and workers, and generates SBOM artifacts for review.
Automated dependency intake
Dependabot watches npm dependencies and GitHub Actions across the main app and worker services so updates arrive as reviewable pull requests instead of silent drift.
Public CycloneDX SBOMs
Runtime dependency inventories are generated during each build and published here: web app, manage-api, VPS worker, plus a manifest with generation metadata.