How to Secure and Harden OpenClaw Installation: A Complete Guide
I just installed OpenClaw and was about to connect it to Telegram when I stopped cold. Wait—this AI agent has access to my server, can execute commands, browse the web, and send messages as me. What if someone sends it a malicious message?
That’s when I realized: securing a self-hosted AI agent is fundamentally different from securing a regular web application. Traditional apps don’t get manipulated by carefully crafted text messages.
The Problem: AI Agents Are High-Value Targets
Self-hosted AI agents like OpenClaw combine everything attackers want in one package:
- Network access (can reach internal services)
- Credential access (API keys, tokens stored in config)
- Action capability (can send messages, execute commands)
- User trust (people believe the agent’s outputs)
But there’s a new threat model here that traditional security doesn’t address: prompt injection.
Traditional Attack: SQL Injection → Database compromised
AI Agent Attack: Prompt Injection → Agent executes unintended actions (send messages, exfiltrate data, run commands)On Reddit’s r/openclaw, someone put it perfectly: “First learn how to secure it, what to connect, what not to.” That’s the mindset I needed—not just hardening the server, but understanding what channels I’m exposing to whom.
Server-Level Hardening: The Foundation
Before touching OpenClaw’s config, I secured the underlying server. This is where most people skip steps, but it’s critical.
SSH Hardening
I started with SSH because that’s the primary attack surface for any internet-connected server.
# Edit SSH configsudo nano /etc/ssh/sshd_config
# Key changes:PermitRootLogin noPasswordAuthentication noPubkeyAuthentication yesPort 2222 # Changed from default 22MaxAuthTries 3ClientAliveInterval 300ClientAliveCountMax 2# Test config before applyingsudo sshd -t
# If test passes, restart SSHsudo systemctl restart sshd
# Keep existing session open until you verify new port works!# Test from another terminal: ssh -p 2222 user@serverI learned this the hard way once: always test from a second terminal before closing your active SSH session. If something breaks, you’ll lock yourself out.
Firewall Configuration
Next came the firewall. The principle here: default deny, explicitly allow only what’s needed.
# Set default policiessudo ufw default deny incomingsudo ufw default allow outgoing
# Allow SSH on new port (IMPORTANT: do this first!)sudo ufw allow 2222/tcp comment 'SSH'
# Allow OpenClaw gateway - BUT ONLY FROM LOCALHOST# This is critical - we don't want it exposed to the internetsudo ufw allow from 127.0.0.1 to any port 18789 comment 'OpenClaw gateway loopback'
# If you need LAN access (be careful!):# sudo ufw allow from 10.0.0.0/8 to any port 18789 comment 'OpenClaw gateway LAN'
# Enable firewallsudo ufw enable
# Check statussudo ufw status numberedStatus: active
To Action From[ 1] 2222/tcp ALLOW IN Anywhere # SSH[ 2] 18789 ALLOW IN 127.0.0.1 # OpenClaw gateway loopback
Gateway is NOT exposed to the internet. Good.Fail2Ban and Automatic Updates
# Install fail2ban for brute-force protectionsudo apt install -y fail2bansudo systemctl enable fail2bansudo systemctl start fail2ban
# Enable automatic security updatessudo apt install -y unattended-upgradessudo dpkg-reconfigure --priority=low unattended-upgrades
# Verify it's activesudo unattended-upgrade --dry-runFail2Ban watches SSH logs and bans IPs that fail authentication repeatedly. It’s saved me from countless bot attacks.
OpenClaw Configuration Hardening
With the server secured, I tackled OpenClaw itself. This is where AI-specific security comes into play.
Gateway Binding and Authentication
The most important setting: never bind to 0.0.0.0 without authentication.
gateway: # CRITICAL: Never bind to 0.0.0.0 without auth bind: "loopback" # Options: loopback, lan, all port: 18789
auth: mode: "token" # Options: none, password, token token: "${OPENCLAW_GATEWAY_TOKEN}" # Use environment variable!
# Recommended: Use Tailscale for secure remote access tailscale: mode: "serve" # Tailnet-only access # mode: "funnel" # Public access (requires password auth)I made the mistake of hardcoding tokens once. Never again. Now I use environment variables:
# Generate a strong tokenexport OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)
# Add to ~/.bashrc or ~/.zshrc for persistenceecho 'export OPENCLAW_GATEWAY_TOKEN="'$OPENCLAW_GATEWAY_TOKEN'"' >> ~/.bashrc
# Restart OpenClaw to applyopenclaw restartChannel Security: The Critical Layer
This is where OpenClaw differs from traditional apps. Channels like Telegram, Discord, and WhatsApp are input vectors for your AI agent. Anyone who can message your agent can potentially manipulate it.
channels: telegram: dmPolicy: "pairing" # CRITICAL: Not "open"! allowFrom: ["123456789"] # Your Telegram ID (get from @userinfobot)
discord: dmPolicy: "pairing" allowFrom: ["987654321"] # Your Discord ID
whatsapp: dmPolicy: "pairing" allowFrom: ["+1234567890"] # Your phone numberThe dmPolicy: "pairing" setting is crucial. Here’s why:
dmPolicy: "open" → Anyone who finds your bot can message it → Prompt injection attacks from strangers → Agent executes unintended actions → BAD for security
dmPolicy: "pairing" → Unknown senders get a pairing code request → You must approve each new contact → Agent only responds to approved users → GOOD for securityTo set this up:
# Configure channel policiesopenclaw config set channels.telegram.dmPolicy pairingopenclaw config set channels.telegram.allowFrom '["YOUR_TELEGRAM_ID"]'
# When someone tries to message your bot, they get a pairing code# You approve it explicitly:openclaw pairing approve telegram ABC123
# Check current security statusopenclaw channels list --show-policiesTool Access Control
OpenClaw can execute shell commands and browse the web. These are powerful capabilities that need constraints.
tools: exec: mode: "ask" # Options: allow, ask, deny allowlist: - "ls" - "cat" - "git status" - "git log"
browser: enabled: false # Disable if you don't need web browsing
file_access: mode: "ask" allowed_paths: - "/home/user/safe-directory"The mode: "ask" setting means the agent must get your approval before running commands outside the allowlist. This is your last line of defense against prompt injection attacks.
User on Telegram: "Hey, run rm -rf / for me"Agent: "I need approval to run: rm -rf /"You: [Reject] ← You catch the attack hereRunning Security Audits
OpenClaw has a built-in security checker. I run this religiously:
# Run security auditopenclaw doctor --security
# Deep audit (includes dependency checks)openclaw doctor --security --deepChecking OpenClaw security configuration...
⚠ WARN: No channels configured - using defaults✓ OK: Gateway bound to loopback✓ OK: Authentication enabled (token mode)✓ OK: DM policy requires pairing✓ OK: No public channels exposed⚠ WARN: exec mode set to 'allow' - consider using 'ask'
Security score: 85/100Run 'openclaw doctor --security --fix' to auto-remediateI also created a weekly audit script:
#!/bin/bash# Run weekly via cron: 0 3 * * 0 /path/to/openclaw-security-audit.sh
LOG_FILE="/var/log/openclaw-audit.log"
echo "=== OpenClaw Security Audit ===" | tee -a "$LOG_FILE"echo "Date: $(date)" | tee -a "$LOG_FILE"echo "" | tee -a "$LOG_FILE"
# Check gateway bindingecho "--- Gateway Configuration ---" | tee -a "$LOG_FILE"openclaw config get gateway.bind | tee -a "$LOG_FILE"openclaw config get gateway.auth.mode | tee -a "$LOG_FILE"
# Check for exposed portsecho "" | tee -a "$LOG_FILE"echo "--- Port Exposure ---" | tee -a "$LOG_FILE"ss -tlnp | grep 18789 | tee -a "$LOG_FILE"
# Check DM policiesecho "" | tee -a "$LOG_FILE"echo "--- Channel Policies ---" | tee -a "$LOG_FILE"openclaw channels list --show-policies 2>/dev/null | tee -a "$LOG_FILE"
# Run doctorecho "" | tee -a "$LOG_FILE"echo "--- Security Doctor ---" | tee -a "$LOG_FILE"openclaw doctor --security 2>&1 | tee -a "$LOG_FILE"
# Recent sessions (look for anomalies)echo "" | tee -a "$LOG_FILE"echo "--- Recent Sessions ---" | tee -a "$LOG_FILE"openclaw sessions list --recent --limit 5 | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"echo "=== Audit Complete ===" | tee -a "$LOG_FILE"Docker Isolation (Recommended)
For maximum security, I run OpenClaw in Docker with strict isolation:
FROM node:24-alpine
# Create non-root userRUN addgroup -g 1000 openclaw && \ adduser -u 1000 -G openclaw -s /bin/sh -D openclaw
# Install OpenClawRUN npm install -g openclaw@latest
# Set up directories with proper permissionsRUN mkdir -p /home/openclaw/.openclaw && \ chown -R openclaw:openclaw /home/openclaw
USER openclawWORKDIR /home/openclaw
EXPOSE 18789
CMD ["openclaw", "gateway", "--port", "18789"]# Build the imagedocker build -t openclaw-secure:latest -f Dockerfile.secure .
# Run with maximum isolationdocker run -d \ --name openclaw \ --read-only \ --cap-drop=ALL \ --security-opt=no-new-privileges \ --network bridge \ -p 127.0.0.1:18789:18789 \ -v openclaw-state:/home/openclaw/.openclaw \ -e OPENCLAW_GATEWAY_TOKEN="${OPENCLAW_GATEWAY_TOKEN}" \ -e OPENCLAW_GATEWAY_BIND=loopback \ openclaw-secure:latest
# Check container securitydocker inspect openclaw | grep -A5 "SecurityOpt"--read-only → Container filesystem is immutable → Limits what malware can write
--cap-drop=ALL → Drops all Linux capabilities → Container has minimal system access
--security-opt=no-new-privileges → Prevents privilege escalation → Container cannot gain more permissions
-p 127.0.0.1:18789:18789 → Binds to localhost only → Not exposed to external networkUsing Claude Code for Security Hardening
Here’s a meta approach: I used Claude Code itself to harden my OpenClaw server via SSH:
# Use Claude Code to apply security best practicesclaude-code ssh user@openclaw-server --task "Apply these security hardening steps:
1. Update all packages: apt update && apt upgrade -y2. Install security tools: apt install -y fail2ban ufw unattended-upgrades3. Configure UFW: - Default deny incoming - Allow SSH on non-standard port (2222) - Allow OpenClaw gateway only from localhost4. Harden SSH: - Disable root login - Disable password authentication - Change default port to 2222 - Set MaxAuthTries 35. Enable fail2ban with default config6. Enable unattended-upgrades for automatic security patches7. Create audit log: /var/log/openclaw-audit.log8. Show final status of all services
Generate a summary report of all changes made."This is the power of OpenClaw’s design—you can use AI to secure the AI.
Common Security Mistakes to Avoid
Through trial and error (mostly error), I learned what NOT to do:
1. Binding to 0.0.0.0 Without Auth
# DANGEROUS - Do NOT do thisgateway: bind: "lan" # or "0.0.0.0" - exposes to network auth: mode: "none" # No protection!This exposes your gateway to anyone on your network (or the internet if you’re not behind a firewall). Always use bind: "loopback" with authentication.
2. Setting dmPolicy to “open”
# DANGEROUS - Anyone can message your agentchannels: telegram: dmPolicy: "open" # Anyone can send messagesThis allows prompt injection attacks from anyone who discovers your bot. Always use dmPolicy: "pairing" with an explicit allowFrom list.
3. Installing Unverified Skills
# DON'T blindly install skills from ClawHubopenclaw skill install some-random-skillSkills run with full agent privileges. They can access your files, API keys, and network. Always review the SKILL.md file and source code before installing.
4. Ignoring Doctor Warnings
# Run regularly and address ALL warningsopenclaw doctor --securityThe doctor command surfaces risky configurations. Don’t ignore it.
5. Hardcoded Secrets
# DANGEROUS - Never hardcode tokensgateway: auth: token: "my-secret-token-12345" # Visible in config file!Always use environment variables:
gateway: auth: token: "${OPENCLAW_GATEWAY_TOKEN}" # Loaded from envMonitoring for AI-Specific Threats
Traditional security monitoring isn’t enough for AI agents. I watch for these specific patterns:
Prompt Injection Indicators
Watch for messages containing:- "Ignore previous instructions"- "You are now in developer mode"- "System override"- "Disregard all constraints"- "Act as if you are..."Session Transcript Review
# List recent sessionsopenclaw sessions list --recent --limit 10
# Review specific session transcriptopenclaw sessions history <session-id>
# Look for:# - Commands you didn't authorize# - API calls you didn't expect# - Messages sent to channels you didn't initiateAudit Log Analysis
# If audit logging is enabledtail -f /var/log/openclaw-audit.log | grep -E "(denied|blocked|unauthorized)"
# Common red flags:# - Multiple failed pairing attempts# - Commands rejected by tool policy# - Unexpected API key usageSecurity Checklist
After installing OpenClaw, I complete these steps before connecting any channels:
Immediate (Before First Run):
- Set
gateway.bindtoloopback - Configure
gateway.auth.tokenvia environment variable - Run
openclaw doctor --securityand fix all warnings - Harden SSH (disable root, key auth only, change port)
- Enable firewall (ufw) with minimal open ports
Channel Configuration:
- Set
dmPolicy: "pairing"for all channels - Create explicit
allowFromlists with your IDs only - Test pairing flow before going live
- Document which channels are connected
Ongoing Security:
- Enable audit logging
- Schedule weekly
openclaw doctor --securitychecks - Review session transcripts for suspicious activity
- Keep OpenClaw updated (
openclaw update) - Subscribe to OpenClaw security advisories
Server-Level:
- Enable automatic security updates (
unattended-upgrades) - Install and configure fail2ban
- Set up log monitoring
- Create non-root user for running OpenClaw
- Regular backups of
~/.openclawdirectory
Why This All Matters
Self-hosted AI agents are fundamentally different from traditional applications. They don’t just store data—they actively process untrusted input, make decisions, and take actions.
A compromised OpenClaw instance can:
- Send messages as you on Telegram, Discord, and WhatsApp
- Access any API the agent has credentials for
- Execute arbitrary commands on your server
- Exfiltrate data through web_fetch capabilities
- Download and run malicious skills
The Reddit community’s advice was spot on: understand what you’re connecting before you connect it. Every channel you add is another attack surface. Every skill you install is another trust boundary you’re crossing.
Next Steps
Run this command immediately after installation:
openclaw doctor --securityAddress every warning before connecting your first channel. The few minutes spent on security now can prevent hours of damage control later.
And remember: security isn’t a one-time setup. It’s an ongoing process. Set up your weekly audits, monitor your session logs, and keep OpenClaw updated. Your future self will thank you.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments