From 9c4d2c132449c210d97e37f14153a3f6b99f9215 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 6 Jun 2026 21:00:14 +0200 Subject: [PATCH] docs(security-pathway): flag kind:21001 CLINK collision + rotation S3 settlement-receipt kind was provisionally 21001, but that kind is claimed by CLINK (Offers). Replace the speculative kind text in the cash-out diagram and the S3 row with an explicit DO-NOT-USE alert citing the 2026-06-02 collision, the aiolabs/satmachineadmin#44 rotation tracker, and the 22000-22099 target band. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/security-pathway-v1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/security-pathway-v1.md b/docs/security-pathway-v1.md index f7696d8..2b7cc8b 100644 --- a/docs/security-pathway-v1.md +++ b/docs/security-pathway-v1.md @@ -256,7 +256,7 @@ What we **do not** adopt and why (from the NIP survey): │ Lightning settles ▼ ┌─────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Settlement attestation (NIP-57-style receipt — kind:9735 or our own kind:21001) │ +│ Settlement attestation (NIP-57-style receipt — see kind-rotation note in §6 / S3 row) │ │ │ │ LNbits publishes (signed by the LNbits server key): │ │ { kind: 9735, │ @@ -303,7 +303,7 @@ None of those need to change. The new layers slot in *above* them. | **S0 — Seed‑URL pairing + ATM keypair separation** | Provisioning script generates a fresh `nsec` for the ATM (already does — we just stop overwriting it with the operator's). Operator pastes a one‑shot QR/seed URL containing `{atm_npub, operator_npub, relay_list, signed_delegation_token}` at ATM first boot. | G3 (most of it), G9 | 1 week | None — purely on our side. Use existing NIP‑26 spec. | | **S1 — NIP‑40 expiration on all kind‑21000** | Every RPC carries `["expiration", now+5min]`. Handler refuses past‑expiration. ATM clock check on boot (warn if drift > 60s). | G4 | 1–2 days | Relay must support NIP‑40 (most do). | | **S2 — NIP‑26 delegation enforcement in nostr‑transport** | Handler parses `delegation` tag, validates sig over conditions, checks conditions match the event, looks up operator pubkey in roster. Reject events without a valid delegation. | G3 (rest), G7 (partially) | 1–2 weeks | LNbits PR upstream (or vendored fork on `aiolabs/lnbits` branch `nostr-transport-nip26`). | -| **S3 — NIP‑57‑style settlement receipts** | After LNbits internal payment legs complete, publish a signed receipt event per settlement (and per leg if we want leg‑level audit). ATM subscribes; operator dashboard renders receipts side‑by‑side with `dca_settlements`. | G2, G7 | 1–2 weeks | Decide kind: `9735` (semantic abuse for non‑zap) vs. our own kind in `21001`/`21002` range. | +| **S3 — NIP‑57‑style settlement receipts** | After LNbits internal payment legs complete, publish a signed receipt event per settlement (and per leg if we want leg‑level audit). ATM subscribes; operator dashboard renders receipts side‑by‑side with `dca_settlements`. | G2, G7 | 1–2 weeks | **Kind allocation — DO NOT USE `kind:21001`.** That kind is claimed by CLINK (Offers) — collision caught during the 2026‑06‑02 CLINK primer review. Rotation off 21001 is tracked at `aiolabs/satmachineadmin#44`; target is the aiolabs reserved band **`22000–22099`** per the workspace rule in `~/dev/CLAUDE.md` (§ "Nostr kind allocations — avoid the CLINK band"). The earlier 21001 lock across `aiolabs/lnbits#22`, `aiolabs/satmachineadmin#17`, and the satmachine ATM is **SUPERSEDED** — pick the new kind before any of those land. Reusing `kind:9735` (zap receipt) is also off the table: NIP‑57 semantics don't apply to bitSpire cash‑out settlements. | | **S4 — NIP‑78 per‑machine config + fleet roster** | Operator publishes `kind:30078` config + `kind:30000` fleet list. Handler cross‑checks ATM npub ∈ fleet; reads max‑withdraw/fee policy from config. | G1, G9 | 1 week | Define config schema; backwards‑compat path for pre‑NIP‑78 machines. | | **S5 — `sender_pubkey` persistence + signed metadata in Payment.extra** | When the dispatcher writes a Payment row, it stamps `Payment.extra.sender_pubkey`, `delegation_root`, and an HMAC over the key fields keyed by the LNbits server's own secret. Mutation post‑write breaks the HMAC. | G2 (DB‑side), G5, G6 | 3–5 days | LNbits PR — fairly localised. | | **S6 — Rate limiting + roster‑gated auto‑account** | Auto‑account‑from‑npub only fires if the npub appears in some operator's NIP‑78 fleet OR if an explicit "open enrollment" flag is set. Relay/handler‑level rate limit per pubkey. | G8, G9 | 1 week | LNbits PR. |