Security
Trust levels
Hosts carry a trust_level of none | software | edr | hardware. The array order in packages/shared/src/index.ts is the rank:
none < software < edr < hardware
trustMeets(level, min) is that rank comparison. Public routing default min_trust is software (DEFAULT_MIN_TRUST in workers/src/routing.ts). The hardware value is listed so a buyer can ask for it and get an honest 503; nothing in this repo grants hardware.
This page is the contract a buyer can rely on. It is not operator-blind marketing. Cross-links: overview, threat model, verify a response, verifiable inference, releases, EDR adapters.
At a glance
| Tier | How a host gets it | What a buyer can rely on | Operator-blind? |
|---|---|---|---|
none | Default. Dev builds (build=dev), unknown/revoked hash, missing keys, failed/stale challenge. | Heartbeat liveness (15 s / 45 s offline). Pool/self only. | No |
software | Reports a blessed release sha256 + Ed25519 over nonce ‖ build_hash at register, then passing 5-min challenges (still-blessed hash, valid sig, posture policy). | The host claims a publicly verifiable blessed build and keeps proving possession of its registered key. The coordinator cannot check which binary is actually running — see below. Public-eligible after probation. | No — not on Linux/Windows; not on macOS until T28/T72 |
edr | Already software, plus the org's EDR adapter verifies the reported device id this challenge cycle (T94). | Same as software, plus an org-controlled sensor says this device is in the fleet, online (< 10 min), facts match, score ≥ min_score. | No. EDR is not a TEE. Root can still read memory. |
hardware | Reserved (T72). | Nothing today. X-NeuronPool-Min-Trust: hardware → 503 No hardware-tier hosts online. | n/a |
none
Guarantee. The coordinator has a row, a host token, and a recent heartbeat if online. That is all.
How. Register without a blessed build_hash, with build=dev, with a revoked hash, without sign_pubkey, or with a bad build-attestation signature (evaluateTrust in workers/src/blessed.ts). Any failed or unanswered challenge demotes software back here (verifyChallengeAnswer, handleHeartbeatChallenge).
Buyer reliance. Do not send public paid traffic here. The router excludes trust_level === 'none' from public even if sell_idle=1. Pool and self still work — that is the social-pool wedge: friends already trust the machine.
Not proven. Identity beyond "this token registered"; binary integrity; confidentiality.
software
Guarantee. At the last successful challenge (≤ 5 min ago if the host is still online and answering):
- The reported
build_hashis onblessed_buildsand not revoked (T20). The hash is self-reported: the agent computes it and the coordinator has no way to measure the running process. A modified agent can report the blessed hash of an unmodified release. Binding the hash to the running code needs a hardware root (TPM quote / Secure Enclave), which is the reservedhardwaretier. - The host signed
neuronpool-build-attestation\n{nonce}\n{build_hash}(register) andneuronpool-host-challenge\n{nonce}\n{build_hash}\n{posture}(challenge) with the registered Ed25519sign_pubkey(T19, T21). - Posture policy:
secure_boot !== false. Unknown (null) is allowed. Explicitsecure_boot: falsedemotes tonone. SIP / lockdown /debugger_blockedare collected and signed but not gated (T21.4postureMeetsTier).
Anyone can independently check the hash against Rekor via GET /verify or GET /v1/blessed-builds/:sha256 (T86). Auto-updating hosts re-check manifest signature + cosign identity + Rekor before swapping bits (T89).
How. Run a release binary from the GitHub Release (not tsx / dev). Register with pubkeys. Stay in the 5-min challenge loop. Pass T25 probation (20 canaries, age ≥ 24 h) before public leases. Return logprobs on complete or the host is marked unverifiable and dropped from public (T102).
Buyer reliance.
- The host says it runs a blessed build of the open-source agent and still holds the key it registered, as of the last challenge. Treat this as an honest-host signal backed by reputation, canaries, and T102 sampling — not as proof of the running binary.
- Completions that carry
X-NeuronPool-Attestationwere signed by that host's key (T23 / T103 — see Verifying a response). - Public jobs may be T102-sampled. A mismatch costs reputation; quarantine removes the host from public.
Explicitly not claimed.
- The operator cannot read the prompt. They can. Sealing stops at the agent process (T22). This is the sentence T27 exists to keep in writing.
- The listed weights are what ran. That is T102/T103, sampled, statistical.
- Secure Boot / SIP / no-debugger in the strong sense. Only "did not report Secure Boot off" is enforced;
nullpasses. - macOS Hardened Runtime,
PT_DENY_ATTACH, notarization (T28 shim + posture are in tree;release.ymlrunsnotarytoolwhen Apple secrets exist).
edr
Guarantee. Everything software guarantees, plus: this challenge cycle, the org's configured EDR adapter returned verified for the device id the agent reported (packages/host-agent/src/edr.ts). Falcon (CrowdStrike) checks Hosts + Zero Trust Assessment: device exists, sensor last seen within 10 minutes, hostname/OS match, assessment.overall >= org.min_score (T94).
edr requires software first. An EDR sensor does not replace the blessed-build proof. Failure (offline sensor, unknown AID, low score, provider outage, decrypt failure, disabled config) leaves the host at software — it does not crash the challenge path.
How. Host is in an org; org writes org_edr (provider, sealed credentials, min_score, min_trust, enabled). Agent reports { provider, device_id } at register and every challenge. Coordinator calls resolveEdrTrust after the software challenge verifies.
Buyer reliance. For tenant-pool traffic, an org can set policy min_trust: "edr" (T96) or org_edr.min_trust. Public buyers can send X-NeuronPool-Min-Trust: edr and will 503 if no such public-eligible host is online (T24).
Not proven. Confidential computing. Falcon ZTA is a vendor score, not a memory-encryption proof. Defender for Endpoint and SentinelOne adapters are stubs (contract tests pass; production mapping is a hand-off — see edr-adapters.md).
hardware
Guarantee. None today. TRUST_LEVELS includes the rank so min-trust filters, headers, and the attestation endpoint sort it above edr. evaluateTrust and verifyChallengeAnswer never return it. resolveEdrTrust never promotes to it.
Roadmap (T72 software scaffold; rank reserved). TPM 2.0 quotes over PCR 0–7 and NVIDIA CC via NRAS exist as in-tree fixtures (hardware-tier-gpu.md). Verification does not persist or grant hardware. T28 (PT_DENY_ATTACH shim + posture) is in tree; notarization CI is gated on Apple secrets (DAN-144). T71 is the same class of macOS Secure Enclave scaffold (hardware-tier-macos.md).
Buyer reliance. If you send X-NeuronPool-Min-Trust: hardware you get 503 with message No hardware-tier hosts online. That is the honest response, not a silent downgrade.
How a host moves
register ──evaluateTrust──► none | software
│
heartbeat every 15 s
│
challenge due? (5 min)
│
answer signed nonce‖build_hash‖posture
│
verifyChallengeAnswer ──fail──► none
│
pass ── software
│
resolveEdrTrust (if org + sensor)
│
verified ──► edr
else ──► software (base)
Revoke (POST /v1/hosts/:id/revoke, T26) stamps revoked_at and refuses heartbeat/lease/re-register. It also nulls T19.4 prev_sign_pubkey so a leaked previous key cannot keep answering challenges. Rotate identity keys with neuronpool keys rotate / POST /v1/host/keys/rotate (old-key-signed handover; previous sign key valid for challenges for 24 h). Reputation quarantine (reputation < 40) and unverifiable=1 remove public eligibility without necessarily changing the tier string.
What the buyer sends and sees
| Input | Effect |
|---|---|
| (omit) | min_trust = api_keys.min_trust or software |
X-NeuronPool-Min-Trust: software | Public hosts at software or above (incl. edr) |
X-NeuronPool-Min-Trust: edr | Only edr/hardware. 503 if none online (and lower-tier hosts existed, or always for hardware) |
X-NeuronPool-Min-Trust: hardware | Always 503 until T72 grants the tier |
X-NeuronPool-Min-Trust: none | Valid header. Public still excludes none hosts via the public-eligibility filter |
| Response header | Meaning |
|---|---|
X-NeuronPool-Trust | Serving host's tier (none/software/edr/hardware) |
X-NeuronPool-Host | First 12 hex chars of sha256(host id) — not the raw id |
X-NeuronPool-Pool | Pool id when the job was pool-scoped |
X-NeuronPool-Coordinator | coordinator_id (federation-ready) |
X-NeuronPool-Attestation | Host signature; see below |
Inference-Id | Job id (also the attestation message prefix) |
GET /v1/providers/attestation (public, Cache-Control: max-age=60) returns online, non-revoked hosts as { host, os, trust_level, build_hash, version, sign_pubkey, last_challenge_at, reputation_band } with no account ids (T24). build_hash / version are omitted for none hosts.
Verifying a response
Two signatures exist. The coordinator puts one of them on X-NeuronPool-Attestation and strips both from the buyer JSON (stripAttestation):
- T23.2 attestation —
job_id ‖ sha256(content). Use verify-response.md when the host did not send a T103 commitment (legacy complete). - T103 commitment —
job_id ‖ sha256(content) ‖ sha256(canonical logprobs JSON). Preferred when present. This is what current agents send.
T103 verifier (same key as T23; extra 32 bytes):
import { ed25519 } from "@noble/curves/ed25519.js";
import { sha256 } from "@noble/hashes/sha2.js";
function canonicalLogprobsJson(logprobs) {
const rows = Array.isArray(logprobs) ? logprobs : [];
return JSON.stringify(
rows.map((t) => [
typeof t.token_id === "number" ? t.token_id : null,
t.token,
t.logprob,
(t.top ?? []).map((x) => [typeof x.token_id === "number" ? x.token_id : null, x.token, x.logprob]),
]),
);
}
const jobId = new TextEncoder().encode(inferenceId);
const contentHash = sha256(new TextEncoder().encode(content));
const logprobsHash = sha256(new TextEncoder().encode(canonicalLogprobsJson(logprobs)));
const msg = new Uint8Array(jobId.length + contentHash.length + logprobsHash.length);
msg.set(jobId, 0);
msg.set(contentHash, jobId.length);
msg.set(logprobsHash, jobId.length + contentHash.length);
const sig = Uint8Array.from(atob(header), (c) => c.charCodeAt(0));
const pub = Uint8Array.from(atob(signPubkey), (c) => c.charCodeAt(0));
ed25519.verify(sig, msg, pub);
sign_pubkey comes from GET /v1/providers/attestation (match X-NeuronPool-Host) or from GET /v1/hosts if you own the host. Do not log prompt or response content. A pass means that key signed that job's claimed content (and logprobs). It is not a TEE quote and not a T102 pass.
Posture bits (T21.1 policy constants)
Collected by packages/host-agent/src/posture.ts (best-effort; missing sensor → null, never throws):
| Bit | OS | Gated for software? |
|---|---|---|
sip | macOS (csrutil status) | No |
secure_boot | Linux (mokutil / lockdown sysfs), Windows (Confirm-SecureBootUEFI) | Yes: false rejects; null allowed |
lockdown | Linux kernel lockdown LSM | No |
debugger_blocked | Best-effort ptrace / kernel debug | No (T28 reports true only when the shim armed PT_DENY_ATTACH) |
none has no posture bar. edr / hardware skip postureMeetsTier's software check (if (tier !== "software") return true) because those tiers are decided after the software answer already passed.
Comparison with Darkbloom (Eigen Labs)
T27 asks for an honest comparison. The Darkbloom column is as publicly described (Apple-Silicon-only hosts, hardware attestation + MDM, proprietary agent). It is not a reverse-engineering of their coordinator. NeuronPool column is this repository.
| Darkbloom (public description) | NeuronPool (this repo) | |
|---|---|---|
| Host OS | Apple Silicon | Linux, Windows, macOS (llama.cpp; MLX on Mac) |
| Default public trust | Hardware attestation + MDM | software (blessed binary + challenge). hardware not granted |
| Operator-blind prompts | Claimed via hardware isolation on enrolled Macs | Not at software or edr. Worker edge also sees plaintext (T22) |
| Build blessing | Proprietary blessed-hash check | Offline release key + cosign keyless + public Rekor (T20/T86/T89). Anyone can re-check |
| Agent source | Proprietary | Apache-2.0 agent + published protocol v1; coordinator BSL 1.1 |
| Confidentiality on the control plane | E2E sealed (their docs) | Same family (X25519 + XChaCha20-Poly1305). D1/DO ciphertext; Worker isolate plaintext |
| Inference verification | Not in our tree | T102 spot-checks + T103 commit-reveal, public jobs only, statistical |
| Enterprise posture | MDM | Optional EDR tier (Falcon implemented) (T94) |
| Free / social path | Self-route to own Macs | Pools: any OS, never billed, never scored |
| Fee | 0 % alpha (public) | PLATFORM_FEE_BPS default 0 |
NeuronPool does not claim feature-parity with Darkbloom's hardware attestation. The software tier is a different product: a verifiable open-source binary on commodity PCs, with sampled logprob checks, not a Secure Enclave. Where Darkbloom is narrower (Mac, MDM) and stronger on operator-blindness if their hardware story holds, NeuronPool is broader (Linux/Windows, pools, public Rekor) and weaker on host-side confidentiality until T72.
Buyer checklist
- Set
X-NeuronPool-Min-Trust(orapi_keys.min_trust) to the floor you mean. Default issoftware, notedr. - Read
X-NeuronPool-Truston the response — the coordinator does not silently upgrade the header. - Verify
X-NeuronPool-Attestationagainst the hostsign_pubkey(T23 or T103 above). - Treat
softwareas "blessed agent, hostile operator." Treatedras "blessed agent, org EDR agrees the device is theirs." Do not treat either as a confidential VM. - If you need operator-blind inference, wait for
hardwareor run the model on machines you already trust (self/ tenant pool) and accept that the hosted Worker edge still decrypts.