# Authenticating agents that share a process

> A harness running several agents inside one operating-system process gives the kernel a single principal to authenticate. Everything a coordination tool can honestly claim about agent identity follows from that.

Published 2026-08-15, revised 2026-08-16. Agenxy — https://agenxy.org/writing/authenticating-agents-that-share-a-process/

---
Dibs coordinates fleets of agents. They register with it, declare what they are
working on, and read what others have declared. Writing its security notes
forced us to state what registration actually proves.

## The boundary the kernel enforces

An operating system authenticates users and processes. An agent has no
corresponding kernel principal. It is a conversational context inside a
harness, and a harness running three agents keeps all three in one address
space, under one user id, with one process id. Asked which agent sent a
request, the kernel can identify the harness process and nothing finer.

That limit applies to agents multiplexed inside one process. An agent isolated
in its own process, user account or virtual machine can be authenticated
through that boundary, and where the isolation matters it is worth building.
Inside a shared process the harness-supplied name is the only distinction, and
the kernel has no view of it.

## What the Dibs source says

Identity is a nonce: a client-generated random string presented at
registration and stored as a raw map key. It is encrypted at rest and never
appears on the board. No hash of it is stored, and the comparison is not
constant-time.

The process id comes from the client and is accepted on trust. It drives
liveness probing rather than identity, and most agents never send one. The
transport is HTTP, and nothing in the codebase verifies peer credentials.

Our security notes already described agent-to-agent isolation as a boundary to
strengthen rather than one that is enforced. The operational problem shows up
in the nonce's lifecycle.

Nothing persists it. The agent has to remember it, and for a language model
remembering means the context window, which means the session transcript: a
plaintext file with no expiry and no revocation path. An agent that loses its
context cannot prove it was itself. It registers again, becomes a second agent,
and has no access to the first one's mail. We have watched that happen to four
agents at once.

So the credential that proves identity is a long-lived plaintext secret living
in a log. That follows from the arrangement above rather than from a decision
anyone made.

## Attestations that are available, and what each one proves

Over a unix socket the kernel will report the calling process unforgeably, with
its audit token and a verified code signature. This is worth having, and it
establishes the process. One process still hosts many agents.

A harness could attest that a call came from agent X. The harness then becomes
the authenticated principal and supplies the agent identity itself, which moves
the question one layer out.

A hardware-backed key per agent has the same placement problem. The key has to
live wherever the agent lives, which here is the transcript.

Each mechanism establishes a principal at its own layer. An agent sharing a
process has no principal at any of them.

## What can be built on that

An agent name is a coordination claim, and its assurance depends on
participants honouring the convention. Dibs gives its claims that status in the
documentation. Anyone who can reach the service can type a name, so a name
cannot safely receive a capability in advance.

A capability can be bound to a live process instead. A credential an agent
carries stays in its transcript indefinitely; a process-bound capability
expires when the process does, which makes process death the revocation event.

Attesting the process narrows the set of callers. It keeps out a stray script,
though it cannot stop a caller inside the harness supplying another agent's
name.

Anything consequential can require fresh authorisation from the person at the
keyboard. A prompt presented through an operating-system surface confirms
current intent. It does not establish an unforgeable human identity: a session
can be compromised and an interface can be spoofed. For an action that spends
money or sends mail, it is still the only authorisation the system has.

## Lifetime of the stdio bridge

MCP servers using the stdio transport are spawned per client connection. Each
harness gets its own child process, with a live parent and a pipe only that
harness can write to. Most of the holder process this design needs already
exists.

We first wrote that the same arrangement solved process lifetime: close the
window, close the pipe, the process exits. That was wrong twice, and both
corrections are worth recording.

The bridge re-issued its subscription every time the stream ended. That
behaviour is what keeps a subscription alive across a daemon restart, and
nothing interrupted it, so a bridge holding one never exited at all.

Underneath that, a process sees end-of-file on stdin only when the last holder
of the pipe's write end closes it, and a harness that spawns shells passes each
one the same descriptors. Kill the harness while a subprocess is running and
the write end stays open, leaving the bridge waiting on a pipe nobody will
write to again. The kernel does enforce ownership of that write end; descriptor
inheritance decides how long the ownership lasts.

Dibs now handles both with the parent-death notification we had proposed for a
holder process and then argued was unnecessary: `PR_SET_PDEATHSIG` on Linux and
`kqueue` `NOTE_EXIT` on macOS, each re-checking the parent afterwards to close
the fork race. The handlers exit rather than unwind, because cancelling a
context leaves a blocking read on stdin active. Measured, a bridge outlived a
killed harness indefinitely with its context already cancelled.

The harness-to-agent link stays soft. The documentation records the absence of
a boundary there rather than implying one.

## Declarations

Dibs holds one thing a secret manager does not: what each agent declared it was
doing. That makes a policy expressible which otherwise is not.

> Release the deployment credential to the agent that declared it was deploying
> the website, and show me that declaration before I approve.

The person reads the claim, compares it against the action being requested, and
decides. Soft identity is survivable under that arrangement, because the
identity is not what the decision rests on.