agentcookie
Tool explainer · MIT · v0.17.1

agentcookie,
explained.

Log in on ONE machine. Every other machine's agents wake up already authenticated. Cookies and API keys, encrypted over your Tailscale tailnet.

One catch, and it is a big one: it only functions on macOS.

SOURCE
you log in here
AES-256-GCM
over Tailscale
SINK
agents run here
LANE 1 · cookies
needs the macOS Keychain
LANE 2 · secrets bus
plain files, works anywhere

What actually runs where (measured, not guessed)

SubcommandWindowsmacOSWhat it is for
secret set / list / env✓ works✓ worksthe secrets bus
discover✓ works✓ worksfind CLIs to adopt
status✓ works✓ worksconfig + daemon state
cookies✓ works✓ worksread the local sidecar
source / sink✕ dead✓ worksship cookies box to box
agent-sync✕ dead✓ worksowned Chrome on a CDP port
export✕ dead✓ worksdump plaintext cookies

Windows and Linux builds install cleanly and pass doctor. That is not the same as working. Everything in the dead column fails at the same place: the macOS Keychain call.

1 · The ProblemWhy this tool exists

Your agents are logged out, and you are the login

Your agents are logged out, and you are the login

You log in on your main machine. Then an agent on the Mac, or a VPS, tries to open the same page and hits a login wall. So you log in again over there. Then the session expires and you do it a third time. Every account, every box, forever. agentcookie's whole pitch: log in once, on one machine, and every agent machine wakes up already you.

  • BEFORE: log in on box 1, log in again on box 2, repeat when it expires.
  • AFTER: log in once on the source. The sink inherits the session.
  • It carries API keys and CLI bearer tokens on the same channel.
  • github.com/mvanhorn/agentcookie, MIT, v0.17.1, actively developed.
The point is not convenience. It is that an agent on another box can act as you without you babysitting a login.
2 · How It WorksSource, wire, sink

One wire, two lanes that behave differently

One wire, two lanes that behave differently

There are exactly two machine roles. The SOURCE is where you sit and log in interactively. The SINK is where your agents run. Between them runs one authenticated channel: AES-256-GCM, keys derived from a one-time pairing code, carried over your Tailscale tailnet. Two different payloads ride that wire, and confusing them is the fastest way to misunderstand this tool.

  • LANE 1, COOKIES: read from real Chrome on the source, upserted into Chrome on the sink. Needs the OS keychain. This is the macOS-only lane.
  • LANE 2, SECRETS BUS: per-CLI env vars and bearer tokens in plain files under ~/.agentcookie/secrets/<cli>/. No keychain involved. Works everywhere.
  • Pairing is X25519 + HKDF, one-time code, per-peer keys.
  • Roles: `agentcookie source` pushes, `agentcookie sink` listens.
Remember this split. Lane 1 is why Windows is dead. Lane 2 is why Windows is still useful.
3 · The Platform TruthRead this before you plan anything around it

It builds anywhere. It only FUNCTIONS on macOS.

It builds anywhere. It only FUNCTIONS on macOS.

The binary cross-compiles cleanly to Windows and Linux. It installs. `doctor` comes back green. And then it reads exactly zero cookies, forever. agentcookie shells out to `security`, the macOS Keychain CLI, to get Chrome's Safe Storage decrypt key. There is no Windows DPAPI path and no Linux equivalent in the source. The README said macOS-only on line 239 and it was telling the truth.

  • A successful build is NOT evidence a tool works.
  • `doctor` passed on Windows because it never touches the Keychain.
  • DEAD on Windows: source, sink, agent-sync, export.
  • ALIVE on Windows: secret, discover, status, cookies.
Fleet status: runs on michaels-mac-studio. Binary present but non-functional on this Windows box, vps2, vps3. Deliberately NOT on the Hetzner box, which is compromised.
Windows · verbatim errorWhat agent-sync actually returns on this box
agentcookie: read Chrome Safe Storage from Keychain (did you grant access?):
exec: "security": executable file not found in %PATH%
macOS · one step furtherSame tool on the Mac, before the Keychain grant
exit status 36

# fix:
agentcookie wizard set-keychain-access
# (prompts for the Mac login password)
4 · Use It TodayThe lane that is not blocked

The secrets bus works on Windows right now

The secrets bus works on Windows right now

Lane 2 never touches the Keychain, so it runs here today. You register a CLI, drop its env vars in, and any consumer on any paired machine can pull them into its shell with one eval. It is a small, boring, useful thing: one place your CLI tokens live, synced instead of copy-pasted between boxes.

  • Each CLI gets its own folder: ~/.agentcookie/secrets/<cli>/secrets.env
  • `secret set` reads the value from stdin or prompts. It never takes it as an argument.
  • `secret list` shows CLIs and key NAMES only, never values.
  • Also available: get, rm, alias, import-from, revoke.
These write PLAINTEXT to disk. That is the design. Only put keys here that you accept living unencrypted on every paired machine.
Windows · works1. Register a key (prompts, or pipe the value in)
agentcookie secret set my-cli MY_CLI_BEARER
Windows · works2. See what is in the bus (names only, no values)
agentcookie secret list
Windows · works3. Load a CLI's keys into the current shell
eval $(agentcookie secret env my-cli)
Windows · worksSee what the discovery engine found on this box
agentcookie discover
agentcookie status
5 · One-Machine ModesYou do not need two boxes

agent-sync and cmux-sync: same trick, no second machine

agent-sync and cmux-sync: same trick, no second machine

The two-machine story is not the only story. `agent-sync` runs an owned Chrome on ONE machine, kept logged in from your real Chrome, and exposes it on a CDP port that agent browsers attach to. Your agents drive a browser that is already you, on the box you are sitting at. `cmux-sync` is the same local loop pointed at cmux's browser instead.

  • agent-sync: owned Chrome on a CDP port, agent browsers connect in.
  • cmux-sync: local loop into the cmux browser's separate cookie jar.
  • Both still read real Chrome, so both are still macOS-only.
  • cmux is an unrelated third-party product, https://cmux.com. Opt-in surface only.
This is the capability worth wanting: agents that act as you, already logged in, without a second machine in the loop.
6 · The Honest CaveatsWhat it cannot do, and what it costs

Google DBSC cookies do not transfer. And it writes plaintext.

Google DBSC cookies do not transfer. And it writes plaintext.

The tool documents its own biggest hole, so believe it. Google's Device Bound Session Credentials tie a session to a key held in the SOURCE machine's Secure Enclave. The sink cannot sign the refresh challenge, so the copied cookie dies on first refresh. agentcookie flags those cookies, and `--skip-dbsc-suspect` drops them instead of shipping sessions that will break.

  • Google DBSC-bound cookies do NOT survive the copy. Not a bug, physics.
  • --skip-dbsc-suspect drops them rather than shipping dead sessions.
  • Plaintext on disk: ~/.agentcookie/cookies-plain.db and secrets/<cli>/secrets.env
  • Default cookie policy is sync-all with NO blocklist. Set a policy before the first wizard run.
  • A go-install build is ad-hoc signed on macOS, so it re-prompts for the login password every run. Use the notarized release for unattended work.
  • Not configured anywhere yet. Every host reports the same FAIL: no source.yaml or sink.yaml.
Any sink is a machine that will hold a full copy of every credential you own. Pick it like that is true, because it is.

The bottom line

On the Mac

The real capability lives here. Cookie sync, agent-sync, all of it. Still needs a Keychain grant and a cookie policy before the first wizard run.

On Windows

The cookie half is dead and is not coming back without an upstream DPAPI path. Use the secrets bus, and do not plan any workflow around cookie sync from this box.

Before you configure it

Any sink holds a full plaintext copy of every credential you own. Default policy is sync-all with no blocklist. Set the policy first.