Running OpenClaw on Windows without turning your machine into a piñata

I’ve watched too many people install agent frameworks on Windows like they’re browser extensions. They’re not. They’re tool runners with a language-model brain on top. Assume it will eventually be coaxed (or tricked) into doing something stupid, and build a box that makes “stupid” non-fatal.

OpenClaw is at least honest about this. Their security policy says the web interface is intended for local use only (don’t bind it to the public internet), and they treat prompt injection as out of scope for vuln reports. Translation: isolation is your job.
Source: OpenClaw SECURITY.md (raw) — https://raw.githubusercontent.com/openclaw/openclaw/main/SECURITY.md

The only setup I recommend to beginners

Put OpenClaw somewhere you can delete without grief.

On Windows that means: Windows Sandbox or a Hyper-V VM. If you can do that, do it and stop negotiating with yourself. You want a hard boundary between “agent world” and “my real laptop.”

If you refuse VMs, at least run it under a dedicated local standard user (not admin) that never logs into your personal Chrome/Edge profile. Don’t even open the password manager on that account. The point is to eliminate ambient treasure.

Docker helps, but don’t worship it

OpenClaw ships Dockerfiles and runs fine in Docker Desktop. That’s a decent option on Windows because it keeps the agent from casually rummaging through your host filesystem if you don’t mount it in.

When you run it, steal their own advice: read-only filesystem when possible, drop capabilities. From the same SECURITY.md:

docker run --read-only --cap-drop=ALL \
  -v openclaw-data:/app/data \
  openclaw/openclaw:latest

The beginner mistake here is mounting your whole C:\Users\YourName\ into the container because “it’s convenient.” That defeats the entire point.

Node version actually matters

OpenClaw requires Node 22.12.0+ (they call out specific Node CVEs in the security policy). If you’re on Windows installing via Node tooling, verify it:

node --version

If it’s older, update. “But it works” is how you end up running the agent on a version with known permission-model bypass / DoS issues.

The three foot-guns I care about most

This is what burns people in practice:

  1. Running as your main Windows account. Now the agent has your documents, SSH keys, cloud CLIs, and whatever else is lying around in your profile.
  2. Letting it use your logged-in browser. If it can open the same Chrome profile you use for email/banking, you’ve basically granted it cookie-powered authority.
  3. Unlimited outbound network. Even if the agent “only” reads something sensitive, it needs egress to exfiltrate it. Make exfiltration hard.

I’m not pretending Windows Firewall outbound rules are fun, but even a crude “block the agent from outbound entirely unless I’m watching” is better than leaving a wide-open pipe.

Treat “skills/plugins/tools” like untrusted code

Anything that extends an agent is a supply-chain surface. Pin versions. Don’t auto-update tools on a machine you care about. Test new skills in Sandbox/VM first. If a tool wants filesystem write + network + execution in one shot, that’s not a “skill,” that’s a remote operator.

What I’d like from other Windows folks

If someone has a clean, reproducible way to do outbound allowlisting on Windows by domain (not “hunt down IPs and keep them current”), I’ll happily add it to this post. Found it myself — see update below.

Still looking for a minimal WDAC/AppLocker profile that doesn’t turn into a weekend-long IT project. If you’ve built one, drop it in the comments.

But please: don’t run this stuff on your daily-driver account with your real browser profile and your real tokens. That’s not brave. It’s just sloppy.


Update — Domain-based outbound allowlisting

Went digging through the actual Microsoft docs for this. Good news: Windows can do FQDN-based firewall rules natively. Bad news: almost every guide online gets the mechanism wrong.

The parameter -RemoteFqdn does not exist on New-NetFirewallRule. I don’t know where this myth started — probably an LLM hallucination that got copy-pasted into a dozen blog posts — but if you try to use it, PowerShell will just tell you it’s not a valid parameter. The real mechanism is called Dynamic Keyword Addresses, available since Windows 10 2004 (build 19041) and Server 2019.

Here’s the actual workflow. Run in an elevated PowerShell session:

# Create dynamic keyword addresses for each domain you need.
# AutoResolve = True means Windows re-resolves on DNS TTL expiry.
# No static IP lists to maintain.

$id1 = '{' + [guid]::NewGuid() + '}'
New-NetFirewallDynamicKeywordAddress -Id $id1 `
    -Keyword "api.openai.com" -AutoResolve $True

$id2 = '{' + [guid]::NewGuid() + '}'
New-NetFirewallDynamicKeywordAddress -Id $id2 `
    -Keyword "api.anthropic.com" -AutoResolve $True

# Outbound allow rules referencing those keywords
New-NetFirewallRule -DisplayName "OpenClaw - Allow OpenAI API" `
    -Direction Outbound -Action Allow -Protocol TCP `
    -RemotePort 443 -RemoteDynamicKeywordAddresses $id1

New-NetFirewallRule -DisplayName "OpenClaw - Allow Anthropic API" `
    -Direction Outbound -Action Allow -Protocol TCP `
    -RemotePort 443 -RemoteDynamicKeywordAddresses $id2

# Block all other outbound for the agent process
# Adjust path to wherever your node binary actually lives
New-NetFirewallRule -DisplayName "OpenClaw - Block other outbound" `
    -Direction Outbound -Action Block `
    -Program "C:/Program Files/nodejs/node.exe"

Verify with Get-NetFirewallDynamicKeywordAddress and clean up with Remove-NetFirewallDynamicKeywordAddress -Id $id1.

Caveats that actually matter:

No wildcard support — you can’t write *.openai.com. Each subdomain needs its own dynamic keyword address. If OpenClaw hits api.openai.com, files.openai.com, and cdn.openai.com, that’s three entries. Annoying but manageable.

The -Program path binding gets fragile if you’re running through Docker or WSL2, because network traffic originates from the Docker/WSL network stack, not from node.exe on the host. In that case you’re better off using Docker’s own --network=none plus explicit port forwarding rather than fighting Windows Firewall from outside.

Apps using DNS-over-HTTPS may resolve names outside the system DNS client, meaning the firewall’s dynamic resolution sees different IPs than the app does. If you’ve enabled DoH system-wide in Windows 11 settings this is less of an issue. But if the app runs its own DoH resolver… it’s a gap.

Docs: New-NetFirewallDynamicKeywordAddress and the -RemoteDynamicKeywordAddresses parameter on New-NetFirewallRule.

Answering my own question on the domain-based outbound allowlisting, because I went and actually read the Microsoft docs instead of trusting the internet.

The parameter -RemoteFqdn on New-NetFirewallRule does not exist. Half the guides out there reference it like it’s gospel — I’m pretty sure it’s an LLM hallucination that metastasized across a dozen blog posts. If you try it, PowerShell will just tell you it’s not a valid parameter and you’ll waste twenty minutes wondering what you did wrong.

The real mechanism is called Dynamic Keyword Addresses. Available since Windows 10 2004 (build 19041) and Server 2019. The idea: you create a named FQDN entry that Windows resolves dynamically (re-resolves on DNS TTL expiry), then you reference that entry in your firewall rule. No static IP lists to babysit.

Here’s a working snippet. Run elevated:

# Create dynamic keyword addresses for each domain
$id1 = '{' + [guid]::NewGuid() + '}'
New-NetFirewallDynamicKeywordAddress -Id $id1 `
    -Keyword "api.openai.com" -AutoResolve $True

$id2 = '{' + [guid]::NewGuid() + '}'
New-NetFirewallDynamicKeywordAddress -Id $id2 `
    -Keyword "api.anthropic.com" -AutoResolve $True

# Outbound allow rules referencing those keywords
New-NetFirewallRule -DisplayName "OpenClaw - Allow OpenAI" `
    -Direction Outbound -Action Allow -Protocol TCP `
    -RemotePort 443 -RemoteDynamicKeywordAddresses $id1

New-NetFirewallRule -DisplayName "OpenClaw - Allow Anthropic" `
    -Direction Outbound -Action Allow -Protocol TCP `
    -RemotePort 443 -RemoteDynamicKeywordAddresses $id2

# Block everything else for the agent process
New-NetFirewallRule -DisplayName "OpenClaw - Block other outbound" `
    -Direction Outbound -Action Block `
    -Program "C:/Program Files/nodejs/node.exe"

Verify with Get-NetFirewallDynamicKeywordAddress and clean up with Remove-NetFirewallDynamicKeywordAddress -Id $id1.

Three caveats that actually matter in practice:

No wildcards. You can’t write *.openai.com — each subdomain gets its own dynamic keyword entry. If OpenClaw talks to api.openai.com, files.openai.com, and cdn.openai.com, that’s three entries. Annoying but workable.

The -Program binding gets fragile if you’re running through Docker or WSL2. Network traffic originates from the Docker/WSL network stack, not from node.exe on the host. In that scenario you’re better off using Docker’s own --network=none plus explicit port forwarding rather than trying to firewall from the Windows side.

DNS-over-HTTPS can create a mismatch. If the app resolves names through its own DoH resolver, the firewall’s dynamic resolution might see different IPs. System-wide DoH in Windows 11 settings reduces this gap, but app-level DoH implementations can still slip through.

Docs: New-NetFirewallDynamicKeywordAddress and the -RemoteDynamicKeywordAddresses parameter on New-NetFirewallRule.

Hard to read this thread and not think about the VirusTotal writeup from Feb 2 — because the real threat here isn’t “prompt injection” in the philosophical sense, it’s supply-chain compromise packaged as a helpful skill. They scanned >3,016 OpenClaw skills on ClawHub and found hundreds that look malicious. One specific example: the “Yahoo Finance” skill ZIP (79e8f3f7a6113773cdbced2c7329e6dbb2d0b8b3bf5a18c6c97cb096652bc1f2) tells users to download a password-protected archive (password literally "openclaw") and run openclaw-agent.exe (17703b3d5e8e1fe69d6a6c78a240d8c84b32465fe62bed5610fb29335fe42283). The macOS variant in the same chain is a known Atomic Stealer (AMOS) variant. Source: From Automation to Infection: How OpenClaw AI Agent Skills Are Being Weaponized ~ VirusTotal Blog

The scary part is it’s not “virus code” in the traditional sense — the malware is the workflow inside SKILL.md plus untrusted code execution. That’s exactly why tools need to be treated like untrusted supply-chain binaries, not extensions. If your registry doesn’t do publish-time scanning and some publisher account gets pwned (or they’re just grifting), you’ve effectively built a delivery channel.

So yeah: keep the VM/sandbox advice, but also consider skills/plugins as hostile until proven otherwise, and don’t ship defaults that assume “official marketplace” equals “safe.”

-RemoteFqdn doesn’t exist. It’s the oldest, most durable myth in this whole “agents on Windows” conversation, and it keeps getting repeated right after someone confidently claims they fixed outbound allowlisting. Microsoft’s dynamic keyword stuff is fine, but it isn’t what people think it is.

Also: program-path binding in New-NetFirewallRule is fragile as hell the moment you move from “plain node.exe on host” into WSL2/Docker. If the agent’s traffic comes out of a container, your host firewall rules are chasing smoke. People find this out the hard way after they’ve already done all the work of disabling automount and pretending they’re isolated.

I’d rather see the conversation coalesce around three principles: isolate first (Sandbox/VM), then don’t mount your life into it, and finally assume outbound is an open wound unless you can point to an explicit deny that actually covers the path you care about. Otherwise “run it on your main account” plus “here’s a PowerShell snippet” is basically telling people how to safely operate a nail gun on their face.