Salta al contenuto
Tutti gli articoli
4 min di lettura

Il tuo workspace è un confine di sicurezza.

Perché i controlli di possesso appartengono a ogni lettura e scrittura, e perché un URL di attività non deve mai concedere accesso.

il team supastack

Deriva il possesso lato server

Un ID di record identifica qualcosa; non dimostra chi può leggerlo. supastack delimita i record utente per workspaceId. Il server risolve il workspace dell'utente autenticato e include quel confine quando legge o modifica un record.

Non trattare un ID di workspace inviato dal browser come prova di possesso. Il browser può richiedere un'azione, ma il contesto server fidato deve stabilire di chi è. Questa regola deve valere per stato delle attività, configurazione dei provider salvata, record di utilizzo e ogni risorsa propria del prodotto. Layout e componenti possono filtrare ciò che viene renderizzato, ma il rendering non è autorizzazione — il controllo appartiene al punto dove il record viene davvero letto o scritto.

Tutto il resto di questo post discende da quella regola: il possesso si deriva, non si richiede. Nel momento in cui un workspaceId inviato dal client viene considerato affidabile da qualche parte, ogni altro controllo diventa decorazione. Il post sull'autenticazione oltre il form di login spiega come la sessione stessa viene stabilita a monte di questa frontiera.

L'appartenenza fa parte del confine

La delimitazione risponde a quale workspace appartiene un record; l'appartenenza risponde se questo utente appartiene a quel workspace. Risolvi entrambe sul server. supastack modella workspace personali e di organizzazione con ruoli owner, admin e member — la guida ai workspace documenta il modello.

I ruoli aggiungono un secondo asse: un member può leggere ciò che solo un admin può cambiare. Tieni distinti i due controlli — «appartiene a questo workspace» e «può eseguire questa azione» — così una retrocessione o rimozione ha effetto sulla stessa frontiera di tutto il resto. Inviti e rimozioni fanno parte dello stesso ciclo di vita, non un ripensamento amministrativo.

I cambi di appartenenza devono anche avere effetto immediato. La prossima richiesta di un membro rimosso dovrebbe fallire alla frontiera, non quando un token in cache capita di scadere — un altro motivo per cui il controllo vive dove i record vengono letti, invece che dentro una credenziale emessa prima.

Testa le richieste che devono fallire

Un test che permette a un proprietario di recuperare un record dimostra il percorso felice. Non dimostra l'isolamento. Abbinalo a un secondo workspace che richiede lo stesso record, una richiesta anonima e una scrittura che tenta di sostituire un altro proprietario.

Verifica il comportamento esterno quanto il risultato persistito. Una richiesta rifiutata non deve mutare i dati di un altro workspace, e una risposta d'errore non deve far trapelare segreti né dettagli grezzi del database. Questi controlli mantengono il confine revisionabile quando l'implementazione cambia.

  • Un secondo workspace richiede lo stesso ID di record — rifiutato.
  • Una richiesta anonima colpisce lo stesso endpoint — rifiutata.
  • Un membro rimosso dal workspace riprova — rifiutato.
  • Una scrittura nomina un proprietario o workspace diverso — rifiutata, senza mutare nulla.
  • Le risposte d'errore restano generiche — niente segreti, niente dettagli dello schema.

Porta la regola nel tuo prodotto

Quando aggiungi una nuova tabella di prodotto, decidi il suo possesso prima di costruire la schermata. Includi workspaceId nel suo modello di persistenza, risolvi il workspace tramite la frontiera server esistente e usa quel contesto sia nelle operazioni di lista sia di dettaglio.

I worker in background richiedono la stessa cura. Un'attività in coda deve portare abbastanza contesto fidato per caricare il record giusto, mentre le credenziali dei provider restano sul server. Un job pianificato che carica righe per semplice ID è comunque dentro il confine. Una regola di possesso coerente è più facile da mantenere di una collezione di eccezioni per route.

La superficie API appartiene alla stessa frontiera. Le chiavi API del workspace e i webhook firmati in uscita portano con sé la delimitazione del workspace — una chiave non deve mai diventare un modo per leggere attraverso i tenant, e un payload di webhook non deve mai trasportare i record di un vicino. La guida al modulo API copre la forma di quella superficie.

Domande frequenti sull'isolamento dei workspace

L'isolamento multi-tenant solleva la stessa manciata di domande in ogni progetto. Queste sono quelle che conviene chiarire presto.

  • Basta la delimitazione a livello applicativo, o serve la row-level security? — La delimitazione fatta valere dal server su ogni lettura e scrittura copre il threat model della maggior parte dei SaaS. La RLS del database aggiunge difesa in profondità ma non sostituisce i controlli alla frontiera — worker e chiavi API hanno comunque bisogno della stessa regola.
  • Come dovrebbe funzionare la condivisione tra workspace? — Modellala esplicitamente — un invito, una riga di appartenenza — invece di indebolire la delimitazione. «Chiunque abbia il link» dovrebbe essere una funzionalità progettata con i propri controlli, non un incidente.
  • Cosa si rompe per primo nelle app multi-tenant? — I percorsi di comodo: link di ripresa, strumenti admin, worker in background che caricano record per semplice ID. Verifica ogni percorso di codice che tocca un record senza passare per la delimitazione normale.
  • Come aggiungo la delimitazione a una tabella esistente? — Aggiungi workspaceId, riempila a ritroso, falla valere in letture e scritture, poi tocca la UI. Rilascia prima i test negativi così il confine è dimostrato invece che presunto.
  • Le server action hanno bisogno di controlli se la pagina è protetta? — Sì. I guard di pagina nascondono schermate; non autorizzano operazioni. Ogni action risolve sessione e workspace in modo indipendente.

Domande frequenti

14 domande

Cos'è supastack?

supastack è una base modulare per costruire prodotti SaaS con AI. Riunisce l'infrastruttura comune così puoi concentrarti sulle funzionalità proprie del tuo prodotto.

Supporta web e mobile?

Sì. supastack include app Next.js ed Expo come punti di partenza per esperienze web e mobile.

Quale autenticazione è inclusa?

Better Auth copre email/password, OTP e login social. I workspace personali vengono provisionati con l'account così i record restano delimitati fin dal primo giorno.

Come è supportata l'AI?

supastack include AI multi-provider configurabile, tracciamento dell'uso, budget e supporto cifrato per le proprie chiavi (BYOK).

Come vengono gestiti gli abbonamenti?

Per i prodotti costruiti sul kit, fatturazione Stripe, abbonamenti e permessi formano la base dell'accesso a pagamento. I segreti dei provider restano lato server.

Dove vive il codice specifico del mio prodotto?

Le funzionalità specifiche del prodotto restano in un codebase separato, mentre il prodotto configura e integra i moduli base di supastack.

Come funziona il prezzo di supastack?

Il kit è un acquisto unico con aggiornamenti a vita: Un framework a 249 $ (prezzo di lancio temporaneo — 100 $ di sconto sul prezzo di listino di 349 $) oppure Tutti i framework (Next.js, iOS, Android) a 499 $ (prezzo di lancio temporaneo — 100 $ di sconto sul prezzo di listino di 599 $), più 75 $ per posto sviluppatore aggiuntivo. Nessun abbonamento al kit. Il checkout su questo sito consegna la tua chiave di licenza via email, con accesso al repo tramite invito GitHub.

Come delimitano i workspace i miei dati?

I record utente sono delimitati da workspaceId. Identità, permessi, uso AI, eventi di fatturazione e voci di audit restano dentro il confine del workspace personale.

Come funzionano i job in background?

Trigger.dev è il runtime di job esplicito. Il contratto JobRunner promette solo enqueue, status e cancel — la semantica di workflow resta specifica ed esplicita di Trigger.dev.

In cosa differisce l'email dall'outreach?

L'email transazionale copre i flussi di prodotto come gli avvisi di completamento delle attività. L'outreach a freddo e le campagne appartengono al prodotto, fuori dal modulo email di questo kit.

Come funzionano gli acquisti su mobile?

La versione mobile include acquisti nativi e ripristino tramite RevenueCat, con accesso verificato dal server. Configura gli account degli store e completa i test sui dispositivi prima della pubblicazione. I pagamenti web restano separati.

Dove risiedono le chiavi dei provider AI?

Le credenziali BYOK sono cifrate e restano lato server. Le chiavi vengono sanificate nei log; uso e budget restano visibili a livello di workspace.

Quali metodi di pagamento accetta il checkout?

Il checkout ospitato da Stripe accetta le carte e può offrire anche Alipay e WeChat Pay una volta attivati i wallet sull'account Stripe — utile per gli acquirenti in Cina. Le autorizzazioni dei wallet vengono confermate in modo asincrono, quindi la pagina della licenza si aggiorna non appena il pagamento va a buon fine.

Posso ottenere un rimborso?

Una volta ottenuto l'accesso al repository, supastack è tuo per sempre, quindi non può essere rimborsato. Ma non preoccuparti: ricevi il codice sorgente completo con aggiornamenti a vita per creare e lanciare prodotti illimitati per te o per i tuoi clienti. L'unica condizione è che non puoi rivendere il codice né ridistribuire il repository come starter kit o modello.

IT