Deploying a Secure 24/7 OpenClaw AI Agent on an M1 Mac
Recently, I set out to run the OpenClaw AI agent 24/7 on my fanless M1 MacBook Air (16GB RAM, 256GB SSD). My goals were clear but technically challenging: I needed the agent to be entirely secure and resource-isolated, avoid wearing down my battery, and importantly, run silently in the background without needing me to be logged into the desktop.
In this tutorial, I’ll walk you through my complete deployment structure—from creating an immutable APFS volume to building a boot-level LaunchDaemon—so you can safely host your own 24/7 personal AI agent on macOS.
1. Architectural Strategy
Given the constraints of a 256GB SSD and the fanless constraints of the M1 Air, efficiency and security had to be baked in from the ground up:
- Resource Limits: My SSD was already 73% full. To prevent OpenClaw’s Chrome profiles and logs from silently consuming the rest, I defined a strict 30GB APFS Volume Quota.
- Process Isolation: OpenClaw does not run as my primary admin account. We establish a dedicated
openclawstandard macOS user. - Headless Persistence: Instead of utilizing local
LaunchAgentscripts (which require an active GUI session), we implement a root-ownedLaunchDaemonfor boot-level startup.
2. Phase 1: System Preparation & Isolation
First, we create an absolutely isolated, non-admin user dedicated to running the daemon, and a dedicated storage layer.
Step 2.1: The Dedicated User
Run the following from your main administrator account terminal:
# Create standard user (non-admin)
sudo sysadminctl -addUser openclaw -fullName "OpenClaw Service" -password "YOUR_SECURE_PASSWORD" -admin 0 -shell /bin/zsh
# Ensure the user is completely stripped of admin group rights
sudo dseditgroup -o edit -d openclaw -t user admin
Step 2.2: The APFS Quota Volume
macOS APFS doesn’t support the traditional BSD edquota commands. The modern solution is creating an APFS volume with a strict, immutable quota:
# Provide exactly 30GB to the AI
sudo diskutil apfs addVolume disk3 APFS "OpenClawData" -quota 30g
# Hand ownership to the new openclaw user
sudo chown openclaw:staff /Volumes/OpenClawData
sudo chmod 750 /Volumes/OpenClawData
Step 2.3: Battery Saver & Sleep Prevention
A 24/7 server shouldn’t go to sleep. Keep the lid of the MacBook open for optimal thermal venting, and run:
# Prevent all system sleep mechanisms entirely
sudo pmset -a disablesleep 1 sleep 0 hibernatemode 0
Pro-Tip on Battery Degradation: Because the MacBook will be plugged in permanently, it’s imperative to manage the battery charge controller. Install AlDente and set the charge limit to 70%.
3. Phase 2: Installation and Onboarding
Install the global dependencies (like Node and OpenClaw) via your admin account so the AI user doesn’t own system-level binaries.
# As the admin user
npm install -g openclaw@latest
Next, switch contexts to the limited user to handle the specific configuration details and API keys. Note that OpenClaw’s wizard can’t handle background sudo password prompts gracefully, so keep interactive sudo entirely in your own human admin terminal.
# Switch to the limited user
su - openclaw
# Run the onboarding script
openclaw onboard --install-daemon
Configure your LLM provider of choice (e.g., Google Gemini 2.5 Flash). When the wizard prompts for the data path, ensure it targets your isolated volume: /Volumes/OpenClawData/workspace.
4. Phase 3: Writing the LaunchDaemon
The interactive wizard installs a LaunchAgent in the user’s home registry. This is insufficient since it demands you to physically log into the openclaw profile upon restart. Let’s clean it up and deploy a System Daemon instead.
First, wipe out the local LaunchAgent:
launchctl unload ~/Library/LaunchAgents/ai.openclaw.gateway.plist
rm ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Next, as your admin user, create the true LaunchDaemon:
sudo tee /Library/LaunchDaemons/com.openclaw.agent.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.openclaw.agent</string>
<!-- Run as the isolated standard user -->
<key>UserName</key>
<string>openclaw</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/openclaw</string>
<string>gateway</string>
<string>--config</string>
<string>/Users/openclaw/.openclaw/openclaw.json</string>
</array>
<!-- Restart if the daemon crashes -->
<key>KeepAlive</key>
<dict>
<key>Crashed</key>
<true/>
</dict>
<!-- Logging pipelines straight to the storage quota -->
<key>StandardOutPath</key>
<string>/Volumes/OpenClawData/logs/launchd.stdout.log</string>
<key>StandardErrorPath</key>
<string>/Volumes/OpenClawData/logs/launchd.stderr.log</string>
</dict>
</plist>
EOF
Load it into the system layer. It evaluates permissions rigorously, so file ownership is heavily enforced:
sudo chown root:wheel /Library/LaunchDaemons/com.openclaw.agent.plist
sudo chmod 644 /Library/LaunchDaemons/com.openclaw.agent.plist
sudo launchctl load /Library/LaunchDaemons/com.openclaw.agent.plist
5. Phase 4: Final Security & Logging Configuration
OpenClaw configs are strictly parsed as JSON5 locally inside ~/.openclaw/openclaw.json. Given the autonomous capabilities of the application, we lock down execution and tool permissions carefully.
Modify the permissions segment dynamically inside the data volume:
"tools": {
"enabled": true,
"defaultPolicy": "deny", // Block everything by default
"allowlist": [
"browser_navigate",
"browser_click",
"file_read",
"file_write"
]
},
Because of our fixed 30GB quota—and because visual headless workflows naturally bloat over time—I also authored two minor cron/scripts to orchestrate rolling 10-day retention policies on the generated logs alongside aggressive disk monitoring.
Conclusion & Core Takeaways
We now have an intelligent orchestration tier continuously running underneath macOS, consuming roughly 1.3% baseline CPU with safely isolated system permissions.
Here are the highest-value lessons I learned building the architecture:
- Forget
edquota: If you want hard storage walls on modern macOS, APFS Volume Quotas are the solitary way forward. They can’t be resized though, so measure twice. - Beware Dual-Gateways: Migrating from OpenClaw’s standard
LaunchAgenttoLaunchDaemon? Double-checkps aux | grep openclawto ensure you aren’t silently colliding and spiking CPU bounds to 125% like I initially was. - YAML Need Not Apply: If your config fails to load gracefully, remember that OpenClaw’s internal schema operates on JSON5!
- Hybrid Automation: Attempting to force AI to operate standard
sudoprompts securely gets messy. Dedicate a side window explicitly for your human-level root operations during set up.
Have you deployed OpenClaw? Did you use a dedicated Mac Mini or integrate tightly onto your daily M-series driver? Let me know in the comments below!
Leave a Reply