Skip to main content

Zeq on hardware

The framework is a machine, and a machine exposes its I/O the way real hardware does — memory-mapped registers, not a config file. The Zeq connection region (~/.zeq/mmio) is a small page a device maps to read the machine's identity (ZID), the live 1.287 Hz clock (ZEQOND, PULSE_PHASE), its CREDIT, and a revocable credential handle (never the raw key). That's all you need to bind a device to the framework — no .env, no key baked into firmware.

There are three ways to put Zeq on a device, from most to least capable:

1 · Run the agent + map the region (a full local machine)

If the device runs a normal OS (Linux SBC, edge gateway, industrial PC), run the zeqd agent — it owns the region, keeps the registers live on the pulse, seals the key at rest, and resolves the handle to a short-lived bearer over an owner-only socket (the zeqd agent ships in the repo under zeqd/). See the MMIO architecture.

printf '%s' "$ZEQ_AK" | zeqd provision --zid ZEQ… --origin https://www.zeq.dev
zeqd run # owns ~/.zeq/mmio, ticks on the pulse, serves handle→bearer

Map it from C with the published header — zeq-mmio.h:

#include "zeq-mmio.h"
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>

int main(void) {
int fd = open("/root/.zeq/mmio", O_RDONLY);
unsigned char *r = mmap(NULL, ZEQ_MMIO_SIZE, PROT_READ, MAP_SHARED, fd, 0);
if (memcmp(r + ZEQ_OFF_MAGIC, ZEQ_MMIO_MAGIC, 8) != 0) return 1; // validate
unsigned long long zeqond = *(unsigned long long*)(r + ZEQ_OFF_ZEQOND); // live
double phase = *(double*)(r + ZEQ_OFF_PULSE_PHASE); // live
printf("ZID=%.32s Zeqond=%llu phase=%.4f\n", r + ZEQ_OFF_ZID, zeqond, phase);
return 0;
}

The credential is resolved separately over ~/.zeq/zeqd.sock ({op:"resolve", handle:"<KEY_HANDLE>"} → the bearer) so no secret is ever in the mapped page.

2 · Read the region over HTTP (a constrained device)

A microcontroller or anything that can't run the agent can read the same registers over the network — MMIO as an endpoint:

GET https://www.zeq.dev/api/zeq/mmio

Returns the full region manifest (the layout below, the doorbell + resolve protocol, how to connect) plus the machine-global live registers — no key needed:

{
"protocol": "ZeqMMIO", "version": 1, "magic": "ZEQMMIO\\0", "regionSize": 4096,
"layout": [ /* every register: offset, size, type, name, desc */ ],
"registers": { "zeqond": 2299088130, "pulse_phase": 0.41, "pulse_hz": 1.287, "R_t": 1.0004 },
"connect": { "sdk": "await ZeqReactorClient.connect()", "header": ".../zeq-mmio.h" }
}

To read your machine's registers (its ZID), present your zeq_ak_ key:

curl -H "Authorization: Bearer $ZEQ_KEY" https://www.zeq.dev/api/zeq/mmio/registers
# → { ok, zid, keyValid, registers: { zeqond, pulse_phase, pulse_hz, R_t } }

A device should anchor to zeqond from one poll and interpolate with its own monotonic timer between polls — never compute the absolute Zeqond itself.

3 · Speak the region format directly (firmware/FPGA)

For firmware or an FPGA soft-core, the region is a fixed 4 KiB little-endian layout — implement it directly from zeq-mmio.h. The endpoint's layout array is the machine-readable form of the same map:

OffsetTypeRegisterMeaning
0x000char[8]MAGIC"ZEQMMIO\0"
0x00Cuint32STATUSREADY·KEY_VALID·PULSE_LOCKED·SEALED·ERROR
0x010char[32]ZIDmachine identity
0x070char[32]KEY_HANDLErevocable capability (not the key)
0x0A0uint64ZEQONDlive Zeqond number
0x0A8doublePULSE_PHASElive phase [0,1)
0x0B0doublePULSE_HZ1.287
0x0B8doubleCREDITcompute-credit balance
0x0C0uint64HEARTBEATliveness beat
0x1000x10Cuint32CMD/DOORBELL/RESP/RESP_LENdoorbell write path

The doorbell (CMD + DOORBELLRESP) is the write path — PING returns the live Zeqond, REFRESH_KEY rotates the handle. Control only; the secret is never written to the page.

Security on a device

  • No key in firmware. The raw zeq_ak_ is sealed at rest by zeqd (AES-256-GCM where available) and held only in the agent's mlocked memory; the page carries a revocable handle with a TTL. A keyed HTTP device keeps its key in a secure element / runtime secret, never a file.
  • Read-only where it should be. A device that only needs the clock/identity reads the public endpoint or the region's read-only registers — no credential at all.
  • Roadmap — /dev/zeq. A character device (FUSE/kernel) for hardware-grade, kernel-enforced isolation of the region is the next step; the file/tmpfs region is the safe default today. See MMIO-ARCHITECTURE.md §8.

See also