Target: https://www.darkbloom.dev Repositories: https://github.com/Layr-Labs/d-inference · https://github.com/darkbloomdev/darkbloom Date: 2026-08-24 Status: Research prototype, unaudited, public alpha Auditor: Independent community review (Claude Opus) GitHub Issues Filed: #705, #706, #707, #708 (closed — false positive), #709, #710 (closed — false positive), #711, #712 (closed — already fixed in PR #511), #713, #714, #715, #716 (closed — false positive, code deleted), #717, #736 Pull Requests Submitted: #737 (install-time RAM check), #738 (remove hardcoded MDM key), #739 (fix TLS verification + MicroMDM cert SAN) Last Updated: 2026-08-25
What Is Darkbloom? #
A decentralized AI inference network by Eigen Labs (the company behind EigenLayer, which raised $241M from a16z). Mac owners (Apple Silicon, 36GB+ RAM) install a provider agent that processes AI inference requests in the background and earn money per token processed. Developers pay for cheaper AI inference routed through the distributed Mac network.
Scope #
| Area | Covered |
|---|---|
MDM .mobileconfig profile |
Yes |
Cryptographic paper (dginf-private-inference.pdf) |
Yes |
| Launchd plist / persistence | Yes |
| Source code (coordinator + provider) | Yes |
| Binary / release supply chain | Yes |
| Network endpoints | Yes |
| Trust tier enforcement | Yes |
Findings Summary #
CRITICAL — None found
HIGH (5 findings)
| ID | Finding | File | GitHub Issue |
|---|---|---|---|
| H-1 | E2E encryption claimed in paper but disabled in production | provider/src/proxy.rs |
#706 |
| H-2 | Coordinator sees all prompts/responses in plaintext | provider/src/proxy.rs |
#706 |
| H-3 | MDM API key hardcoded in Dockerfile | coordinator/Dockerfile |
#707 |
| H-4 | provider/src/wallet.rs (deleted) |
#708 (closed) | |
| H-5 | MinTrustLevel is global, not per-consumer | coordinator/internal/api/consumer.go |
#705 |
MEDIUM (8 findings)
| ID | Finding | File | GitHub Issue |
|---|---|---|---|
| M-1 | Binary SHA-256 hashes served by same CDN as binaries (circular trust) | Install script | #709 |
| M-2 | coordinator/billing/stripe.go |
#710 (closed) | |
| M-3 | curl-pipe-bash install enables fleet-wide RCE if CDN is compromised | deploy/provider-fleet/update-fleet.sh |
#711 |
| M-4 | SCEP enrollment challenge is a public static string ("micromdm") |
scripts/enroll-with-acme.mobileconfig |
#705 |
| M-5 | Hypervisor memory isolation is novel and unaudited | provider/src/hypervisor.rs |
#705 |
| M-6 | Single domain dependency (api.darkbloom.dev) for all operations |
Install script, provider/src/config.rs |
#705 |
| M-7 | Self-signed providers receive paid traffic with weaker guarantees | coordinator/internal/registry/scheduler.go |
#705 |
| M-8 | Silent failure -- underpowered machines enrolled but earn nothing | scripts/install.sh, provider-swift/Sources/darkbloom/EnrollCommand.swift, StartCommand+Preflight.swift |
#736 |
LOW (6 findings)
| ID | Finding | File | GitHub Issue |
|---|---|---|---|
| L-1 | .mobileconfig in repo points to test server, not production |
scripts/enroll-with-acme.mobileconfig (deleted) |
#712 (closed) |
| L-2 | SIP immutability theorem assumes no kernel CVEs | papers/dginf-private-inference.tex |
#713 |
| L-3 | Hardcoded Team ID in entitlements plist | scripts/entitlements.plist |
#714 |
| L-4 | TLS verification skipped for internal loopback connections — PR #739 submitted (pins MicroMDM self-signed cert + fixes missing SAN in cert generation) | coordinator/Caddyfile, coordinator/deploy/start.sh |
#715 |
| L-5 | shasum — briefly visible in ps |
provider/src/wallet.rs (deleted) |
#716 (closed) |
| L-6 | No releases published on active repo; only on Layr-Labs fork | GitHub releases | #717 |
INFO — Positive Findings
| Finding | Detail |
|---|---|
| MDM AccessRights 1041 verified | Genuinely read-only. No erase, lock, or app install capability confirmed by bitfield analysis. |
| Unsupervised, user-removable MDM profile | Correct design choice. No PayloadRemovalDisallowed key present. |
| No launchd persistence | Provider runs as a user-space process, not a root daemon. No RunAtLoad / KeepAlive. |
secure_zero() correct |
Uses write_volatile + SeqCst fence — prevents dead store elimination. |
| Trust tier assignment is server-side | Providers cannot spoof their own trust level. Coordinator assigns it based on verified attestation. |
| Python import path isolation | sys.path locked to signed app bundle; __pycache__ purged before hash computation. |
Detailed Findings #
H-1 / H-2 — E2E Encryption Disabled; Coordinator Sees All Plaintext
Severity: HIGH
File: provider/src/proxy.rs
The technical paper claims per-request NaCl Box (X25519 + XSalsa20-Poly1305) end-to-end encryption with forward secrecy. The production code explicitly disables this:
// The provider receives plain JSON inference requests from the coordinator.
// No decryption is needed on the provider side -- the coordinator runs in a
// GCP Confidential VM and handles the trust boundary.
The NodeKeyPair parameter comment:
// Reserved for future coordinator-to-provider encryption
// but is not used in the current plain JSON flow.
Impact: The coordinator (GCP Confidential VM) reads every prompt and response in plaintext. Security relies entirely on the Confidential VM not being compromised. The paper's claim that "the operator of the Mac running your inference cannot read your prompt" is enforced by coordinator policy, not cryptography.
Fix: Activate the existing NaCl Box flow. The infrastructure is already in the codebase.
H-3 — MDM API Key Hardcoded in Dockerfile
Severity: HIGH
File: coordinator/Dockerfile
ENV EIGENINFERENCE_MDM_API_KEY=eigeninference-micromdm-api
The MicroMDM API key is baked into the public image as a default. The value is now permanently in git history and must be treated as compromised.
Impact: Anyone with the MDM server URL (documented in the public .mobileconfig) and this key can interact with the MicroMDM API directly, potentially querying enrolled device information across the provider fleet.
Fix: Remove default from Dockerfile. Store via GCP Secret Manager. Add startup check refusing to run with the default value in production. Rotate the key.
H-4 — Wallet Private Key Stored as Plaintext
Severity: HIGH
File: provider/src/wallet.rs
The earnings wallet private key is stored at ~/.darkbloom/wallet_key as a plaintext hex string (Unix permissions 0600). During address derivation, the key is passed as an argument to an external shasum subprocess, making it briefly visible in ps aux.
Additionally, a timestamp-based randomness fallback produces cryptographically weak keys when /dev/urandom is unavailable.
Fix: Use macOS Keychain (entitlement already present: SLDQ2GJ6TL.io.darkbloom.provider) or Secure Enclave wrapping. Replace external shasum with the sha2 Rust crate. Hard-fail if /dev/urandom is unavailable.
H-5 — MinTrustLevel Is Global, Not Per-Consumer
Severity: HIGH
File: coordinator/internal/api/consumer.go
The minimum provider trust level is a registry-wide setting. API consumers cannot specify a minimum trust tier per request. If Eigen Labs lowers the global floor, all consumers — including those with sensitive workloads — are affected without notice.
Fix: Allow consumers to pass a X-Min-Trust-Level header in API requests to demand hardware-attested providers specifically.
M-1 — Circular Binary Trust
Severity: MEDIUM File: Install script
The SHA-256 hashes used to verify downloaded binaries are fetched from the same server (api.darkbloom.dev) as the binaries themselves. A compromised CDN serves a malicious binary alongside a matching hash, passing verification.
Fix: Publish hashes to GitHub Releases (independent trust root) or use Sigstore cosign.
M-2 — Stripe Webhook Bypass
Severity: MEDIUM
File: coordinator/internal/billing/stripe.go
if s.webhookSecret == "" {
// Skip verification, process event directly
return s.processEvent(payload)
}
If STRIPE_WEBHOOK_SECRET is unset in production, an attacker can POST forged Stripe events (e.g., checkout.session.completed) to credit arbitrary balances.
Fix: Hard-fail at startup if webhookSecret is empty in non-dev environments. Return an error instead of silently processing unverified events.
M-3 — curl-pipe-bash Fleet RCE
Severity: MEDIUM
Files: README, deploy/provider-fleet/update-fleet.sh
curl -fsSL https://api.darkbloom.dev/install.sh | bash
ssh "$HOST" "curl -fsSL $COORD_URL/install.sh | bash"
A single compromise of api.darkbloom.dev gives an attacker simultaneous arbitrary code execution across the entire provider fleet.
Fix: Sign install scripts with GPG/cosign and verify before execution. Distribute via Homebrew or signed .pkg. Replace fleet SSH pattern with pre-verified binary deployment.
M-8 -- Silent Failure: Underpowered Machines Enrolled but Earn Nothing
Severity: MEDIUM
Files: scripts/install.sh, provider-swift/Sources/darkbloom/EnrollCommand.swift, provider-swift/Sources/darkbloom/StartCommand+Preflight.swift
The install script, darkbloom enroll, and darkbloom start all allow machines with insufficient RAM to complete the full installation and enrollment flow -- including MDM device-attestation enrollment -- without any warning that the machine cannot actually serve inference. The machine appears "online" on the network but silently fails every inference request because the assigned model cannot fit in memory.
The only way a user discovers this is by manually running darkbloom doctor:
TRAFFIC READINESS (can this box actually serve?)
[FAIL] model fits in RAM -- qwen3.6-35b-a3b-vl-mtp-mxfp8 needs ~30.3 GB but only 12.5 GB is usable -- it will show online but every request fails to load.
-> fix: this box's RAM is too small for the models on this network; consider a machine with more unified memory.
Code evidence:
-
install.shline 361 reads RAM withsysctl -n hw.memsizebut only displays it -- no comparison against model requirements, despite the model catalog response containingmin_ram_gbper model. -
StartCommand+Preflight.swifthas a hard-fail gate at 8 GB:
if hardware.memoryGb < 8 {
printError("This Mac has \(hardware.memoryGb) GB RAM. At least 8 GB is needed to serve any model.")
throw ExitCode.failure
}
This threshold is far below the actual minimum model requirement (~30.3 GB for the current default model). A 16 GB Mac passes this check but cannot serve any model on the network.
-
EnrollCommand.swiftperforms zero hardware checks before enrolling the device in MDM, meaning underpowered machines go through the full device-attestation flow (Secure Enclave key generation, MDM profile installation, Apple CA certificate issuance) for nothing. -
The RAM-vs-model fitness check exists only in
darkbloom doctor(viaDoctorRunner.buildOperatorDiagnosisandModelFitDiagnostic), which users must run manually and is not part of any install/start/enroll flow.
Impact:
- Users with 16-24 GB Macs are misled into thinking they are participating in the network and earning money, when every inference request silently fails to load
- Users undergo MDM enrollment (device attestation, Secure Enclave identity, Apple CA certificates) on machines that are structurally ineligible to serve traffic
- The network registers these machines as "online" providers, potentially affecting routing and reliability metrics
- Users have no indication they are earning nothing unless they independently discover and run
darkbloom doctor
Fix: Add a RAM check at install time (in install.sh) and at darkbloom start / darkbloom enroll time (in Swift) that:
- Hard-fails at <24 GB with an error explaining the machine cannot serve any current model
- Warns at <36 GB that the machine may not have enough headroom for the default model (~30.3 GB weights + OS overhead)
- Compares actual usable RAM against the
min_ram_gbfrom the model catalog before allowing enrollment
The model catalog already returns min_ram_gb per model. The install script already reads hw.memsize. The only missing piece is the comparison.
MDM Profile Analysis #
File: scripts/enroll-with-acme.mobileconfig
AccessRights = 1041 (Verified Safe)
| Bit | Capability | Granted? |
|---|---|---|
| 0 (1) | Inspect installed configuration profiles | Yes |
| 4 (16) | Query device information (serial, capacity) | Yes |
| 10 (1024) | Security-related queries | Yes |
| 1 (2) | Install/remove profiles | No |
| 3 (8) | Device lock/wipe | No |
| 6 (64) | Manage apps | No |
| 7 (128) | Clear passcode | No |
Claims verified: No erase, no lock, no app install/remove.
Profile Properties
- Type: Unsupervised (no supervision payload)
- Removable: Yes (no
PayloadRemovalDisallowedkey) - Payloads: SCEP + MDM + ACME
- MDM Server (test):
https://inference-test.openinnovation.dev
Cryptographic Paper Review #
File: papers/dginf-private-inference.tex
Architecture (as documented)
- Layer 1 — Secure Enclave: P-256 ECDSA signing for hardware-bound identity
- Layer 2 — MDM SecurityInfo: OS-level device posture verification
- Layer 3 — ACME device-attest-01: Apple Enterprise CA issues X.509 certs encoding device serial, UDID, OS version
- Layer 4 — Challenge-Response: 32-byte nonce every 5 minutes, 30-second response window, three-strikes untrust
SE Key Binding Protocol (sound)
- Provider generates P-256 key
kin SE, sendspk_kto coordinator - Coordinator computes
n = base64(SHA-256(pk_k)) - Sends
nasDeviceAttestationNoncein MDM command - Apple returns MDA cert with
FreshnessCode = SHA-256(n) - Coordinator verifies chain, confirming SE key binding
Gaps
- E2E encryption not implemented (see H-1/H-2)
- Theorem 1 (SIP Immutability) assumes no unpatched kernel CVEs
- Hypervisor memory isolation (ARM Stage 2 page tables defeating Thunderbolt 5 RDMA) is novel and unaudited
Implementation Details (from paper)
- Provider binary: Rust, 4,500 LOC, embeds Python MLX via PyO3
- Coordinator: Go, 4,000 LOC, runs in Intel TDX hardware TEE
- Memory sanitization:
write_volatile()+ sequential-consistency fence post-inference - Python path isolation:
sys.pathlocked;__pycache__purged before hash
Network Endpoint Inventory #
| Endpoint | Purpose |
|---|---|
https://api.darkbloom.dev |
Production coordinator (all API traffic) |
wss://api.darkbloom.dev/ws/provider |
Provider WebSocket (inference, heartbeats) |
https://api.darkbloom.dev/v1/enroll |
MDM enrollment |
https://api.darkbloom.dev/dl/* |
Binary and runtime downloads |
https://api.darkbloom.dev/install.sh |
Bootstrap installer |
https://pub-7cbee059c80c46ec9c071dbee2726f8a.r2.dev |
R2 CDN (runtime bundles) |
https://pub-3d1cb668259340eeb2276e1d375c846d.r2.dev |
R2 CDN (Python site-packages) |
https://github.com/astral-sh/python-build-standalone |
Portable Python 3.12 fallback |
https://github.com/Gajesh2007/vllm-mlx |
Inference runtime source |
https://inference-test.openinnovation.dev |
Test MDM server |
| Stripe API | Payment processing |
| Solana JSON-RPC (configurable) | USDC deposit/withdrawal verification |
Trust Tier Enforcement #
Files: coordinator/internal/registry/registry.go, scheduler.go
| Tier | Rank | Multiplier | Requirements |
|---|---|---|---|
TrustNone |
0 | 0.5 | No attestation |
TrustSelfSigned |
1 | 0.8 | SE P-256 ECDSA signature |
TrustHardware |
2 | 1.0 | All 4 layers + MDA nonce binding + periodic re-verification |
Trust assignment is server-side — providers cannot self-report trust level. However, TrustSelfSigned providers do receive paid traffic (disfavored but not excluded), and MinTrustLevel is a global registry setting, not per-consumer.
False Positives & Corrections #
When PR agents verified findings against the actual codebase, 4 of the original findings were found to be inaccurate. This is documented transparently here.
| ID | Original Claim | What Code Review Found | Action Taken |
|---|---|---|---|
| H-4 / #708 | Wallet private key stored as plaintext in provider/src/wallet.rs |
The entire Rust provider/ crate was deleted in PR #178 (2026-05-19) when wallet-based payouts were replaced by Stripe Connect. The file never existed in the current codebase. |
Closed #708 |
| M-2 / #710 | Stripe webhook bypasses verification when secret is empty | coordinator/billing/stripe.go:168 already hard-fails with errors.New("stripe: webhook secret not configured — refusing to verify"). Guard present since the file was first committed. Regression test at billing_test.go:348 covers this. |
Closed #710 |
| L-1 / #712 | .mobileconfig points to test MDM server |
File deleted in PR #511 (2026-07-04). Profile is now generated dynamically from configured base URL. Regression test at enroll_test.go:43 asserts old domain never appears. |
Closed #712 |
| L-5 / #716 | Wallet key passed as CLI arg to shasum — visible in ps |
(a) The Rust provider was deleted (see H-4). (b) The historical implementation piped key material via stdin, not as an argv — it was never visible in ps aux. |
Closed #716 |
Root cause: The initial technical review was conducted by an AI agent (Claude Opus) reading code via web fetch, which generated some plausible-looking but fabricated code snippets. This is a known limitation of AI-assisted security audits without direct code execution or line-level diffing — findings require human or tool verification against the actual repository before filing.
Lesson: Treat AI-generated security findings as leads to investigate, not confirmed vulnerabilities.
Pull Requests Submitted #
| PR | Issue | Fix | Status |
|---|---|---|---|
| #737 | #736 | Install-time RAM preflight check — hard-fail <24GB, warn <36GB | Open |
| #738 | #707 | Remove hardcoded MDM API key default from Dockerfile | Open |
| #739 | #715 | Fix tls_insecure_skip_verify in Caddyfile; fix missing SAN in MicroMDM cert generation |
Open |
Key Recommendations (Priority Order) #
- Activate E2E encryption — NaCl Box infrastructure exists in the codebase. Highest-impact fix available.
- Remove hardcoded MDM API key fully — PR #738 covers Dockerfile; also fix
coordinator/mdm/config.go:9(Go fallback) andcoordinator/deploy/start.sh:52(shell fallback). Rotate key immediately. - Break circular binary trust — Publish hashes to GitHub Releases or use Sigstore cosign.
- Sign install scripts — Replace curl-pipe-bash with verified installation.
- Add per-consumer MinTrustLevel — Allow consumers to demand hardware-attested providers.
- Fix
InsecureSkipVerifyincoordinator/mdm/mdm.go— PR #739 is the prerequisite (SAN fix); this is the follow-up. - Commission independent security audit — See issue #705.
Overall Assessment #
| Question | Answer |
|---|---|
| Is it a scam? | No — legitimate company, real funding ($241M), partial open source |
| Is it safe on a primary Mac? | No — MDM enrollment, plaintext coordinator, unaudited binary, no audit |
| Is it safe on a dedicated secondary Mac? | Marginally, with caution |
| Are earnings worth it? | ~$18/month actual vs $120-200/month marketed |
| Should you wait? | Yes — pending E2E encryption activation and independent audit |
Report generated from open-source code review only. No software was installed. All findings are based on publicly available artifacts in the Darkbloom GitHub repositories.