GLASS ATLAS SINGLE AUTHOR · NOTES PUBLISHED

devops

Building Myself a Persistent Agent (On Paper, For Now)

#self-hosting#agents#tailscale#security#hermes-agent#homelab#digitalocean

The plan for a personal always-on agent already has its two hardest calls answered: how it's reachable, and how far it's allowed to reach back.

The problem is hardware, not software

I want a personal agent that's actually on all the time. Something that manages my calendar, fires notifications on a schedule, and doesn't need me to open a laptop and start a session for any of that to happen. The thing stopping me isn't the software. It's that I don't own a machine that's plugged in and running 24/7.

So I've been sketching out the alternative: don't wait for spare hardware, just rent a box that's already always on. Here's the shape of that plan, the two decisions in it I actually think are interesting, and the one part I'm deliberately not building yet.

Nothing below is running. This is the design before the build, written down because the design is the part worth thinking out loud about.

System diagram of the planned Hermes Agent setup: a DigitalOcean droplet running Hermes in a Docker sandbox inside a Tailscale private mesh with two personal machines, outbound-only connections to Discord, Google Calendar, and the Codex/ChatGPT subscription, and a separate greyed-out speculative remote-dev-agent idea.
The whole plan in one picture: droplet plus Docker sandbox, a Tailscale mesh instead of a public port, outbound-only service calls, and the remote-dev-agent idea kept separate and unbuilt.

What I actually want it to do

Keep the scope narrow on purpose: read and write my calendar (create events, move them, update them), send me notifications, and run recurring jobs on a cron schedule so it can check in and nudge me without being asked. That's it. No browser automation, no local model, no ambitious "do my job for me" scope creep. A simple assistant to improve productivity.

The agent I'm building this around is Hermes Agent. From what I've read of its docs, it has three faces: a terminal UI you can drive directly, a "gateway" mode that lets you talk to it over Discord/Telegram/Slack/etc., and a dashboard for configuring tools, skills, and a built-in cron scheduler. Calendar and cron are apparently kept conceptually separate in it too, which matches how I'd want to use it anyway: calendar is for events that involve other humans, cron is for the agent's own recurring busywork. I like that split enough that it shaped my scope above rather than the other way around.

Hosting it somewhere that isn't my desk

No spare always-on hardware, so the plan is a small DigitalOcean droplet. I picked DigitalOcean mostly because their droplets are dead simple to spin up and reason about, not because of anything Hermes-specific. As far as I can tell from the deployment docs, Hermes without browser tools is genuinely light, something like 1 vCPU and a couple gigs of RAM is plenty as long as it's talking to a remote LLM API instead of running a model locally. That's a cheap droplet, on the order of what a decent coffee habit costs per month, which is the right price point for something that's basically going to sit there refreshing my calendar.

The deploy path I'm planning to follow looks roughly like this, going by the Docker instructions in the docs:

BASH
# one-time interactive setup, writes config into a mounted volume
mkdir -p ~/.hermes
docker run -it --rm -v ~/.hermes:/opt/data nousresearch/hermes-agent setup

# the actual always-on run
docker run -d --name hermes --restart unless-stopped \
  -v ~/.hermes:/opt/data -p 8642:8642 \
  nousresearch/hermes-agent gateway run

Docker's own --restart unless-stopped handles crashes and reboots reasonably well by itself, but I'd still wrap the container in a proper systemd unit so I have a normal systemctl status hermes to check instead of squinting at docker ps. Belt and suspenders, for something I want to trust to actually be there when it says it will be.

Paying with a subscription I already have

The part of this I'm most pleased with is the model bill. I already pay for a Codex subscription, and apparently Hermes supports OAuth device-code login against that instead of requiring a separate API key billed per token. If that holds up the way the docs describe it, the marginal cost of running this thing is just the droplet, a few dollars a month, with zero additional spend on the actual intelligence behind it.

The infrastructure is cheap. The point of using a subscription I already pay for is that the marginal cost of running an always-on agent should be close to zero, not "cheap plus another API bill I forget about until it's $40."

The exposure problem: proxy or private network

Here's the first decision I think is actually worth explaining rather than just listing. I want the Hermes dashboard reachable from outside the droplet, not just over SSH tunnel, because I want to check on it from my phone or my laptop without ceremony. The obvious way to do that is a reverse proxy with TLS and basic auth sitting in front of the dashboard port, which is the standard "put a website on the internet" move.

But thinking it through, that's solving the wrong problem. I don't need the dashboard reachable from anywhere, I need it reachable from my machines. That's exactly what Tailscale is for: join the droplet and my two personal machines into one private mesh network, and bind the dashboard to the droplet's Tailscale address instead of a public port. Discord notifications don't need any inbound connection either, since the bot side of that is an outbound websocket to Discord's servers, not something listening for incoming traffic. Put those two facts together and the droplet ends up with no public inbound ports at all, while still being reachable from wherever I actually am.

Same reachability I originally wanted, smaller attack surface, one less TLS certificate to think about renewing. I'd still leave basic auth on inside the tailnet, because "it's on a private network" is a good second layer, not a reason to drop the first one.

Keeping it on a leash

The second decision matters more, because this thing has write access to my calendar and a channel to message me, and I don't want to find out the hard way what it does when it's uncertain. "Sandboxing" here means two separate things and I want both.

First, how it executes anything: from what the docs describe, Hermes can run agent commands inside an isolated Docker backend rather than directly on the host, with dropped capabilities and no privilege escalation. That's the difference between the agent messing something up inside its own throwaway box and the agent messing something up on a machine I actually depend on.

Second, how much it can do without asking. Hermes apparently ships an approval system with real modes, manual, smart, or fully off, and tools are supposedly bucketed into risk tiers from read-only up through destructive. My plan is manual or smart approval, never the "off" mode, with calendar writes and Discord messages sitting low-risk enough to go through on their own, and anything shell- or filesystem-adjacent needing an explicit yes from me. If the docs are accurate about a website blocklist and stripped environment variables for anything it executes, that's two more small locks on a door I'd rather not leave open.

None of this is exotic. It's the same instinct as least-privilege anywhere else: the agent gets exactly the reach its job requires, and not the reach I could give it because the box happens to support it.

The idea I'm not ready to build yet

This is the part I want to be honest about instead of quietly leaving out, because it's the most interesting thing about this whole plan and also the part that directly argues with everything in the last section.

That Tailscale mesh connecting the droplet to my two personal machines could do more than carry dashboard traffic. If the agent's execution reach extended into those machines too, I could message Hermes on Discord with a feature idea and have it actually run a pipeline against a real dev environment, on hardware that isn't a throwaway droplet. That's a genuinely different agent: not a calendar assistant, a remote development agent I can direct from my phone.

I'm not building that yet, and I want to be specific about why. Everything in the sandboxing section above exists to keep the agent's blast radius confined to a disposable droplet. Wiring its execution reach into my actual daily machines throws that constraint out entirely. If I ever do pursue this, it needs its own, stricter story, Tailscale ACLs that scope exactly which node and which ports are reachable at minimum, and probably a completely separate, more locked-down execution path than whatever I'm running for the calendar-and-notifications version. It's not a "coming soon" feature. It's a direction I think is feasible and will likely chase eventually, once the boring version has been running long enough that I trust it.

For now: cheap droplet, private network instead of a public one, a leash instead of free rein. That's the version I'm actually going to build.