Most of what has gone wrong with OpenClaw in 2026 was not a subtle exploit. It was gateways left open to the internet and skills installed without being read. Both are configuration problems, which means both are yours to fix. This is the runbook we use to self-host OpenClaw securely — the specific settings, in the order we apply them.
Do not bind the gateway to a public interface. Do not run it as root. Do not install a skill you have not opened. Those three cover the overwhelming majority of incidents reported this year.
Why self-hosting OpenClaw securely needs its own checklist
An agent with tool access is a different security object from a web app. A web app does what you programmed. An agent does what it decides, using credentials you gave it, in response to text a stranger sent it. The project's own README states the position plainly: treat inbound messages as untrusted input.
That is not boilerplate caution. Third-party skills are executable code — a skill can ship shell scripts and request tool permissions. Installing one from a marketplace is closer to piping a script from the internet into your shell than to adding a browser extension. Researchers found and documented exactly this pattern in circulation earlier this year.
OWASP now publishes a Top 10 for Agentic Applications (v2.01, June 2026). If you are building a security case for your own team, start there rather than with any vendor's marketing page.
Step 1 — Patch first, before anything else
Check your version before you touch configuration. CVE-2026-25253 describes token exfiltration via gatewayUrl, and the advisory gives the affected range as up to and including 2026.1.28. Several write-ups circulating online state a narrower range — take version ranges from the advisory, not from blog posts.
openclaw --version
npm install -g openclaw@latest
One dependency detail that wastes an afternoon if you miss it: OpenClaw expects Node 22.22.3+, 24.15+ or 25.9+. Node 26 is the current default. Node 23 is explicitly unsupported — if that is what your distro installed, fix it before you debug anything else.
Step 2 — Never expose the gateway
This is the single most common failure. The gateway listens on port 18789, and researchers scanning for it have repeatedly found instances answering from the public internet. Published counts vary by an order of magnitude depending on methodology, so the number is not the point — the point is that this keeps happening, and it is trivially avoidable.
Bind to localhost and put a firewall in front. On a Debian or Ubuntu host:
# default deny inbound, allow only what you actually need
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp # your SSH, ideally key-only
sudo ufw enable
# prove the gateway is not listening on a public interface
sudo ss -tlnp | grep 18789
# want: 127.0.0.1:18789 — NOT 0.0.0.0:18789 or [::]:18789
If that ss output shows 0.0.0.0, stop and fix the bind address before going further. Nothing else on this list matters while the gateway is reachable.
If you genuinely need remote access, terminate TLS at a reverse proxy and authenticate there — never by opening the port:
location / {
proxy_pass http://127.0.0.1:18789;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # gateway uses websockets
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
auth_basic "restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
allow 203.0.113.0/24; # your office range
deny all;
}
Step 3 — Run it unprivileged and boxed in
Give the agent its own user with no sudo, and let systemd constrain what that user can reach. Every directive below is doing real work, not decoration:
[Unit]
Description=OpenClaw gateway
After=network-online.target
[Service]
User=openclaw
Group=openclaw
ExecStart=/usr/bin/openclaw gateway
Restart=on-failure
# filesystem: read-only system, private tmp, only the workspace is writable
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/home/openclaw/.openclaw
# privilege: no path to escalation
NoNewPrivileges=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictSUIDSGID=true
# resource ceilings so a runaway loop cannot take the box down
MemoryMax=2G
TasksMax=256
[Install]
WantedBy=multi-user.target
ProtectSystem=strict plus a single ReadWritePaths is the important pair. If a skill misbehaves, the blast radius is one directory rather than the filesystem.
Step 4 — Treat every skill as untrusted code
Skills load from ~/.openclaw/skills/ or the workspace skills/ directory, each a folder with a SKILL.md and optional scripts/. Before enabling any skill you did not write, read it. The checklist we use:
- Open every file in
scripts/. Not a skim — read it. This is where a payload lives if there is one. - Grep for outbound calls. Any
curl,wget,fetchor raw socket to a host you do not recognise is disqualifying until explained. - Check what it reads. A skill touching
~/.ssh,~/.aws,.envfiles or the OpenClaw config itself needs a very good reason. - Read the
allowed-toolsfrontmatter. A note-taking skill requesting shell access is a contradiction. - Prefer skills you wrote. They are short. Writing one is usually faster than auditing someone else's.
Step 5 — Hold the credentials somewhere else
The strongest control is architectural, and it is the one people skip: do not give the agent your credentials at all.
Give it the ability to call a workflow, and let the workflow hold the keys and enforce the rules. The agent proposes; the workflow validates and decides. A compromised or confused agent then reaches "asked a webhook, which refused" rather than "wrote to production." We describe that wiring in full in our OpenClaw + n8n integration guide, and the reasoning behind splitting the two in OpenClaw vs n8n.
Where the agent must hold a secret, keep it in the environment rather than in a skill file, so it never lands in a repository or a skill you share.
Keeping OpenClaw self-hosted securely: a ten-minute monthly review
openclaw --versionagainst the latest release, and check the advisory feedsudo ss -tlnp | grep 18789— still localhost only?- List installed skills; remove anything unused. Unused code is pure attack surface
- Rotate the tokens the agent can reach
- Read a sample of recent transcripts. You are looking for requests that tried to steer the agent, not for correct answers
What we have not tested
We run self-hosted infrastructure and workflow automation for clients, and the hardening above is the standard we apply to services of this shape. Our OpenClaw-specific operating history is shorter than our n8n history: we have not run it under adversarial load, not tested these controls against an actual malicious skill, and not audited the gateway's own code. Everything here is defence-in-depth applied from primary documentation and published advisories — treat it as a floor, not a guarantee.
If you would rather have this built and monitored rather than maintained by hand, that is part of what our automation work covers.
Advisory ranges, Node version floors, gateway port and skill-loading paths verified against the OpenClaw repository, its documentation and NVD on 6 August 2026. Ports and defaults change between releases — confirm against the current docs before applying this to a live host.