Modello di sicurezza dei token
I token L402 sono composti da due parti unite da::
- Macaroon — JSON codificato in base64 contenente
{hash, exp}. Firmato tramite SHA-256. Non può essere falsificato senza conoscere il preimage. - Preimage — il segreto a 32 byte che, quando viene sottoposto a hashing con SHA-256, deve corrispondere all’hash incorporato nel macaroon.
Protezione dal replay
l402-kit include una protezione integrata dal replay. Ogni preimage può essere utilizzato una sola volta:401 Token already used.
Store predefinito: Set in memoria. Ciò significa:
- I riavvii azzerano lo store di replay (i token diventano riutilizzabili dopo i riavvii)
- Più istanze non condividono lo stato
Scadenza dei token
I token contengono un campoexp (timestamp Unix in ms). L’SDK rifiuta automaticamente i token scaduti.
TTL predefinito: 1 ora (impostato dal provider Lightning durante la creazione della fattura).
HTTPS è obbligatorio
Non utilizzare mai L402 su HTTP semplice in produzione. Il macaroon e il preimage vengono trasmessi nell’headerAuthorization. Tramite HTTP, sono esposti agli attaccanti di rete.
Rate limiting
L402 verifica i token crittograficamente, senza consultare un database — quindi è economico. Ma la creazione di fatture Lightning (la risposta 402) chiama l’API del tuo provider Lightning. Proteggi la creazione delle fatture con un rate limiter per prevenire attacchi DoS:Gestione dei segreti
Non inserire mai le chiavi API nel codice sorgente. Usa le variabili d’ambiente:.env + dotenv (mai committato su git).
Autenticazione degli endpoint amministrativi
Se esponi endpoint di amministrazione o statistiche, non accettare mai segreti tramite parametri di query nell’URL. Gli URL vengono registrati integralmente da reverse proxy, CDN e provider cloud — inclusa la query string.Igiene delle chiavi Supabase
Usa correttamenteSUPABASE_SERVICE_KEY (solo lato server) rispetto a SUPABASE_ANON_KEY (sicuro da esporre ai client):
| Chiave | Utilizzo | Bypassa RLS? |
|---|---|---|
anon | Estensione VS Code, client browser | No |
service_role | Funzioni API lato server | Sì |
pro_access) devono usare la service key — mai la anon key. Le policy RLS sulle tabelle sensibili non devono concedere accesso alla chiave anon.
Content Security Policy
Se servi un frontend insieme alla tua API, assicurati che la tua CSP non blocchi il flusso L402:Gestione dei dati — eliminazione dei dati utente
Gli utenti possono eliminare tutta la loro cronologia dei pagamenti e l’abbonamento Pro direttamente dall’estensione VS Code in qualsiasi momento (Impostazioni → Zona pericolosa). L’estensione chiama:- Tutte le righe in
paymentsdoveowner_address = ? - Tutte le righe in
pro_accessdoveaddress = ?
L’estensione richiede all’utente di digitare il proprio indirizzo Lightning esattamente prima che il pulsante di eliminazione venga abilitato — una conferma in stile GitHub per le azioni distruttive.
Privacy e minimizzazione dei dati
l402-kit è progettato per raccogliere il minimo di dati necessari per funzionare. Ecco cosa viene memorizzato, perché e come rendere più sicuro ogni campo.Cosa viene memorizzato
| Tabella | Campo | Perché | Sensibilità |
|---|---|---|---|
payments | preimage | Protezione dal replay + prova di pagamento | ⚠️ Media — usa l’hash al suo posto (vedi sotto) |
payments | owner_address | Attribuire i ricavi all’indirizzo Lightning | Bassa — gli indirizzi Lightning sono pubblici |
payments | amount_sats | Statistiche della dashboard | Bassa |
payments | endpoint | Analitiche per endpoint | Bassa–media |
pro_access | address | Verificare l’abbonamento Pro | Bassa — pubblico |
waitlist | email | Inviare email di benvenuto e di rilascio | ⚠️ Alta — PII reale, cifrare o omettere |
waitlist | lightning_address | Segnale opzionale di identità | Bassa |
Memorizza gli hash dei preimage invece di archiviarli in chiaro
Il preimage è il segreto a 32 byte che prova che un pagamento Lightning è stato effettuato. Memorizzarlo in chiaro significa che una violazione del database espone ogni prova. Memorizza invece l’hash SHA-256 — è già pubblico (incorporato nella fattura BOLT11) e sufficiente per la protezione dal replay:Proteggi le email della waitlist
Gli indirizzi email sono le uniche vere PII nel sistema. Opzioni in ordine di protezione crescente:Dimostra la proprietà del wallet prima di eliminare i dati (LNURL-auth)
L’endpoint/api/delete-data dovrebbe accettare richieste solo dal reale proprietario dell’indirizzo Lightning. Usa LNURL-auth per dimostrare la proprietà crittograficamente — l’utente firma una sfida del server con la chiave privata del proprio Lightning wallet, senza necessità di password o account:
Consulta il diagramma di flusso completo per la sequenza completa con lo stato di Supabase.
Questo garantisce che nessuno possa eliminare i record di un altro utente, anche conoscendo l’indirizzo Lightning.
Checklist
Prima di andare in produzione
Prima di andare in produzione
- HTTPS applicato su tutti gli endpoint
- Chiavi API nelle variabili d’ambiente, non nel codice sorgente
- Gli endpoint di amministrazione/statistiche usano l’autenticazione tramite header, non parametri URL
?secret= - La chiave
service_roledi Supabase è usata lato server; la chiaveanonsolo sui client - Le tabelle Supabase sensibili non hanno policy SELECT per
anon - L’endpoint di eliminazione dati (
/api/delete-data) usa la service key, mai la anon - Rate limiter sulla creazione delle fatture
- Protezione dal replay testata (prova a riutilizzare un preimage → atteso 401)
- Scadenza del token testata (imposta un TTL breve in sviluppo, conferma 401 dopo la scadenza)
- Preimage memorizzati come hash SHA-256, non come segreti in chiaro
- Email della waitlist cifrate a riposo o scartate dopo l’invio
-
/api/delete-datarichiede la prova LNURL-auth della proprietà del wallet
Per API ad alto traffico
Per API ad alto traffico
- Store di replay basato su Redis (condiviso tra le istanze)
- Monitoraggio dei tassi di risposta 402 (picco = potenziale DoS)
- Failover del provider Lightning (fallback BlinkProvider → LNbitsProvider)
- Monitoraggio della pagina di stato del tuo provider Lightning (es. status.blink.sv)