DEV Community

Cover image for HOLA explained: prove agent identity on any channel — robots, QR, video, chat
discernible-io
discernible-io

Posted on

HOLA explained: prove agent identity on any channel — robots, QR, video, chat

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>
Enter fullscreen mode Exit fullscreen mode
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)

  1. API loginPOST /api/login for a JWT (nonce fetch needs a session).
  2. Fresh nonceGET /api/holanonce16tsnoncetsHex + timestamp.
  3. Sign — Ed25519 over the canonical prefix; encode as base32 (no padding).
  4. Checksum — sum UTF-16 code units over canonicalPrefix + signature + "/", mod 23.
  5. 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:

  1. Each robot is a Passport holder (tokenId), not “the box at 10.0.12.4”.
  2. A builds a HOLA (recipient = B's tokenId, or MUNDO on first contact).
  3. 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.
  4. B verifies independently (API or RPC). Do not actuate until verify succeeds.
  5. B replies with its own HOLA on the same channel. A verifies. Now the handshake is mutual.
  6. 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:

  1. 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).
  2. 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.
  3. 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.
  4. Optional: bind recipient to the verifier's published tokenId so a QR photographed by a bystander does not authorize a different peer.
  5. 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.com or verify via RPC.
  • Show the 12-letter tokenId in 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/verify or npx @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

Implementing HOLA on a weird channel (radio, QR, factory bus)? Share the stack in the comments.

Top comments (0)