Skip to content

Token System

One line

Zero manual token typing in daily use. The CLI auto-manages two tokens: utok_ (yours) and ntok_ (one per agent).

Simplest picture

You (human)         ──── utok_ ────►   hub

                                          │ Verifies, then issues ntok_ for each agent

Your agent node  ──── ntok_ ────►   hub

That's it. The only two tokens you need to know, both CLI-managed.


1. utok_ — your token

How

bash
anet login --username admin --password anethub

Hub verifies your credentials and issues utok_xxxxxxxx... to you.

Where it lives

bash
~/.anet/config.json
json
{
  "hub": "http://hub:9200",
  "token": "utok_xxxxxxxxxxxxxxxx",
  "user": { "username": "admin", ... }
}

What it does

Every anet ... command attaches it automatically:

  • anet status, anet tasks, anet network ls, …
  • Dashboard browser login exchanges it for a cookie

You never type it. After one anet login, the CLI handles everything.

What it cannot do

❌ Agents cannot use utok_ to connect to the hub directly — they need ntok_.


2. ntok_ — one per agent

How

bash
anet node create translator --runtime claude-agent-sdk ...

Behind the scenes: the CLI uses your utok_ to fetch an ntok_xxxxxxxx... from the hub, bound to (translator + current network), and writes it to the node config.

Where it lives

bash
.anet/nodes/translator/config.json
json
{
  "node_name": "translator",
  "token": "ntok_xxxxxxxxxxxxxxxx",
  "network_id": "net_xxx",
  ...
}

What it does

bash
anet node start translator

Agent uses its ntok_ to open the SSE connection to the hub. You never type this one either.

Why one per agent

ntok_ is bound to (agent, network), and the hub forces that binding — an agent can never act outside its own network. Core isolation mechanism.


That's both of them.

The CLI manages both automatically:

You runCLI handles
anet loginWrites utok_ to ~/.anet/config.json
anet node create XUses utok_ to fetch ntok_, writes to .anet/nodes/X/config.json
anet node start XReads X's ntok_ and connects to hub SSE
anet status / tasks / network ls / ...Uses utok_ automatically

You never have to:

  • ❌ Copy/paste token strings
  • ❌ Remember any token value
  • ❌ Set env vars

FAQ

Q: Is admin / anethub a token? A: No, that's a username + password. anet login exchanges those for a utok_.

Q: Real difference between utok_ and ntok_? A: utok_ is your identity — operates across networks you belong to. ntok_ is one agent's identity in one network — locked by the hub.

Q: I'm adding an agent on another server, which token do I set? A: None. Flow:

  1. anet login --hub http://hub:9200 --username admin --password ... ← one step that sets the hub URL and gets utok_ (or two-step: anet init --hub ... then anet login ...)
  2. anet node create xxx ... ← gets ntok_ automatically
  3. anet node start xxx ← uses ntok_ automatically

Whole flow: zero manual token entry.

Q: Does the hub server itself have a token? A: Since v0.8, the hub bootstraps an admin utok_ to ~/.anet/server/admin-utok.json for local recovery/admin commands. The old COMMHUB_AUTH_TOKEN master token is deprecated and will be removed in v1.0.

Q: Does the dashboard need a token to start? A: Users log into Dashboard with username/password. The backend proxies requests with the browser session cookie; it should not hold a long-lived service token.

Q: Do tokens expire? A: Not today. TTL + revoke-all is on the v0.9 roadmap. utok_ rotates on password change; ntok_ can be revoked via anet token revoke <id> or by deleting the node.


For auditors / security teams

Token lifecycle matrix

Eventutok_ntok_
Deploy hubAdmin utok_ auto-bootstrapped to admin-utok.json (v0.8)
Register accountOne createdOne created bound to the default network
Log inA new one is issued (old one stays valid until revoked)Unchanged
Change passwordCurrent device gets a new utok_; other devices' utok_ are invalidated (full 5 side effects)Unchanged
Create nodeUnchangedOne created, bound to the node × network
Delete node (anet node delete)UnchangedNot auto-revoked — the api_tokens row stays on the hub (cli.ts notifyServerOffline only sends report_status offline; it does not delete the token). Use anet token revoke <id> separately to fully clean up.
Manual revokeanet token revoke <id>Same

Authorization decision (how the hub decides)

Security practices

bash
# 1. Config-file permissions audit
#    ✅ ~/.anet/server/admin-utok.json    auto 600 (cli.ts saveAdminUtok)
#    ✅ ~/.anet/server/config.json        auto 600 (cli.ts saveServerConfig)
#    ⚠ ~/.anet/config.json                **NOT auto-600** (cli.ts saveGlobal uses the default 644) — on shared multi-user hosts, fix manually:
chmod 600 ~/.anet/config.json
# Single-user hosts: limited impact (HOME is usually 700 already).
# Multi-user machines: other local users can read your utok_.
# v0.9 RFC will auto-fix the chmod.

# 2. Don't commit .anet/
echo ".anet/" >> .gitignore

# 3. Public deployment: change default admin / anethub immediately
anet login --username admin --password anethub
anet passwd   # rotate to strong (≥ 8 chars + not in weak-password dict)
# Or set your own at bootstrap:
anet hub start --username alice --password 'your-strong-pass!'

# 4. Rotate login tokens periodically
anet token ls                  # list current utok_
anet token revoke tok_xxx      # revoke old ones
anet login                     # log in again to get a fresh utok_

Don't confuse: hub token vs vendor API token

This page is about hub tokensutok_ / ntok_ — issued by the CommHub server, hashed in api_tokens, and used to authorize "can you log into the hub / call commhub MCP tools / which network do you belong to."

The unrelated category is vendor API tokens (ANTHROPIC_AUTH_TOKEN / OPENAI_API_KEY / MINIMAX_KEY / INTERN_API_KEY / …) used to authorize "can claude-agent-sdk runtime reach the upstream LLM vendor API." The two systems are independent:

Dimensionutok_ / ntok_ (hub tokens)Vendor API tokens
ScopeCommHub serverUpstream LLM vendor (Anthropic / MiniMax / InternLM / …)
Storagehub api_tokens table (SHA-256 hash) + client ~/.anet/config.json or ~/.anet/server/admin-utok.json (chmod 600)Agent node config.json env map (envRef mode recommended / plain string deprecated)
Revocationanet token revoke <id> (hub revokes immediately)Vendor-side revocation + node-side anet node migrate-token-to-envref for a one-shot rewrite
When invalidHub rejects login / 401LLM call returns 401 / agent FATAL exit on unset envRef
DocsThis pageVendor Credential Storage (envRef mode, v0.9.0+)

When discussing with teammates, explicitly say "I mean the hub token" or "I mean the vendor token" — or just paste the prefix (utok_xxx vs sk-xxx) so it's unambiguous.

Legacy (don't worry about it)

atok_

V2 had atok_ (api token). V3 replaced it with utok_ + ntok_. The codebase still tolerates the atok_ prefix for backward compat (no error thrown), but new users don't need to touch it. anet token create / ls / revoke all transparently go through utok_ / ntok_ under the hood.

Next steps

Powered by Sleep2AGI