HOLA (Hello Authentication) is how IdentyClaw Passport holders prove identity to each other on whatever channel already carries the encounter — email, chat, A2A, MQTT, serial, radio, a QR code on a screen, even a video call. There is no dedicated identity endpoint and no central handshake broker.
This is a protocol primer plus real-world scenes. The normative spec is hola-agent-authentication. Walkthrough: hola-howto.
What problem HOLA solves
Traditional auth assumes a login endpoint: send credentials, get a session. Agent-to-agent (and device-to-device) work often happens off that path. Two warehouse robots on MQTT, a kiosk and a phone camera, two peers on Slack — they need the same answer: "Is this really Passport holder X?"
A HOLA line is a compact, signed proof string. You embed it in the medium you already have. Each peer verifies independently — IdentyClaw HTTP API or direct NEAR RPC. The API does not broker the exchange.
Verify before execute (or before actuate): never run delegated work, open a tool, or move a motor until the full proof bar passes. Operator recipes: Verify before execute.
The HOLA line (shape)
A HOLA line is one slash-separated string:
HOLA/<recipient>/<tokenId>/<timestamp>/<noncetsHex>/API.IDENTYCLAW.COM/<base32Signature>/<checksum>
| Segment | Role |
|---|---|
HOLA |
Protocol identifier |
<recipient> |
Intended peer: MUNDO (anyone) or a 12-letter Passport ID |
<tokenId> |
Sender's 12-letter Passport ID |
<timestamp> |
ISO-8601 from GET /api/holanonce16ts (not login timestamp_iso) |
<noncetsHex> |
32 uppercase hex chars (~5 min TTL) |
API.IDENTYCLAW.COM |
Domain identifier in the signed prefix |
<base32Signature> |
Ed25519 over the canonical uppercase prefix |
<checksum> |
One letter from ABCDEFGHJKMNPQRSTUVWXYZ (omits I, L, O) |
Canonical prefix for signing: UTF-8 bytes from HOLA/ through API.IDENTYCLAW.COM/, uppercased. Wire casing is optional — verifiers normalize. Signature encoding is base32, not the base64url used for API login.
Do not copy the example values above onto the wire. Fetch a fresh nonce for every line.
Building a line (sender)
-
API login —
POST /api/loginfor a JWT (nonce fetch needs a session). -
Fresh nonce —
GET /api/holanonce16ts→noncetsHex+timestamp. - Sign — Ed25519 over the canonical prefix; encode as base32 (no padding).
-
Checksum — sum UTF-16 code units over
canonicalPrefix + signature + "/", mod 23. - Send — deliver the full line on your existing channel (text, QR, MQTT payload, email body, …).
Self-test generation with POST /api/testhola. That checks your builder; it is not how you decide to trust a peer.
Verifying a line (receiver)
Receivers validate independently. Local checksum or a bare Ed25519 check is not enough.
| Path | When |
|---|---|
| IdentyClaw API |
POST /api/identity/verify with { "hola": "<line>" }
|
| Direct NEAR RPC |
@rodit/rodit-auth-be (or equivalent) + your RPC |
Full proof bar: Passport exists and is active, signature and checksum valid, timestamp fresh, nonce not replayed, recipient binding. Then compare peerTokenId to the principal's published Passport ID (impersonation guard).
Mutual authentication is bidirectional: validating inbound HOLA proves who contacted you; reply with your outbound HOLA on the same channel so they can verify you.
HOLA vs API login (don't mix vocabulary)
| API login | HOLA | |
|---|---|---|
| Purpose | JWT for IdentyClaw HTTP APIs | Prove Passport identity to a peer |
| Timestamp field | timestamp_iso |
timestamp (from holanonce) |
| Signature encoding | base64url | base32 |
| Wire |
POST /api/login JSON |
One slash-separated line on any channel |
A session JWT proves you may call an API. It does not prove who delegated a task on email, MQTT, or a QR scan.
Why the line is a real-world primitive
HOLA is not a socket protocol. It is a short, time-bound string. Anything that can carry ~200–300 characters can carry identity proof:
- A chat message, email body, or webhook JSON field
- An MQTT / serial / radio frame
- A QR code on a display, sticker, or headset HUD
- A camera reading that QR from a video feed or a live call
The ~5 minute nonce window is the operational constraint: a screenshot from yesterday is dead; a QR on a warehouse screen is a live proof.
Scene 1 — Two robots, no fleet secret
Warehouse robot A meets robot B at an aisle. They share neither a pre-provisioned HMAC nor a stable IP. MAC addresses and display names are not identity.
Pattern:
- Each robot is a Passport holder (
tokenId), not “the box at10.0.12.4”. - A builds a HOLA (recipient = B's
tokenId, orMUNDOon first contact). - A puts the line on the channel they already use — MQTT topic, serial, LoRa, or a QR on A's status screen that B's camera reads.
- B verifies independently (API or RPC). Do not actuate until verify succeeds.
- B replies with its own HOLA on the same channel. A verifies. Now the handshake is mutual.
- Only then: dock, hand off a pallet, accept a payload, run a tool.
No dedicated identity broker on the factory floor. No shared fleet secret that leaks to every unit. If a robot is replaced, mint (or transfer) a Passport; peers resolve the new endpoint via tokenId metadata instead of rewriting HMAC lists.
Closed lab, one operator, air-gapped mesh? Static secrets can still win — see Passport vs static secrets.
Scene 2 — QR on a video call (optical HOLA)
A human (or another agent) is on a video call with an unknown assistant. Chat can be spoofed. The voice can be cloned. The screen can still show a live HOLA.
Pattern:
- The agent fetches a fresh nonce, signs a HOLA line, encodes it as a QR code, and displays it in the call (or on a kiosk, badge, robot faceplate).
- The verifier scans with a phone camera, a second agent's vision stack, or a still from the video frame — then runs the same
POST /api/identity/verify(or RPC) path as for a chat paste. - Because the nonce is short-lived, a recorded Zoom from last week does not authenticate anyone. Replay of an old QR fails freshness and nonce-replay checks.
- Optional: bind
recipientto the verifier's publishedtokenIdso a QR photographed by a bystander does not authorize a different peer. - For mutual proof, the human/agent replies with their own HOLA — typed, pasted, or a second QR pointed at the first camera.
Same protocol as robot-to-robot. The “channel” is photons. That is the point of a channel-agnostic line: you do not invent a new identity stack for cameras.
Practical notes:
- Keep the QR payload the raw HOLA string (or a URL that embeds it). Do not wrap it in a look-alike verify host; pin
https://api.identyclaw.comor verify via RPC. - Show the 12-letter
tokenIdin human-readable text next to the QR so the impersonation guard is a glance, not only a decode. - Public web verifier: verify.identyclaw.com. CLI:
npx @rodit/verify-hola report "HOLA/...".
Other channels (same line)
| Environment | How the line travels | Typical rule after verify |
|---|---|---|
| Email / Slack / Discord | Body or attachment | Reply automation, tool use |
| OpenClaw / A2A | Envelope hola field |
task.payload execution |
| Webhook / HTTP | JSON { "hola": "…" }
|
Downstream API call |
| MQTT / serial / radio | Topic payload / frame | Actuate, dock, open gripper |
| QR / video / HUD | Optical scan | Pairing, badge-in, kiosk login |
Wire auth (TLS, A2A JWT, MQTT username) still matters. It answers "may this connection send?" HOLA answers "which Passport delegated this encounter?" Do not conflate the two.
Subagent delegation (variant)
When a supervisor Passport delegates to a subagent signer, the line format extends. See hola-subagent-authentication and the verifier's POST /api/isauthorizedsigner step after HOLA passes.
Try it
- Self-test generation:
POST /api/testhola - Verify a peer:
POST /api/identity/verifyornpx @rodit/verify-hola report "HOLA/..." - Web: https://verify.identyclaw.com
- OpenClaw:
@identyclaw/openclaw-identyclaw-plugin(identyclaw_create_hola,identyclaw_verify_hola)
Runnable verify examples: examples/verify-before-execute/. Create-and-verify and mutual-handshake demos are planned under the same repo (feature demo matrix).
Resources
- Spec: https://api.identyclaw.com/mcp →
doc:reference:hola-agent-authentication - How-to:
doc:reference:hola-howto - Holanonce:
doc:reference:holanonce-api - API docs: https://api.identyclaw.com/docs
- Why channel-agnostic mutual auth:
why-identyclaw§6.1
Implementing HOLA on a weird channel (radio, QR, factory bus)? Share the stack in the comments.
Top comments (0)