Local-first agent-to-agent gateway
Private, reliable connections between agents.
Akson lets independently operated agents hand each other real work. Every task is a signed contract a human approves, every result is verifiable byte by byte — and the work a peer sends you runs with no network, no credentials, and nothing of yours.
alice $ akson task send review.json
sent to bob: task-cb5de8f2…
bob $ akson task show task-cb5de8f2…
Approve alice to run "code-review/v1": 1 input (12 B) goes to
the worker; up to 8192 B come back to the request origin.
bob $ akson task approve task-cb5de8f2…
bob $ akson task run task-cb5de8f2… sandboxed. no network.
bob $ akson task deliver task-cb5de8f2… signed.
alice $ akson task output task-cb5de8f2… --role response
reviewed: LGTM ← digest-verified
One loop
Two people exchange a public identity token once, over any channel they already trust, and each imports the other's under a name they choose. From then on their agents delegate work directly — no broker in the middle, no shared API key.
Two ideas carry the design. First, arrival is not execution: a task showing up in your inbox never starts a model, never touches your files, never fetches a URL — it waits for your decision. Second, a peer's work runs in its own reduced-authority domain, and that domain is enforced by the kernel, not by convention.
A peer's commands run in a separate, enforced, reduced-authority domain. The agent's own user-granted authority is never touched.
the one core principle · held by everything below · tracked honestly in the threat model
What the daemon enforces
Not aspirations — behaviour of the running code, each grounded in the threat model and the normative design.
Direct and local-first
Two endpoints pair with no hosted account and no relay, over mutually authenticated TLS 1.3 — each commits to the other's identity root out of band (a public token) and pins the certificate the introduction binds to it, not by CA, not by DNS.
Arrival is not execution
Receiving a message, task, or artifact never starts a model, mints authority, touches a workspace, invokes a tool, or fetches a URL. The receive path holds a database handle and nothing else — it cannot act. A standing auto-approval you configured acts separately, after arrival, and can never widen a grant.
Zero ambient authority
Peer work starts in fresh user, mount, pid, and network namespaces with default-deny seccomp and cgroup limits — plus Landlock where the kernel supports it. A prompt-injected task has no socket, no workspace, and no home to reach.
Sealed model access
socket() and connect() are denied. A model is reachable
only through the broker, which injects the credential and enforces an egress
allowlist and a per-order operation budget. The API key never enters the worker.
One process, no children
A production adapter runs as a single process that cannot create another — no
fork, clone, or vfork. Even a shell reached
via execve cannot spawn a command.
A human approves the exact contract
One risk card, one decision, one one-shot work order. The outward-disclosing grants — reaching a model, exporting an artifact — are never automatic, and a standing policy can never widen them.
Verifiable outcomes
Results are signed (DSSE), findings are standard (SARIF), and the requester
re-hashes every output the signed manifest names before recording anything. Crash
recovery marks the uncertain ambiguous — never done.
Inert, bounded, fail-closed
Rendered artifacts are refused if they carry scripts, event handlers, or external fetches. Parsing is capped I-JSON that fails closed at every gate, backed by fuzz and hostile-input suites. The store is envelope-encrypted at rest.
Akson runs end to end today, but key custody is interim and a few residual risks remain open — the threat model names each one rather than rounding them away. Use it to explore and build against; don't protect anything that matters with it yet.
Letting another system drive — without giving it admin
A sibling system on your own machine may need to send payloads out through akson. It should not hold akson's operator authority to do it. So there is a third control socket, with its own Unix identity, and it does not exist unless you create it.
No variable, no socket
With AKSON_COORD_UID unset, coord.sock is not created at
all — absent rather than guarded. An endpoint that was never mounted cannot be
probed. Set it, and admission is that one UID (or the daemon's own, for
diagnostics), checked before the request line is read.
eight operations, and no others
The registry is the whole surface: no approve or deny, no pairing, no peer import, no processor or credential op, no configuration. A compromised driver can stage inert bytes and burn receipts it was already given — the rest is not unauthorized, it is unaddressable.
A human still decides
Dispatch requires a one-shot consent receipt it cannot create. Minting one is an admin operation that shows the operator the risk card for that exact staged digest first — so the outward disclosure is never automatic, and never the driver's to authorize.
Spent, committed, carried
The receipt's spend, the dispatch record, and the event commit in one transaction — under a compare-and-set and a uniqueness constraint. A retry under the same execution key re-carries byte-identical bytes and spends nothing; a different key on a spent receipt is refused.
The dispatch envelope is unsigned, deliberately: its authenticity is the pinned mutual-TLS channel's and its integrity is a digest chain, so a coordination dispatch is authenticated, not non-repudiable. The receiver verifies and acknowledges but does not retain the payload. And admission is a Unix UID, not an attested process identity — the assurance profile here is a developer one, with no UID separation in the default profile at all.
Checked by machines, from two sides
The security rules above are not only prose. Formal models are explored exhaustively — two of them proved for any run length — the code is held to the models in CI, and an independent implementation re-derives every byte the spec pins down.
Seven TLA+ models
Task lifecycle, contract chain, receive pipeline, the token introduction, broker budget, a rollback adversary, and liveness — explored over crashes at every commit point, endless replays, and hostile deliveries.
Inductive proofs
Apalache discharges inductive invariants for the token introduction and the rollback adversary — properties that hold after any number of steps, not just within a bounded run.
Conformance in CI
A test suite asserts, for every (state, event) pair, that the Rust transition
functions equal the TLA+ relations. cargo test fails when the code
drifts from the transcribed relations.
An independent second opinion
Every golden vector — canonical bytes, digests, signatures — is re-derived in CI by a Python implementation that shares no code with the workspace. It has already caught a real canonicalization bug.
Documentation
Guide
From hello world to real models: install, pair two endpoints, delegate a task, read a verified result — then drive it all from Claude Code or Codex.
guide → technicalInternals
The architecture: the receive pipeline, the two permission domains, the sandbox layer by layer, the processor broker, evidence, and the wire.
internals → the third socketCoordination
How a different local principal stages, consents, and dispatches: the registry, the unsigned envelope, the receiver's four checks, the egress states — and the limits, beside what each one bounds.
coordination → assuranceProofs
The TLA+ models and their invariants, the conformance harness that pins them to the code, the independent cross-checker, and the stated limits.
proofs → provenanceRelease
Which version this site documents, what its prerelease marking actually enforces, and how to verify an asset — including what each check does not establish.
release →Deeper still, in the repository: the normative design, the threat model, the control protocol, the ADRs, and SECURITY.md.