DEV Community

Cover image for Build an OpenClaw agent hive with IdentyClaw: A2A + email out of the box
discernible-io
discernible-io

Posted on

Build an OpenClaw agent hive with IdentyClaw: A2A + email out of the box

You can run a hive of OpenClaw agents — two, twenty, or as many as your hosts allow — that talk over A2A and email without hand-wiring peer URLs or inventing shared secrets for every pair.

The public path:

  1. Clone the container ops repo
  2. Install the IdentyClaw plugins (pinned in the deploy toolkit)
  3. Mint an IdentyClaw Passport per agent
  4. Set each agent’s email + public URL
  5. Scale with AGENT_IDS (and more hosts when you outgrow one machine)

This guide is self-contained. For deeper Passport theory, plugin tool lists, and multi-tenant collaboration envelopes, see the companion walkthrough: Onboard OpenClaw agents with IdentyClaw Passport.


What you get

Capability How
Isolated gateways One Podman container + state dir per agent
Stable peer identity 12-letter Passport tokenId
A2A messaging @identyclaw/openclaw-a2a-pluginPOST /a2a, Agent Cards, P2P RODiT JWT
Email in/out Migadu IMAP/SMTP + Himalaya skill (this article’s email example)
Signed wake events @identyclaw/openclaw-identyclaw-webhooks-plugin on /hooks/*
Identity / HOLA @identyclaw/openclaw-identyclaw-plugin + ClawHub identyclaw skill
Peer URL resolution Passport metadata.webhook_url via IdentyClaw API — not a static peer map

Repos used in this guide (swap if you prefer):

Concern Example we use Notes
LLM OpenRouter (sk-or-…) OpenCode Zen/Go also supported by the deploy scripts
Email Migadu + Himalaya Other IMAP/SMTP providers need different Himalaya / image wiring
TLS Self-signed via ./identyclaw.sh generate-certs Replace with Let’s Encrypt, commercial CA, or your infra PEMs anytime

Architecture (one host or many)

                    ┌────────── IdentyClaw API ──────────┐
                    │  Passports · verify · GET /agents  │
                    │  metadata.webhook_url per tokenId  │
                    └───────────────┬────────────────────┘
                                    │ resolve peers by tokenId
          ┌─────────────────────────┼─────────────────────────┐
          ▼                         ▼                         ▼
   ┌─────────────┐           ┌─────────────┐           ┌─────────────┐
   │  agent-a    │◄── A2A ──►│  agent-c    │◄── A2A ──►│  agent-N    │
   │  OpenClaw   │           │  OpenClaw   │           │  OpenClaw   │
   │  + plugins  │── email ──│  + plugins  │── email ──│  + plugins  │
   │  Migadu box │           │  Migadu box │           │  Migadu box │
   └─────────────┘           └─────────────┘           └─────────────┘
          ▲                         ▲                         ▲
          └──────── nginx TLS (pod mode) / public HTTPS ──────┘
Enter fullscreen mode Exit fullscreen mode

Peers are Passport IDs, not hostnames in config. When an agent’s gateway moves, update webhook_url on that Passport — collaborators keep resolving the live base.


Prerequisites

Requirement Notes
Linux host with Podman (rootless OK) AlmaLinux / RHEL / Fedora / similar
Node.js 22+ on the host Used by helper scripts
Public GitHub access Clone deploy + plugin sources
One Migadu mailbox per agent you enable Create mailboxes first; passwords can wait until after init
OpenRouter API key One key per agent (or share carefully — prefer per-agent)
DNS for public hosts (pod / multi-host) Point AGENT_*_PUBLIC_HOST names at your ingress

1. Clone the container-based agent repo

The ops toolkit is code-only and public:

git clone https://github.com/discernible-io/identyclaw-agents.git
cd identyclaw-agents
chmod +x identyclaw.sh
./identyclaw.sh init
Enter fullscreen mode Exit fullscreen mode

init creates a sibling app directory (default ../identyclaw-agents-app) for secrets, TLS, and per-agent state. Never commit that directory.

Full operator detail: identyclaw-agents README.


2. Size the hive: AGENT_IDS (arbitrarily large)

How many gateways run on this host is one line in ~/identyclaw-agents-app/env.local:

# Two agents on this host
AGENT_IDS=agent-a agent-c

# Stock three-agent template
AGENT_IDS=agent-a agent-c agent-e

# Grow on the same host — add ids + matching AGENT_<LETTER>_* blocks
AGENT_IDS=agent-a agent-c agent-e agent-f agent-g
Enter fullscreen mode Exit fullscreen mode

Rules that keep a large hive sane:

  1. Per agent on this host: email, gateway port, public host, NEAR credentials, OpenRouter key.
  2. Stock template covers a, c, and e. For custom ids (agent-f, …), copy an AGENT_*_ block in env.local and adjust ports so they do not collide.
  3. More than one machine: set AGENT_IDS to the agents on that host only. Cross-host peers are Passport tokenId values in A2A_PEER_AGENTS (or discovered via GET /api/agents) — not hard-coded URLs.
  4. Agents not listed in AGENT_IDS are simply not started; you can provision credentials later.

Example split across hosts:

# Host 1
AGENT_IDS=agent-a
A2A_PEER_AGENTS=<tokenId-of-agent-c> <tokenId-of-agent-e>

# Host 2
AGENT_IDS=agent-c agent-e
A2A_PEER_AGENTS=<tokenId-of-agent-a>
Enter fullscreen mode Exit fullscreen mode

Enable dynamic peer URL resolution (typical):

IDENTYCLAW_A2A_DYNAMIC_PEERS_FROM_JWT=1
Enter fullscreen mode Exit fullscreen mode

Peers resolve via GET /api/identity/token/{tokenId}/fullmetadata.webhook_url.


3. Plugins — installed by the deploy toolkit

On ./identyclaw.sh start / restart, each agent gets the published integrations (pins live in env.example):

Integration ClawHub / source Role
identyclaw skill + identyclaw-tools clawhub.ai/identyclaw/identyclaw · plugin API login, HOLA, identity, DID
identyclaw-a2a openclaw-a2a-plugin A2A send/receive, Agent Card, P2P JWT
identyclaw-webhooks webhooks plugin Signed /hooks/wake + /hooks/agent

Refresh pins when needed:

./identyclaw.sh upgrade-plugins all
./identyclaw.sh restart all
Enter fullscreen mode Exit fullscreen mode

Optional trust skill for collaboration envelopes: identyclaw-a2a-trust.


4. Build, start, OpenRouter, Migadu

./identyclaw.sh build-image
# Edit ../identyclaw-agents-app/env.local — AGENT_IDS, AGENT_*_EMAIL, ports, PUBLIC_HOST
./identyclaw.sh start all
./identyclaw.sh status
Enter fullscreen mode Exit fullscreen mode

LLM (OpenRouter example) — per agent in AGENT_IDS:

./identyclaw.sh set-api-key agent-a    # paste sk-or-...
# repeat for agent-c, agent-e, …
./identyclaw.sh onboard agent-a
./identyclaw.sh restart agent-a
Enter fullscreen mode Exit fullscreen mode

Email (Migadu + Himalaya example) — one Migadu mailbox per agent; set AGENT_A_EMAIL (etc.) in env.local, then:

./identyclaw.sh set-password agent-a   # Migadu mailbox password → secrets/
./identyclaw.sh restart all
./identyclaw.sh test-mail agent-a
Enter fullscreen mode Exit fullscreen mode

Himalaya in this image expects Migadu-style IMAP/SMTP (IMAP 993; SMTP 587 + STARTTLS). Other providers are possible but need their own Himalaya config / image changes — treat Migadu as the supported reference path in this toolkit.

Reciprocal email HOLA smoke (when mailboxes are live):

./identyclaw.sh test-mail-hola agent-a <peer-token-id>
Enter fullscreen mode Exit fullscreen mode

5. Passport per agent + point the URL

Each hive member needs its own IdentyClaw Passport (NEAR implicit account + mint):

  1. Generate credentials into that agent’s secrets/near-credentials/ (deploy helpers / plugin NEAR generate — see MCP guide:enrollment).
  2. Purchase / mint at https://purchase.identyclaw.com for the printed implicit_account_id.
  3. Restart the agent so IDENTYCLAW_* syncs into plugin config.
  4. Confirm: chat or tool → identyclaw_get_my_identity / GET /api/me/identity → note the 12-letter tokenId.

Point the public URL — set Passport metadata webhook_url to the agent’s HTTPS base (no /hooks/agent path). Peers and webhooks resolve that field.

./identyclaw.sh webhook-url agent-a    # prints the base the host expects
Enter fullscreen mode Exit fullscreen mode

Examples (main-tier style hosts):

Agent Typical base (illustrative)
agent-a https://agent-a.example.com:9443
agent-c https://agent-c.example.com:9443

With IDENTYCLAW_RODIT_SELF_CONFIGURE=1 (default in the toolkit), agents can align self config from on-chain / API metadata after credentials exist.

Deep enrollment and plugin allowlists: companion onboarding article · MCP guide:enrollment.


6. TLS: self-signed now, any CA later

For pod ingress (IDENTYCLAW_DEPLOY_MODE=pod):

# Set AGENT_*_PUBLIC_HOST and IDENTYCLAW_INGRESS_PORT in env.local first
./identyclaw.sh generate-certs
Enter fullscreen mode Exit fullscreen mode

That writes PEMs under ~/identyclaw-agents-app/certs/ with SANs for your agent hosts.

  • Self-signed is enough to bootstrap A2A and webhooks: mutual auth for those surfaces is RODiT / Passport (JWT + Ed25519 webhook signatures), not the TLS CA brand.
  • Replace anytime with Let’s Encrypt, your corporate CA, or managed certs — drop fullchain.pem / privkey.pem (or follow your infra cert docs) and reload nginx.

Loopback / standalone mode can skip public TLS while you develop; use pod mode when agents must reach each other over the internet.


7. Prove the hive works

# A2A discovery + auth boundaries
./identyclaw.sh discover-a2a-peers all
./identyclaw.sh test-a2a
./identyclaw.sh test-a2a-auth
./identyclaw.sh test-a2a-messaging agent-a agent-c   # when both live

# Webhooks
./identyclaw.sh test-webhook agent-a

# Email HOLA (Migadu path)
./identyclaw.sh test-mail-hola agent-a <peer-token-id>

# Broader constitution suite
./identyclaw.sh test
Enter fullscreen mode Exit fullscreen mode

Two trust layers (do not mix them up):

  1. Wire — A2A Bearer JWT / signed webhook → who may speak on the channel
  2. Task — HOLA (and optional identyclaw.collaboration.v1 envelope) → who delegated the work; verify before execute

Scaling checklist (N agents)

For each new agent:

  1. Create Migadu mailbox → AGENT_X_EMAIL + set-password
  2. Add id to AGENT_IDS + unique GATEWAY_PORT / PUBLIC_HOST
  3. set-api-key (OpenRouter) → onboardrestart
  4. NEAR credentials → mint Passport → set webhook_url to that agent’s HTTPS base
  5. Add tokenId to peer hosts’ A2A_PEER_AGENTS (or rely on API discovery)
  6. upgrade-plugins / discover-a2a-peers / smoke tests

Across hosts: repeat the container repo on each machine; keep one Passport identity per agent; never share NEAR private keys between containers.


Public repos & links


What this is not

  • IdentyClaw does not host your OpenClaw gateways or replace Podman.
  • Migadu is the documented email example for Himalaya in this image — not the only mail system in the world.
  • OpenRouter is the documented LLM example — OpenCode is available in the same scripts.
  • Self-signed certs are a bootstrap, not a requirement forever.

If you already run a single OpenClaw gateway by hand, the companion Passport onboarding guide still applies — this article is the hive-shaped path using the public container toolkit.

Questions or a stuck peer resolve? Open an issue on identyclaw-agents or ask in your OpenClaw community channel with the agent tokenId (never paste private keys or full JWTs).

Top comments (0)