You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
blog: harden OpenClaw post security posture (#248)
* blog: harden OpenClaw post security posture
- Remove specific locations, chat counts, plist names, exact schedules
- Generalize infrastructure to "Mac-class device" / "system service"
- Describe guardrails as principles (least privilege, separate service
accounts, out-of-band approval) rather than exact mechanisms
- Reframe hard parts as lessons learned, not precise failure modes
- Remove personal schedule details; add consent language for shared data
- Add monitoring/detection section (weekly activity report, anomaly alerts)
- Remove GOG_KEYRING_PASSWORD and other implementation specifics
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* blog: humanizer pass on OpenClaw post
- Remove formulaic openers ("The lesson:", "The takeaway:", "The goal")
- Break up rule-of-three/five feature lists into shorter sentences
- Rewrite security paragraph from brochure tone to plain language
- Cut negative parallelism ("not just X, but Y")
- Vary sentence structure and rhythm throughout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: content/blog/2026-02-24-openclaw-the-home-agent.txt
+30-42Lines changed: 30 additions & 42 deletions
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
title: "OpenClaw: Experimenting with a personal AI agent"
3
3
date: 2026-02-24
4
4
author: Dylan & Claude
5
-
description: "What I learned running an open-source AI agent on a Mac Mini--with guardrails, iMessage, and enough cron jobs to book date night every month."
5
+
description: "What I learned running an open-source AI agent on a self-hosted Mac Mini--least privilege, out-of-band approvals, and the boring plumbing that makes it work."
6
6
tags:
7
7
- AI
8
8
- Projects
@@ -11,96 +11,84 @@ category: Technical
11
11
draft: false
12
12
---
13
13
14
-
[OpenClaw](https://openclaw.ai/) is an open-source framework for building personal AI agents on your own hardware. It's a gateway process that gives Claude (or any model) persistent identity, message routing across iMessage and Slack, browser automation, cron scheduling, and a skill system for wiring up APIs. Self-hosted, no cloud dependency, runs on a Mac Mini.
14
+
[OpenClaw](https://openclaw.ai/) is an open-source framework for building personal AI agents on your own hardware. A gateway process gives Claude (or any model) persistent identity and connects it to messaging channels, browser automation, cron jobs, and whatever APIs you wire up. No cloud dependency. Runs on a Mac Mini.
15
15
16
16
I wanted to see how far I could take it. Not by giving an agent the keys to everything on day one, but by adding one capability at a time and making sure each one had real limits on what it could do. This is what that looked like after a few months--what I wired up, what broke, and what surprised me.
17
17
18
18
## My setup
19
19
20
-
I wanted an assistant that could actually do things--adjust the thermostat, book a restaurant, triage email, order dish soap--from an iMessage thread. Each skill got added only after I figured out what it should never be allowed to do.
20
+
I wanted an assistant that could actually do things--adjust the thermostat, book a restaurant, triage email, order household supplies--from an iMessage thread. Each skill got added only after I figured out what it should never be allowed to do.
21
21
22
-
My instance runs on a Mac Mini in my cabin. It talks to me through iMessage, has 27 skills wired into the Nest thermostat, 1Password, Resy, Gmail, and a bunch more. Most of the work was plumbing, not AI.
22
+
My instance runs on a Mac Mini in my cabin. It talks to me through iMessage with skills across smart home, dining, email, shopping, and productivity. Most of the work was plumbing, not AI.
23
23
24
24
## The architecture
25
25
26
-
A Node.js gateway process sits behind a macOS LaunchAgent. The gateway wraps Claude (Sonnet 4.6 at the moment) and connects it to iMessage--140+ group chats and DMs. Sessions reset at 4 AM or after two hours idle, which keeps context fresh without breaking continuity mid-conversation.
26
+
A Node.js gateway process runs as a system service on macOS. The gateway wraps Claude and connects it to iMessage. Sessions reset periodically, which keeps context fresh without breaking continuity mid-conversation.
The wrapper script is worth calling out. macOS LaunchAgents run in a stripped-down environment where keychain access, 1Password CLI, and GUI interactions all behave differently than a normal terminal session. The wrapper pre-caches secrets, patches third-party library bugs at startup, and wires up the environment so the gateway boots cleanly when the machine restarts.
42
+
macOS system services run in a stripped-down environment--keychain access, password managers, GUI interactions all behave differently than a normal terminal session. That wrapper script exists because of this. It handles secrets, patches third-party bugs at startup, and wires up everything the gateway needs to boot cleanly on restart.
43
43
44
44
## What it actually does
45
45
46
46
The skills fall into a few buckets.
47
47
48
-
On the smart home side: Nest thermostat control across two locations (a cabin and a city apartment), Hue lights, Samsung TV, Mr Cool minisplit AC through the Cielo Home API. I also built a climate dashboard--a single Python file serving Chart.js over Tailscale, fed by JSONL snapshots a cron job writes every 30 minutes.
48
+
On the smart home side: thermostat control across multiple locations, smart lights, and AC. I also built a climate dashboard--a lightweight web app served over a private network, fed by periodic snapshots.
49
49
50
-
For dining, it handles Resy and OpenTable search and booking. Monthly cron jobs automate date night: each month gets a cuisine rotation (Italian, then Mediterranean, then Spanish, etc.), the agent finds availability, books, creates a calendar event, and pings the group chat.
50
+
For dining, it handles restaurant search and booking. Recurring cron jobs automate date night: the agent finds availability, books, creates a calendar event, and pings the group chat. (My partner knows about and opted into all of this.)
51
51
52
-
Email triage runs against my fiancée's Gmail every morning at 7 AM. Unreads get bucketed into labels--Urgent, Action, Financial, Shopping, FYI. Urgent stuff gets starred with draft replies. An evening pass at 8 PM archives stale threads and flags unsubscribe candidates.
52
+
Email triage runs with consent against a shared family inbox. Unreads get sorted into categories--urgent, actionable, financial, shopping, informational. Urgent items get flagged with draft replies. A second pass later in the day archives stale threads and flags unsubscribe candidates.
53
53
54
-
Shopping goes through Amazon via browser automation against system Chrome. The agent finds and recommends products but won't place an order without explicit approval. This was one of the first skills where I spent more time on the restrictions than on the feature itself.
54
+
Shopping goes through browser automation. The agent finds and recommends products but won't place an order without explicit out-of-band approval. This was one of the first skills where I spent more time on the restrictions than on the feature itself.
55
55
56
-
Then there's the grab bag: Google Calendar, Apple Reminders, web search, URL and podcast summarization, and the [EchoNest](/blog/echonest-collaborative-music-queue) music queue.
56
+
Then there's the grab bag: calendar, reminders, web search, content summarization, and the [EchoNest](/blog/echonest-collaborative-music-queue) music queue.
57
57
58
58
## The hard parts
59
59
60
-
### 1Password and the LaunchAgent hang
60
+
### Secrets management in headless contexts
61
61
62
-
This one made me want to throw the Mac Mini out the window. `op read` hangs forever when called from a LaunchAgent on macOS Tahoe. The CLI daemon spawns, tries to reach the desktop app over Mach bootstrap, and just... blocks. No timeout. No error. Nothing.
63
-
64
-
I went through the whole checklist: service account tokens, disabling biometric unlock, isolated config directories, wrapping it in a background process with a kill timer. None of it worked. The Mach port connection fires before any env var gets checked, so you can't opt out from inside the daemon.
65
-
66
-
What I landed on: the gateway wrapper loads secrets from a cache file that gets populated over SSH. The agent itself can still call `op read` at runtime because it's running inside Node, not the LaunchAgent context. A refresh script keeps the cache current. It's two systems doing one job, which I don't love, but it works.
62
+
Getting password manager access working from a system service was the biggest headache. The CLI hangs when it can't reach the desktop app through the expected IPC channel--no timeout, no error. I ended up with a separate secrets pipeline that pre-loads what the agent needs at boot, backed by a dedicated service account with minimal permissions. Don't assume desktop tooling works headless. It won't.
67
63
68
64
### Browser auth persistence
69
65
70
-
The Amazon skill needs authenticated Chrome sessions. Headless Chrome on macOS crashes with `Trace/BPT trap` when it hits encrypted cookies via Keychain without a user present. So: separate user data directory, re-auth through visible Chrome when tokens rot, and full profile replacement when things get corrupted. Not pretty.
66
+
Browser automation on macOS crashes when it hits encrypted cookies without a desktop session present. Isolated browser profiles with their own auth state get around this, but token rotation and profile corruption mean it needs active maintenance. Worth budgeting real time for if you go this route.
71
67
72
-
### mDNS crashes on network changes
68
+
### Network instability and third-party bugs
73
69
74
-
`@homebridge/ciao` panics whenever a network interface changes, which Starlink does constantly. I wrote a monkey-patch that the gateway wrapper applies on every start. It survives OpenClaw updates. Not elegant, but it hasn't broken in months and I've stopped thinking about it.
70
+
Some dependencies panic on network interface changes, which satellite internet triggers constantly. I wrote patches that get reapplied on every restart. Not elegant, but stable for months. If you're running something 24/7 on variable connectivity, plan for it from day one.
75
71
76
72
## Cron jobs and state management
77
73
78
-
Cron definitions live in my dotfiles repo, but the gateway decorates them with runtime state--IDs, timestamps, execution history--that shouldn't be committed. A sync script strips the state when saving to dotfiles and merges it back on deploy. I can edit job configs in git, push, and have them picked up on the next gateway restart without clobbering execution history.
79
-
80
-
```bash
81
-
# Save to dotfiles (strip runtime state)
82
-
./sync-cron-jobs.sh dotfiles
83
-
84
-
# Deploy from dotfiles (merge with live state)
85
-
./sync-cron-jobs.sh gateway
86
-
```
74
+
Cron definitions live in version control, but the gateway decorates them with runtime state--IDs, timestamps, execution history--that shouldn't be committed. A sync script strips the state when saving and merges it back on deploy. I can edit job configs in git, push, and have them picked up on the next restart without clobbering execution history.
87
75
88
76
## Security boundaries
89
77
90
78
Before adding any skill, I asked: what's the worst thing this could do?
91
79
92
-
1Password access is read-only, scoped to a dedicated vault. No access to personal vaults, can't create or modify items. Shopping requires explicit human approval for every purchase--no subscriptions, no bypassing CAPTCHA or 2FA. iMessage is locked to allowlisted group chats and authorized senders; payment details and other sensitive data never appear in messages. Email runs auth health checks before sending anything, and token expiry gets surfaced instead of failing silently.
80
+
Every integration gets its own service account with the minimum permissions it needs. Read-only where possible. Anything involving money or personal data goes through a separate approval channel--the agent can recommend, but a human confirms. Messaging is locked to allowlisted contacts. Auth checks run before any outbound action, and token problems get surfaced instead of swallowed.
93
81
94
-
## What I'd do differently
82
+
I also run a weekly activity report that flags unexpected auth failures, unusual request patterns, and skills that haven't run when they should have. Detection matters as much as prevention.
95
83
96
-
I ran Haiku 4.5 for the first few months, then upgraded to Sonnet 4.6 in February. The jump in multi-step reasoning--restaurant bookings that require comparing three options, email triage that actually understands context--was immediately noticeable. I should have started with the stronger model and dialed down if costs were a problem.
84
+
## What I'd do differently
97
85
98
-
The file-based keyring for Gmail OAuth (`gog` CLI with `GOG_KEYRING_PASSWORD`) works but feels held together with tape. A proper headless OAuth flow would have been worth the upfront investment instead of patching around macOS keychain quirks.
86
+
I started with a smaller model and upgraded after a few months. The jump in multi-step reasoning was immediately noticeable. I should have started with the stronger model and dialed down if costs were a problem.
99
87
100
-
The patch system for third-party bugs does its job, but auditing is manual. When a dependency updates, I have to check whether the diff still applies. Some kind of version-pinned patch verification would save me from finding out the hard way.
88
+
Headless OAuth is worth the upfront investment. Patching around macOS keychain quirks in a system service context gets fragile fast. Same goes for dependency patching--some kind of version-pinned verification would save time over manual auditing.
101
89
102
90
## The boring part
103
91
104
-
The most useful thing about OpenClaw isn't any single skill. It's that the plumbing is boring enough to forget about. The Mac Mini boots, the LaunchAgent fires, secrets load, patches apply, 27 skills come online. Date nights get booked. Email gets sorted. The thermostat does its thing. A weekly cron job sends me an activity report so I catch errors before they catch me.
92
+
After a few months, the whole thing just runs. The machine boots, the service starts, secrets load, patches apply, skills come online. Recurring tasks do their thing. The weekly report tells me if anything is off.
105
93
106
-
Most of the engineering here wasn't AI work. It was macOS daemon behavior, browser automation nonsense, and secrets management. Handing Claude a bag of tools and watching it figure out how to use them was the easy part. Getting comfortable enough to stop checking on it every hour took longer.
94
+
Most of the engineering here wasn't AI work. It was system service behavior, browser automation, and secrets management. Handing Claude a bag of tools and watching it figure out how to use them was the easy part. Getting comfortable enough to stop checking on it every hour took longer.
0 commit comments