Come aggiungere il controllo degli accessi basato sui ruoli (RBAC) alla tua app
Per aggiungere il controllo degli accessi basato sui ruoli, assegna a ogni utente uno o più ruoli (per esempio amministratore, editor, visualizzatore), definisci quali azioni può compiere ciascun ruolo e controlla questi permessi sul server per ogni richiesta — non limitarti a nascondere i pulsanti. Verifica anche che il record a cui si accede appartenga all'account o al team dell'utente. Inizia con pochi ruoli fissi nel database e fai dei test provando a raggiungere direttamente i dati di un altro utente.
Autenticazione vs autorizzazione
Due termini che si confondono spesso:
- Autenticazione è chi sei? — il login. Vedi come aggiungere il login alla tua app.
- Autorizzazione è cosa ti è permesso fare? — quali pagine, record e azioni un utente loggato può raggiungere.
L'RBAC è il modo più comune di fare autorizzazione. È importante: a settembre 2026, il Broken Access Control è al primo posto nella OWASP Top 10:2025, l'elenco molto usato dei rischi di sicurezza più gravi per le applicazioni web. I problemi tipici sono utenti che leggono i record di altri cambiando un ID nell'URL, oppure utenti normali che chiamano route API riservate agli amministratori.
Scegli un modello
| Modello | Come funziona | Ideale per | Compromesso |
|---|---|---|---|
| Una sola colonna ruolo | users.role = admin / member | App piccole con due o tre ruoli | Diventa confuso quando le persone hanno ruoli diversi in contesti diversi |
| Ruoli + permessi | I ruoli mappano a permessi con nome (invoices.approve); il codice controlla i permessi | App le cui regole cresceranno | Più tabelle; un elenco di permessi da mantenere |
| Ruoli per team (multi-tenant) | Una tabella di appartenenze: utente + organizzazione + ruolo | SaaS in cui le persone appartengono a team o workspace | Ogni query deve essere limitata all'organizzazione |
| Basato su attributi o relazioni | Regole sugli attributi del record ("l'autore può modificare il proprio post") o sulle relazioni (condiviso con) | Documenti, condivisione, flussi di lavoro complessi | Più difficile da ragionarci; valuta una libreria o un servizio dedicato |
| Ruoli del provider di autenticazione | Il tuo provider di login memorizza ruoli o appartenenze alle organizzazioni | App che usano già un provider di autenticazione ospitato | Legato a quel provider; va comunque applicato sul tuo server |
In pratica la maggior parte delle app combina due cose: i ruoli per il tipo di azioni che qualcuno può compiere, e la proprietà per i record su cui può agire. "Gli editor possono modificare i post" è una regola di ruolo; "…i post del proprio workspace" è una regola di proprietà. Ti servono entrambe.
Parti più semplice di quanto pensi. Amministratore, membro e visualizzatore coprono un numero sorprendente di app. È più facile dividere un ruolo in seguito che sciogliere dieci ruoli che nessuno capisce.
Progetta i ruoli prima di scrivere codice
Scrivi prima una tabella dei permessi in linguaggio semplice. Serve come specifica per l'IA e come piano di test:
| Azione | Proprietario | Amministratore | Membro | Visualizzatore |
|---|---|---|---|---|
| Vedere i progetti del team | ✓ | ✓ | ✓ | ✓ |
| Creare e modificare i progetti | ✓ | ✓ | ✓ | |
| Eliminare i progetti | ✓ | ✓ | ||
| Invitare e rimuovere persone | ✓ | ✓ | ||
| Cambiare i ruoli | ✓ | |||
| Fatturazione | ✓ |
Decidi anche i casi limite: l'ultimo proprietario può andarsene? Un amministratore può rimuovere il proprietario? Cosa vede un utente rimosso?
Passo dopo passo
1. Prima il login deve funzionare
L'RBAC si appoggia sull'autenticazione. Il server deve sapere in modo affidabile chi sta facendo ogni richiesta, dalla sessione o da un token verificato — mai da un ID utente inviato dal browser nel corpo della richiesta.
2. Memorizza i ruoli nel database
Per un'app con un solo team, una colonna role sugli utenti va bene. Per i team, usa una tabella delle appartenenze:
create table memberships (
user_id uuid references users(id),
organization_id uuid references organizations(id),
role text not null check (role in ('owner','admin','member','viewer')),
primary key (user_id, organization_id)
);
Non permettere mai agli utenti di impostare il proprio ruolo con un normale aggiornamento del profilo. I cambi di ruolo passano da un endpoint dedicato e verificato nei permessi.
3. Controlla i permessi sul server, in un unico punto
Scrivi un unico helper — qualcosa come can(user, 'projects.delete', project) — e chiamalo in ogni route API, server action e job in background che legge o modifica dati. Una funzione centrale è più facile da rivedere e testare di controlli sparsi nel codice. Nega per impostazione predefinita: se nessuna regola consente un'azione, viene rifiutata.
4. Limita ogni query
Ogni query sui dati del team dovrebbe includere il team: where organization_id = :currentOrg, non solo where id = :id. È questo che impedisce a qualcuno di cambiare /projects/123 in /projects/124 e vedere il progetto di un'altra azienda. Restituisci "non trovato" invece di "vietato" per i record di altri team, così non riveli che esistono.
5. Aggiungi protezione a livello di database dove conta
La row-level security (RLS) di Postgres permette al database di far rispettare quali righe ogni utente può vedere. È essenziale se il browser parla direttamente con il database (come con alcuni backend ospitati), e un secondo livello utile per le tabelle sensibili negli altri casi.
6. Rifletti i ruoli nell'interfaccia
Ora nascondi o disattiva ciò che gli utenti non possono fare, così l'app non risulta confusa. Serve solo per l'usabilità; a proteggere sono i controlli sul server.
7. Registra le azioni sensibili
Annota chi ha cambiato i ruoli, eliminato dati o esportato record, e quando. Un registro di audit aiuta con le richieste di supporto e con gli incidenti.
8. Testa come un attaccante
Accedi con ciascun ruolo e prova ogni azione della tabella dei permessi. Poi prova le cose che non dovrebbero funzionare: chiamare route API di amministrazione come visualizzatore, cambiare ID negli URL e nelle richieste, rimuoverti come ultimo proprietario. Vale la pena scrivere test automatici per la tabella dei permessi quando le regole si sono stabilizzate.
Prompt che funzionano
Aggiungi il controllo degli accessi basato sui ruoli. Ruoli per organizzazione: owner, admin, member, viewer, memorizzati in una tabella memberships. I permessi sono in questa tabella: [incolla la tua tabella]. Crea un unico helper lato server can(user, action, resource), che neghi per impostazione predefinita, e usalo in ogni route API. Limita ogni query per organization_id. Nascondi nell'interfaccia le azioni che l'utente non può compiere, ma non fare mai affidamento su questo per la sicurezza.
Verifica ogni route API e ogni funzione server di questa app. Per ciascuna elenca quali dati legge o modifica, se controlla che l'utente sia loggato, se controlla il suo ruolo, e se limita la query alla sua organizzazione. Correggi quelle a cui manca un controllo e mostrami l'elenco.
Aggiungi una pagina /admin riservata agli amministratori in cui il proprietario può cambiare i ruoli dei membri. Impedisci di rimuovere o retrocedere l'ultimo proprietario, registra ogni cambio di ruolo con chi l'ha fatto e quando, e assicurati che l'endpoint di cambio ruolo rifiuti chiunque non sia proprietario.
Errori comuni
- Controllare i ruoli solo nel frontend. L'API resta aperta a chiunque la chiami.
- Fidarsi degli ID inviati dal client — un
userIdo unrolenel corpo della richiesta invece che nella sessione. - Query senza limiti che recuperano solo per ID del record.
- Ruoli controllati sulle pagine ma non sulle route API, sulle esportazioni, sui download di file o sui webhook.
- Amministratore riconosciuto dall'indirizzo email scritto nel codice (
if email === 'me@...'), facile da dimenticare e difficile da cambiare. - Troppi ruoli troppo presto, che nessuno sa spiegare sei mesi dopo.
- Sessioni non aggiornate: un utente retrocesso mantiene i diritti da amministratore finché non esce. Verifica i ruoli dal database, o aggiornali, per le azioni sensibili.
Checklist RBAC
- Tabella dei permessi scritta in linguaggio semplice, casi limite decisi
- Il server riconosce l'utente dalla sessione, mai dai dati della richiesta
- Ruoli memorizzati nel database; gli utenti non possono cambiare il proprio
- Un unico controllo centrale dei permessi, con diniego predefinito, usato in ogni route
- Ogni query limitata all'organizzazione o alla proprietà dell'utente
- Row-level security dove il browser può raggiungere il database
- L'interfaccia nasconde ciò che gli utenti non possono fare (solo per usabilità)
- Azioni sensibili registrate
- Ogni ruolo testato, incluse le chiamate API dirette e gli ID modificati
Il controllo degli accessi è una voce di una lista più lunga; la checklist di sicurezza per le app create con l'IA copre il resto. Se stai costruendo uno strumento per il tuo personale, come costruire uno strumento interno mostra dove si inseriscono i ruoli.
RBAC su Mythex
Mythex non fornisce un sistema di login o di ruoli integrato per gli utenti della tua app. Scegli una libreria o un provider di autenticazione e descrivi i ruoli, e l'agente li collega al tuo codice e al database Postgres del progetto (aggiungere il login alla tua app). I ruoli dell'area di lavoro di Mythex, come Proprietario e Membro, controllano chi può modificare i tuoi progetti Mythex, non chi può usare l'app che pubblichi. Usa la modalità Piano per concordare la tabella dei permessi prima di costruire, poi usa il prompt di revisione qui sopra e testa ogni ruolo nell'Anteprima prima di pubblicare. I prompt di sicurezza della documentazione sono un utile passo successivo.
Domande
Che cos'è il controllo degli accessi basato sui ruoli?
Il controllo degli accessi basato sui ruoli (RBAC) decide cosa può fare ciascun utente in base ai ruoli che ha, come amministratore, editor o visualizzatore. I permessi sono associati ai ruoli e non alle singole persone, quindi cambiare ciò che qualcuno può fare significa cambiarne il ruolo.
Qual è la differenza tra autenticazione e autorizzazione?
L'autenticazione verifica chi è una persona, di solito tramite il login. L'autorizzazione decide cosa quella persona autenticata può vedere e fare. L'RBAC è un modo di realizzare l'autorizzazione.
Nascondere i pulsanti nell'interfaccia basta per limitare l'accesso?
No. Chiunque può chiamare direttamente la tua API, quindi nascondere un pulsante cambia solo ciò che le persone vedono. Ogni richiesta che legge o modifica dati deve essere verificata sul server, rispetto al ruolo dell'utente e alla proprietà del record.
Devo usare la row-level security di Postgres?
La row-level security permette al database stesso di far rispettare quali righe ogni utente può leggere o scrivere, ed è una forte rete di sicurezza, soprattutto quando il frontend parla direttamente con il database. Aggiunge complessità, quindi molte app applicano i permessi nel codice del server e usano la row-level security come livello extra per le tabelle sensibili.