- Docs
- Bureau — Blue Team (defensive)
- Hive
Bureau — Blue Team (defensive)
Hive
Hive watches IoT pairing ceremonies (LoRaWAN OTAA, Zigbee TC link keys, Z-Wave, Thread, Matter PASE/CASE) and emits signed contradictions for four common spoofing patterns: rogue joins, key-rotation skips, DAC certificate forgeries, and EUI clones.
Posture: 🔵 Blue Team (defensive) · Status: alpha
What it does
Smart-home, hospital, and factory-floor wireless fabrics – LoRaWAN, Zigbee, Z-Wave, Thread, Matter – each have their own pairing ceremony. Every time a sensor joins, it exchanges cryptographic keys with the fabric's coordinator. Today, those exchanges happen in the dark – most fabric admins have no record of who joined when, with what credentials, claiming to be what.
Hive watches the pairing transcripts and signs them. Then it watches for four things that shouldn't happen: a device joining without prior commissioning (rogue-join), a long-lived device that never rotated its key (key-rotation-skip), a "Matter" device whose certificate chain doesn't match the brand it claims (matter-cert-mismatch), or two devices in different fabrics claiming the same hardware ID (duplicate-EUI). Each contradiction becomes a signed red dot you can show the manufacturer, the IoT integrator, or a regulator.
Who would use it
- A hospital biomedical-engineering team in Boston rolling out 800 Matter-enabled patient monitors who need to verify each one's DAC certificate chain matches the vendor they bought from (not a counterfeit shipped through a gray-market reseller).
- A smart-factory IoT admin at a Tier-1 automotive supplier who wants signed observations that the LoRaWAN sensor reporting torque on Line 7 is the sensor the SBOM says it is – not a rogue device a contractor walked in.
- A smart-home buyer who paid extra for a Matter-certified door lock and wants to verify the device actually has the cert chain CSA published, before binding it to their phone.
- A CISO at an apartment-complex chain who needs to file insurance claims after a Mirai-class botnet recruited their cheap WiFi cameras – the rogue-join proofs name exactly which devices joined which networks at what timestamps.
- A Federal Communications Commission researcher auditing whether LoRaWAN deployments in agriculture are actually rotating their AppKeys per the spec (the answer, for most networks, is no).
What you'll need
- Node.js 18+ and the Pluck CLI:
npm install -g @sizls/pluck-cli - An operator key:
pluck bureau keys generate --out ~/.pluck/keys(one-time) - For real fabrics: a sniffer per protocol – Heltec LoRa node (~$25), TI CC2531 USB Zigbee sniffer (~$30), Aeotec Z-Stick for Z-Wave (~$50), nRF52840 dongle for Thread (~$45), Pluck Matter SDK reader for PASE/CASE (in development)
- For the alpha demo: nothing – runs in-memory on synthetic data spanning all five fabric kinds
Step-by-step
The alpha runs in-memory on synthetic data. The production CLI (real sniffer integration, daemon mode, capture/verify/replay) ships in a follow-up.
1. Run the demo
pluck bureau hive demo
Output:
hive/demo: ingesting signed observations (1 legit + 1 rogue-join + 1 matter-cert-mismatch + 1 duplicate-EUI + 1 lorawan-rotation-skip)...
hive/demo: tamper proofs emitted = 4
hive/demo: proofId=a8c1d2… kind=rogue-join eui=cdcdcdcdcdcdcdcd
hive/demo: proofId=771e9f… kind=matter-cert-mismatch eui=deadbeefcafebabe
hive/demo: proofId=21bb33… kind=duplicate-eui eui=1111222233334444
hive/demo: proofId=99ad44… kind=key-rotation-skip eui=5555666677778888
hive/demo: proofs notarized (stub) = 4
The demo synthesizes five reader observations spanning four fabric kinds: one legitimate Zigbee join, one rogue Matter join (no prior commissioning record), one Matter cert-mismatch (the DAC subject's mvid/mpid markers don't match the vendor/product the device claims), one duplicate-EUI Z-Wave clone (same hardware identifier in two different fabrics inside the 24-hour witness window), and one LoRaWAN device that joined 60 days ago and never rotated its AppKey. Four contradictions get signed.
2. Look at a tamper proof
Each proof carries the offending observations verbatim – the matter-cert-mismatch proof, for example, contains the DAC certificate PEM the device presented and the (vendorId, productId) it claimed.
cat ./hive-out/proofs/proof-matter-cert-mismatch-771e9f.json
3. Verify
pluck bureau verify ./hive-out
The verifier checks the reader's signature, walks the cert chain back to the Product Attestation Authority, recomputes the EUI uniqueness window, and prints PASS / FAIL.
Run it yourself
Drop this into a Node 18+ project (npm install @sizls/pluck-bureau-hive @sizls/pluck-bureau-core tsx):
// index.ts
import { createHash } from "node:crypto";
import {
createHiveSystem,
DEFAULT_LORAWAN_CADENCE_MS,
fingerprintPrivateKey,
signCanonicalBody,
type JoinObservation,
} from "@sizls/pluck-bureau-hive";
import { generateOperatorKey } from "@sizls/pluck-bureau-core";
async function main() {
const operator = generateOperatorKey();
const reader = generateOperatorKey();
const readerFingerprint = fingerprintPrivateKey(reader.privateKeyPem);
const t0 = "2026-04-26T00:00:00.000Z";
const t1 = "2026-04-26T00:00:01.000Z";
// Reference clock 60 days in – past the 36-day rotation threshold.
const nowMs = Date.parse(t0) + 60 * 24 * 60 * 60 * 1000;
const hive = createHiveSystem({
signingKey: operator.privateKeyPem,
disablePausePoll: true,
disableLogging: true,
tolerances: {
expectedRotationMs: DEFAULT_LORAWAN_CADENCE_MS,
cadenceSlackPct: 0.2,
duplicateEuiWindowMs: 24 * 60 * 60 * 1000,
nowMs,
},
});
try {
// 1) Legitimate Zigbee join – first-chrono so it's its own commissioning baseline.
hive.observeJoin(buildJoin("zigbee", "abababababababab", "fabric-A", t0, reader.privateKeyPem, readerFingerprint));
// 2) Rogue Matter join – no prior commissioning record.
hive.observeJoin(buildJoin("matter", "cdcdcdcdcdcdcdcd", "fabric-A", t1, reader.privateKeyPem, readerFingerprint));
await new Promise((r) => setImmediate(r));
await new Promise((r) => setImmediate(r));
const proofs = hive.facts.tamperProofs();
console.log(`tamper proofs emitted = ${proofs.length}`);
for (const p of proofs) {
console.log(`proofId=${p.proofId.slice(0, 16)} kind=${p.kind} eui=${p.deviceEui ?? "<none>"}`);
}
} finally {
await hive.shutdown();
}
}
function buildJoin(kind: JoinObservation["kind"], deviceEui: string, networkId: string, timestamp: string, readerKey: string, readerFingerprint: string): JoinObservation {
const joinTranscriptDigest = createHash("sha256").update(`transcript:${kind}:${deviceEui}:${networkId}:${timestamp}`).digest("hex");
const skeleton = { schemaVersion: 1 as const, kind, deviceEui, networkId, timestamp, readerFingerprint, joinTranscriptDigest };
const observationId = createHash("sha256").update(JSON.stringify(skeleton)).digest("hex");
const signed = signCanonicalBody({ ...skeleton, observationId }, readerKey);
return { ...skeleton, observationId, signature: signed.signature };
}
main().catch((err) => { console.error(err); process.exit(1); });
Run with tsx index.ts. Expected output:
tamper proofs emitted = 1
proofId=… kind=rogue-join eui=cdcdcdcdcdcdcdcd
Open in StackBlitz – runs in your browser, no install required.
What you get
For each detected fabric attack: a signed HiveTamperProof cassette (a .intoto.jsonl Sigstore-compatible file) carrying the offending observations verbatim. A factory IoT admin can hand it to the contractor who delivered the rogue device and say "this didn't come from you" – and the contractor can verify it themselves with cosign verify-blob without trusting either party's word.
The cassettes also chain into per-network and per-device timelines: every join, every key rotation, every commissioning record for fabric 0xABCD0001 is in one place, with every contradiction flagged. That's the artifact insurers, regulators, and procurement teams want when something goes wrong.
What it can't do
- Hive doesn't prevent a device from joining. The fabric still trusts whoever holds the right credentials. Hive produces observations after the join, not access control.
rogue-joindetection requires a prior signed commissioning record. If your operator process never signs commissioning, every join looks rogue. Operators have to commit to the witness chain before turning the detector on.- A compromised sniffer can sign whatever observation it wants. Pair Hive with hardware-attested sniffer keys for upstream protection.
- The alpha is in-memory only. Real protocol integration (LoRaWAN packet decoder, Zigbee Trust Center observer, Thread commissioner watcher, Matter PASE/CASE recorder) ships in follow-ups.
- Hive can't tell you which device is "the right one" if both presented identical credentials. It tells you cloning happened and gives you the math; the response (revoke, replace, prosecute) is yours.
A real-world example
In June 2026 a tier-1 automotive supplier in Stuttgart rolls out 1,400 LoRaWAN torque sensors across three production lines. Six months later, their security team's quarterly audit notices something wrong: 12 devices on Line 7 are reporting normally but their AppKeys haven't rotated since the original install – every other device has rotated 5 to 6 times, exactly per the 30-day cadence the spec calls for.
They feed the joined-device log through Hive. Twenty seconds later, 12 signed key-rotation-skip proofs land. Each carries the deviceEUI, the last-known rotation epoch, and the expected-but-missing rotations. The integrator's contracted SLA promised AppKey rotation per spec; Hive's proofs are entered as exhibit A in the contract dispute. The supplier recovers €840K in penalty payments. Three months later the integrator's firmware bug – a classloader race that silently dropped rotation events for any device with EUI starting 0x55 – gets a public CVE.
For developers
Predicate URIs
| URI | What it attests |
|---|---|
https://pluck.run/Hive.Join/v1 | One reader-signed pairing observation (LoRaWAN / Zigbee / Z-Wave / Thread / Matter) – kind, deviceEui, joinTranscriptDigest, networkId, timestamp. |
https://pluck.run/Hive.Matter/v1 | One reader-signed Matter PASE/CASE commissioning observation – deviceEui, networkId, claimed (vendorId, productId), DAC + PAI PEM, transcript hash. |
https://pluck.run/Hive.LoRaWAN/v1 | One reader-signed LoRaWAN AppKey rotation epoch witness – deviceEui, networkId, monotonic epoch counter, timestamp. |
https://pluck.run/Hive.Tamper/v1 | One Bureau-signed tamper proof (rogue-join, key-rotation-skip, matter-cert-mismatch, or duplicate-eui) carrying verbatim offending observations. |
Programs composed
- Pluck
dowse– the reader-side cassette wrapper that carries signed pairing transcripts to the Bureau path - Raven – provides the RF substrate witness so a join observation is anchored to a measured radio environment
- Custody – provides per-device chain-of-custody so a single device's joins reach Rekor without operator-side cherry-picking
- SBOM-AI – provides the signed Matter device DAC manifest the matter-cert-mismatch detector cross-checks claimed vendor/product IDs against
- Sigstore Rekor – proofs are notarized as DSSE in-toto envelopes with a public inclusion proof
Threat model + adversary
- Up to 20,000 join observations, 10,000 Matter commissioning records, 20,000 key-rotation events, and 1,024 tamper proofs kept in memory before FIFO eviction.
- Default LoRaWAN rotation cadence is 30 days; default slack is 20%. Both are operator-configurable per device class.
- Matter PEM bodies capped at 8 KiB; vendorId / productId capped at 16-bit unsigned (0xFFFF).
- Hive does NOT detect a fabric where the witness reader is itself compromised. Pair with hardware-attested sniffer keys + 0600-permissioned operator keys for upstream protection.
- SSID / network secret / wireless key material never appears in a signed body. Device EUIs are sensitive (per-die long-lived identifiers); operators MAY carry the EUI as
sha256(eui||salt)if vendor PII concerns apply.
Verify a published cassette
pluck bureau verify <bundle-dir>
# Or with cosign directly
cosign verify-blob \
--key <pubkey.pem> \
--signature <signature.sig> \
--type https://pluck.run/Hive.Tamper/v1 \
<body.json>
The package exports validateHiveTamperProof, verifyCanonicalBody, extractMatterIdsFromCert, and predicateTypeForTamperKind for verifier authors.
See also
- Bureau Foundations
- Threat Model
- Verify a dossier
- Operator Duties
- Raven – RF substrate witness
- Custody – per-device chain-of-custody
- SBOM-AI – signed Matter device DAC manifest stream
- Sigil – sibling contactless tag observatory