English | 简体中文
Website · Documentation · Protocol · Security · Contributing
Anet is private, encrypted store-and-forward infrastructure for agent and human edge nodes. Nodes own their identities, establish trust by explicitly exchanging and pinning signed Peer Cards, and move the same immutable encrypted packets over whichever path is currently available.
Anet does not depend on Discord, Telegram, a domain name, a platform account, or a central message server. A packet can travel over a direct TLS connection, through an opaque carrier or Ahub, or inside an offline bundle without changing its end-to-end security model.
Anet is under active development. The current release is
v0.12.1.
For a new Windows device, the recommended path is one PowerShell command. It downloads the deployment entry point, creates one private node, installs the runtime, registers the auto-start task, and starts the supervisor plus its anet serve child. The supervisor then polls the control page and can apply software, default configuration, Peer Cards, and nested pages/kv sources.
The control page must provide software.version and an initial software.wheel_url. Add software.sha256 for a pinned package hash and software.repo_url so a downloaded entry point can fetch matching helper scripts and later source updates. See docs/windows-control-page.example.json and docs/WINDOWS_AUTOSTART.md.
Run this in an ordinary PowerShell window for a current-user installation:
& ([scriptblock]::Create((Invoke-RestMethod https://raw.githubusercontent.com/yunlux/Anet/main/scripts/install_windows_oneclick.ps1))) -ControlUrl https://example.invalid/anet/control.jsonFor a machine-wide installation that starts at Windows boot, open PowerShell with Run as administrator and add -Admin:
& ([scriptblock]::Create((Invoke-RestMethod https://raw.githubusercontent.com/yunlux/Anet/main/scripts/install_windows_oneclick.ps1))) -Admin -ControlUrl https://example.invalid/anet/control.jsonCurrent-user mode uses %LOCALAPPDATA%/Anet and an AtLogOn task. Administrator mode uses %ProgramData%/Anet, the SYSTEM principal, and an AtStartup task. Both modes run a bounded duplicate preflight first; a known existing Anet/Ahub runtime, service, task, or process stops the install instead of silently creating a second deployment. Use -AllowExisting only when a second explicit deployment is intended.
The same deployment model is available on the other platforms. Run these entry points from an Anet checkout (the Windows command above is the only checkout-free entry point):
# WSL
python3 scripts/install_wsl_oneclick.py --control-url <CONTROL_URL>
# non-WSL Linux
python3 scripts/install_linux_oneclick.py --control-url <CONTROL_URL>
# macOS
python3 scripts/install_macos_oneclick.py --control-url <CONTROL_URL>
# Android Termux
python3 scripts/install_termux_oneclick.py --control-url <CONTROL_URL>WSL and Linux create and start a systemd --user supervisor, macOS loads a LaunchAgent, and Termux uses termux-services/runit plus Termux:Boot. WSL also needs the Windows host keepalive task if the distribution must start after a Windows reboot:
.\scripts\register_wsl_keepalive.ps1 -Distribution Ubuntu -LinuxUser <LINUX_USER>Windows and WSL are separate nodes even in mirrored networking. Give them distinct listener ports and the same opaque host: context. Port numbers only isolate listeners; they do not make the two runtimes' 127.0.0.1 addresses interchangeable. Host-scoped locators must use a shared non-loopback address (or 0.0.0.0 with explicit -Advertise/--advertise).
The original runtime-only installers remain available for operators who do not want a persistent node or service:
Windows scripts/install_windows.ps1
WSL scripts/install_wsl.py
macOS scripts/install_macos.py
Linux skills/install-anet/scripts/install.py
For the full control-page format, service paths, diagnostics, and CLI/MCP boundaries, see docs/CLI_AGENT_GUIDE.md, docs/MCP_AGENT_GUIDE.md, docs/WINDOWS_AUTOSTART.md, docs/POSIX_AUTOSTART.md, and docs/TERMUX_AUTOSTART.md.
If Codex or another coding agent should run the deployment, give it the following instruction. It should use the one-click entry point above, report the final node ID, node home, service/task state, and control-page URL, and never copy identity, TLS private keys, SQLite state, or an entire node home from another device:
Install and deploy Anet from https://github.com/yunlux/Anet. Use this control
page URL: <CONTROL_URL> (replace the placeholder before running). This request
authorizes one independent persistent node, its service/autostart integration,
and the supervisor's remote control-page polling. Detect the platform and use
its one-click deployment entry point; on native Windows use the PowerShell
one-command entry, adding -Admin only for machine-wide startup. On WSL, Linux,
macOS, or Termux run the matching one-click script from the checkout. If WSL
must restart after a Windows reboot, also register the host keepalive task when
that host-side action is authorized. Treat Windows and WSL as separate nodes:
use separate homes, identities, Node IDs, and listener ports, and never publish
127.0.0.1 as a host-scoped peer address. Report the installed runtime,
independent node, auto-start service/task, node ID, node home, and control-page
URL. Stop on an existing deployment, identity, hash, permission, or
control-page conflict; use -AllowExisting/--allow-existing only when a second
deployment is explicitly requested. Do not copy identity, TLS private keys,
SQLite state, or an entire node home from another device.
This prompt only delegates the commands above to an agent; it does not change the platform-specific node-home, identity-isolation, or duplicate-preflight rules.
Networks change, platforms disappear, and agents move between runtimes. Anet keeps the narrow waist stable:
- Identity is not an address. A node is identified by its cryptographic Node ID, not by an IP address, hostname, label, runtime, or organizational role.
- Custody is not delivery. A relay accepting ciphertext does not imply that the destination persisted it or that an agent completed the work.
- Authentication is not authorization. A valid sender signature proves origin; local capability and side-effect policy still decide what may run.
- Transport is replaceable. Direct TLS, SOCKS, stdio byte streams, Directory/WebDAV carriers, Ahub, and offline bundles carry the same sealed packet.
- Private state stays local. Identity keys, TLS private keys, SQLite state, and the complete node home must never be copied between runtimes or devices.
Agent / human runtime
│
├── CLI control plane
└── narrowly scoped MCP data plane
│
Anet node home
┌───────────┼───────────┐
│ identity │ trust │ durable queues
└───────────┼───────────┘
│ sealed packet
┌───────────┼───────────────┐
│ direct │ carrier/Ahub │ offline bundle
└───────────┴───────────────┘
Core security and delivery properties:
- Ed25519 signing identity and X25519 encryption identity;
- signed Peer Cards, explicit pinning, pairing, and local revocation;
- ephemeral X25519 + HKDF-SHA256 + ChaCha20-Poly1305 packet sealing;
- signed, peer-scoped one-time prekeys with atomic reservation and retirement;
- TLS 1.3, certificate channel binding, and mutual signed challenges;
- MessagePack payloads with randomized power-of-two padding;
- SQLite WAL queues, deduplication, TTL, bounded hops, leases, and receipts;
- durable consumer groups with claim, renew, ACK/NACK, and crash recovery;
- QoS-aware routing, health scores, bounded hedged direct sync, and carrier replication;
- typed Agent task envelopes and a persistent task ledger;
- encrypted store-and-forward paths whose relays do not receive node private keys or plaintext payloads.
See PROTOCOL.md for the wire and object model and openwiki/architecture/overview.md for the repository architecture map.
The following demonstration uses two separate node homes and loopback ports. These identities are for local testing only.
anet --home .\demo\a init --label node_a --host 127.0.0.1 --port 43101
anet --home .\demo\b init --label node_b --host 127.0.0.1 --port 43102
anet --home .\demo\a card --out .\demo\a.card.json
anet --home .\demo\b card --out .\demo\b.card.json
anet --home .\demo\a peer-add .\demo\b.card.json
anet --home .\demo\b peer-add .\demo\a.card.jsonFor safer asynchronous onboarding, use the signed challenge-response flow:
anet --home .\demo\a pair-offer --out .\demo\a.offer.json --ttl 3600
anet --home .\demo\b pair-accept .\demo\a.offer.json --out .\demo\b.response.json
anet --home .\demo\a pair-complete .\demo\a.offer.json .\demo\b.response.jsonStart one service for each private node home:
anet --home .\demo\a serve
anet --home .\demo\b serveInspect B's complete Node ID, send a message, and read the trusted inbox:
anet --home .\demo\b status
anet --home .\demo\a send <B_NODE_ID> --kind message --text "hello"
anet --home .\demo\b inbox --trusted-onlysend persists ciphertext in the local durable queue. A running serve or an
explicit sync performs delivery, so sender and destination do not need to be
online at the same time.
Direct connections retain TLS 1.3 and the signed peer handshake. A local SOCKS5/SOCKS5H proxy changes only the TCP dial path:
anet --home <HOME> direct-proxy socks5h://127.0.0.1:1080
anet --home <HOME> dialer-probe <PEER_NODE_ID>Remote proxies require explicit permission. Credentials are referenced by environment-variable name and are never embedded in the URL.
A shell-free stdio dialer can carry Anet over any reliable bidirectional byte
stream—serial links, radio modems, SSH pipes, custom transports, or future
physical-layer experiments—without giving the adapter access to node keys or
changing the Anet wire format. See STDIO_DIALER.md.
Directory and WebDAV carriers require no inbound listener. They move an additional encrypted and signed delivery frame through an untrusted directory or HTTPS mailbox:
anet --home .\demo\a carrier-sync D:\anet-drop
anet --home .\demo\b carrier-sync D:\anet-dropAhub is an optional, agent-neutral rendezvous, mailbox, and relay service. It holds signed public control objects and opaque encrypted packets, but owns no node identity and cannot turn a custody acknowledgement into destination or business completion. See AHUB_V1.md, RELAY_V1.md, and AHUB_OPERATIONS.md.
anet --home .\demo\a bundle-export .\carry.anet --destination <B_NODE_ID>
anet --home .\demo\b bundle-import .\carry.anetBundles still contain end-to-end encrypted objects and may be carried over removable media, file sharing, or another offline channel.
Use the CLI for sparse, explicit operations:
- install and upgrade;
- identity and trust lifecycle;
- locator and carrier configuration;
- diagnostics, recovery, and release gates.
CLI output is JSON and is suitable for agents, PowerShell, shell scripts, and automation runners.
Use a narrowly scoped stdio MCP session for repeated messaging, durable claims, and typed Agent tasks:
$env:ANET_HOME = "C:\Anet\nodes\runtime-a"
anet mcpStart from mcp-stdio.example.json. Production
profiles should bind an agent ID, consumer-group prefix, kind prefix, allowed
peers, task senders, and exact task capabilities through process-level
environment settings. Keep private relationship activity disabled unless that
Agent needs it (ANET_MCP_ALLOW_RELATION_ACTIVITY=0 by default). A separate
default-off anet_relation_model MCP read tool returns only the current local
Actor/Subject/circle structure and narrow contextual trust; it omits labels,
evidence references, events, and payloads (ANET_MCP_ALLOW_RELATION_MODEL=0
by default).
Audience-bound relationship disclosure is a separate default-off capability
(ANET_MCP_ALLOW_RELATION_DISCLOSURE=0); it carries only a content-free,
recipient-bound view and never imports remote circles or trust into the local
model. See
RELATIONSHIP_DISCLOSURES_V1.md. Do not
expose the complete MCP surface by default.
For a display-ready remote perspective, use
relation-reported-view <SENDER_NODE_ID>. It derives a provenance-bearing,
partial-unknown report from received disclosures without treating the
sender's Subjects, circles, or contextual trust as local state.
Scheduled disclosures use v2 series metadata so a selected rdsr_ chain can
prove cursor continuity or expose a missing page; continuity never implies
complete reality or current state.
An audience may send an advisory gap notice naming only the visibly missing
sequence numbers. It is not a disclosure pull. The observer may resend the
exact archived page only while its original schedule remains active, without
changing scope or advancing the series.
Anet defines strict agent.task.request, agent.task.status,
agent.task.result, and agent.task.cancel envelopes. The anet_task MCP
surface provides stable task IDs, lifecycle validation, capability declarations,
durable dispatch, cancellation tombstones, and execution-token fencing without
treating network identity as local authorization.
See AGENT_TASK_PROTOCOL.md and A2A_V1_GATEWAY.md.
Abazr is an independent Agent Bazaar product above Anet, not an Anet or Ahub core module. Its non-financial cooperation language is Need, Offer, Match, Proposal, Agreement, Fulfillment, and Evidence; wallets, tokens, escrow, and blockchains remain optional adapters.
Run the isolated ABA-D0 vertical slice:
python experiments/abazr_demo.pyThe demo creates no Anet node, service, wallet, payment, or network connection. See ABAZR_BLUEPRINT.md for the Mermaid architecture, roadmap gates, and explicit trust boundaries.
Anet uses one protocol and one Python wheel with platform-specific pinned install entry points. Existing persistent deployments use separate, explicitly configured release gates; the clean installer never discovers or mutates an existing node automatically.
- Windows:
scripts/install_windows.ps1 - WSL:
scripts/install_wsl.py - macOS:
scripts/install_macos.py - Linux:
skills/install-anet/scripts/install.py - WSL deployment gate:
scripts/wsl_release_gate.py
See PLATFORM_RELEASES.md and RELEASE_CHECKLIST.md.
- Network endpoints and traffic patterns may still be observed or blocked.
- Destination IDs, timing, ciphertext length buckets, and adjacent-node relationships may leak depending on the path.
- Jitter and backoff are not cover traffic or an anonymity proof.
- Anet does not currently provide onion routing, a mixnet, MLS groups, automatic NAT traversal, or hardware-backed key storage.
- Local decrypted inbox data and active process memory are outside the one-time-prekey forward-secrecy claim.
- Private keys currently live in local files; production deployments should use protected OS or hardware-backed key stores when available.
- Unknown senders remain untrusted and do not receive automatic delivery receipts.
Read SECURITY.md before deploying Anet beyond a controlled environment. Verification evidence and known limitations are recorded in VERIFICATION.md.
python -m pip install -e ".[test]"
ruff check .
pytest -qThe website lives under website/ and uses its own Node toolchain:
cd website
npm install
npm testContribution guidelines are in CONTRIBUTING.md.
Anet is licensed under the Apache License 2.0.