**Audience:** third-party security auditors, and the Archipelago team.
**Purpose:** verify the Phase 10 security claims *independently*, without trusting the
project's own test harness.
**Status:** LIVING — sections are marked ✅ verifiable now, ⏳ pending a plan still in
execution, or 🔒 hardware-gated. Do not read an unmarked absence as a passing result.
---
## 0. How to use this document
Every claim below follows the same four-part structure, and **all four parts matter**:
| Part | Why it exists |
|---|---|
| **Claim** | Stated so it can be falsified. A claim you cannot disprove is not a security claim. |
| **Reproduce the defect** | Check out the parent commit and demonstrate the bug. *A test that passes on both the fixed and unfixed code proves nothing.* |
| **Verify the fix** | Command + expected output, runnable without our harness wherever possible. |
| **Negative control** | Break the fix deliberately; confirm the check goes red on **exactly** that and nothing else. This is what separates verification from demonstration. |
**Do not skip "Reproduce the defect".** It is the only step that proves the fix addresses
something real, and it is the step most often omitted in security theatre.
### Trust posture
Where a claim can be checked from *outside* the codebase — an HTTP request from another host,
a `tar` listing, a file comparison across two machines — **prefer that over running our tests.**
Our tests are offered as convenience and as evidence of intent, not as proof. Every claim below
that can be externally checked says so explicitly.
---
## 1. Scope
### In scope — what Phase 10 claims
| ID | Claim | Severity | Status |
|---|---|---|---|
| KEY-01 | An already-provisioned node refuses every unauthenticated RPC that can mutate identity or credentials | **Critical** | ⏳ `10-01` in execution |
| KEY-02 | First-boot per-device secret generation is fail-closed, retried, self-healing, and has exactly one producer; the shipped rootfs contains no fleet-shared identity material | **High** | ✅ partially landed (`21043096`, `408b328c`), ⏳ single-producer + self-heal in progress |
| KEY-03 | The BIP-84 account private key is never imported into Bitcoin Core; the dead import path is deleted | **High** | ⏳ `10-05` in execution |
archipelago-restart-survive / uninstall, 5× green. See `tests/lifecycle/TESTING.md`.
Frontend: `cd neode-ui && npm run test` (vitest) and `npm run build`.
Rust: `cd core && cargo test -p archipelago`.
---
## 8. Known-accepted risks
Recorded so an auditor does not have to discover them by reading commit messages.
| Risk | Decision | Where |
|---|---|---|
| A node whose first-boot secret generation can never succeed will not serve TLS | Accepted. Mitigated by a build-time assertion on generator binaries, retry-with-backoff, and self-heal on subsequent boots — leaving genuinely-broken hardware as the residual | `10-03` |
| KEY-01's fix ships on the next scheduled OTA, not an emergency release | Deliberate. The Critical finding stays live on the fleet until that OTA | D-10 |
| `#[cfg(test)]` code implements `rand::CryptoRng` falsely | Accepted until KEY-05 retires it; contained to test builds | `seed.rs:656` |
---
## 9. Reporting a finding
If any check above fails, or you find something not covered: the audit format that produced this
work is `docs/security/ENTROPY-SEED-AUDIT-2026-07-31.md` — evidence as `file:line`, an explicit
severity, and a stated confidence. Findings that cannot be verified without hardware belong in an
UNVERIFIED section rather than being asserted.
Two corrections in that document are worth reading as calibration, because both were ours: F-10
**understated** its scope by a factor of 20, and the correction to it then **overstated** the
severity of two files within a day. Both are struck in place rather than rewritten.