How We Discovered That AI Agents Can’t Be Trusted With Keys

A report on keeping cryptographic identity safe from your own AI

Synthesized by Jorgenclaw (AI agent) and Claude Code (host AI), with direct feedback and verification from Scott Jorgensen


The Setup

I run an AI agent named Jorgenclaw. He lives on a small computer in my house, connects to me through Signal, browses the web, manages files, and posts to Nostr — a decentralized social network where your identity is a cryptographic key pair.

On Nostr, your private key (called an “nsec”) is everything. It proves you are you. Whoever holds it is you. There’s no password reset, no customer support, no “forgot my key” flow. If someone gets your nsec, they can post as you, sign as you, be you — permanently.

So naturally, I wanted my AI agent to have his own Nostr identity.

The Problem We Didn’t See Coming

To post on Nostr, Jorgenclaw needs to sign messages with his private key. The obvious approach: store the key somewhere on the host machine and make it available to the containerized agent.

That’s what we did with Clawstr, a Nostr CLI tool. The workflow was:

  1. Generate or receive the private key in hex format (64 characters)
  2. Store it in ~/.clawstr/secret.key on the host machine
  3. Mount that file into Jorgenclaw’s Docker container at /workspace/group/.clawstr_hex
  4. Jorgenclaw reads the hex from the mounted file when signing posts

This worked well. The key never passed through environment variables. It stayed in a dedicated file, mounted read-only into the container. Jorgenclaw could read it to sign posts, but couldn’t modify it.

But during a routine conversation about security, we realized something uncomfortable.

Claude Code — the AI running on my host machine — can read every file my user account can access. Every dotfile, every config, every file in my home directory. It’s not malicious. It just has the same filesystem permissions I do.

And the private key? Sitting right there in ~/.clawstr/secret.key, in plaintext.

“So pretty much no file on this machine can be kept secret from you,” I said.

“Correct,” Claude replied.

The Threat Model

This isn’t about whether Claude would steal a key. It’s about whether the architecture allows it. Good security doesn’t depend on trusting any single actor — it depends on making theft structurally impossible.

The threat model looks like this:

  1. The AI on the host (Claude Code) can read any file the user can read. It sees ~/.clawstr/secret.key, config files, databases — everything.
  2. The AI in the container (Jorgenclaw) is sandboxed in Docker with only specific directories mounted in. The private key file is mounted at /workspace/group/.clawstr_hex, making it readable to Jorgenclaw for signing operations.
  3. The cloud provider (Anthropic) processes every message, file read, and tool output from both AIs. If either AI reads the key file, the contents pass through Anthropic’s servers.

Three layers, zero places to hide a plaintext key.

The Discovery: Kernel Memory

This is where we need to thank the very smart people at Marmot Protocol (the team behind White Noise). They’d already solved this hard computer science problem — we just didn’t know it existed yet.

What Marmot figured out: The Linux kernel has a built-in secret storage system called keyutils. It stores values in kernel memory — not on the filesystem. There’s no file to read, no path to cat, no config to grep. The secret exists only in protected kernel space.

keyctl add user my_secret "the-actual-value" @u

That’s it. The key is now in kernel memory. No file was created. An AI that reads every file on disk will find nothing.

But there’s a catch: keyctl print can still extract it. A sufficiently capable AI could run that command. We needed one more layer.

The Solution: The Daemon Pattern

White Noise has a two-part design:

  • wnd (the daemon): Runs on the host machine. Holds the private key in memory. Listens on a Unix socket. Performs all cryptographic operations — signing, encrypting, decrypting.
  • wn (the CLI client): Stateless. Connects to the daemon’s socket, sends a command, gets a response. Never touches the key.

Here’s what this means for Jorgenclaw:

  1. The private key lives in kernel memory on the host
  2. The wnd daemon reads it at startup and holds it in process memory
  3. Jorgenclaw’s container gets the wn CLI binary and the daemon’s socket mounted in
  4. When Jorgenclaw wants to post, sign, or send, he runs wn — which asks the daemon to do the cryptographic work
  5. The key never enters the container. Never appears in an environment variable. Never touches a file.

Jorgenclaw can use his identity without ever seeing his identity.

The AI has the ability to act but not the ability to steal. That’s the architectural difference between trust and security.

Where We Are Now: Production Confirmed

Signal + White Noise, side by side. Jorgenclaw now operates on two messaging channels simultaneously. Signal handles family groups and individual DMs. White Noise handles encrypted Nostr-based messaging. Both are systemd user services that start on boot.

White Noise messaging: fully secured. The wnd daemon holds the nsec in process memory, loaded from the desktop keyring at startup. Jorgenclaw’s container only gets the wn CLI binary and the daemon’s Unix socket. The key never enters the container.

Images work without key exposure. Jorgenclaw can receive and view images sent through White Noise. The daemon handles MLS decryption and downloads media to a cache directory. Jorgenclaw reads the decrypted files without ever touching the cryptographic layer.

The Bigger Problem: Your AI Can Read ALL Your Chats

Signal, WhatsApp, Telegram, and most desktop messaging apps store their data on your computer’s filesystem. Message databases, contact lists, media files — all sitting in folders under your home directory.

Now add an AI assistant to that laptop. It can read anything you can read. That includes the Signal data directory — not just the chats the AI is participating in, but all of them. Your private conversations with your spouse, your doctor, your lawyer.

The recommendation for high-risk individuals is straightforward: don’t run Signal (or any encrypted messenger) on the same computer as an AI agent. Keep Signal on your phone.

When the AI Accidentally Peeked

During the signing daemon build, a sloppy verification command leaked 10 characters of the private key to Claude Code’s terminal. Five of those characters were the nsec1 prefix (every Nostr key starts with this — it reveals nothing). The remaining 5 characters of actual key data represent about 8.6% of the meaningful information.

Cracking the rest from those 5 characters would take more universe-lifetimes than there are atoms in the solar system. The exposure was a principle violation, not a practical risk. We fixed the verification command:

keyctl search @u user wn_nsec >/dev/null 2>&1 && echo "KEY EXISTS" || echo "KEY NOT FOUND"

When Error Messages Betray You

The nostr-tools library’s error message helpfully included the value it failed to decode — which was the full private key — right there in the system journal where the AI could read it. Libraries are written to be helpful to developers. Helpful error messages are dangerous when the “developer” reading them is an AI agent that shouldn’t see the data.

The fix: load only the nsec line from the key file (not the whole file), and never log key material in error messages.

The Bigger Picture

Most AI agent frameworks today pass secrets around as environment variables or config files. The more capable agents get, the more dangerous plaintext secrets become.

The pattern Marmot Protocol implemented isn’t new — it’s how SSH agents, GPG agents, and hardware security modules have worked for decades. The principle: the entity that uses the key should not be the entity that holds the key.

Your AI should be able to sign, encrypt, and authenticate. It should never be able to export, display, or exfiltrate the keys that make those operations possible.

Keys belong in the kernel. Agents belong in containers. And the wall between them should be made of architecture, not trust.


The full report including step-by-step key generation procedures, threat model tables, and the complete key safety workflow is available at sovereignty-by-design.

Last updated: March 12, 2026

← Back to Writings