Come Google Verifica i Permessi di Accesso per Miliardi di Utenti e Cosa C'entra SpiceDB
Quando un progetto supera uno schema semplice con ruoli di amministratore e utente, inizia il caos. In un'architettura a microservizi, il controllo dei permessi spesso si trasforma in una rete intricata. Un servizio memorizza i ruoli in un database, un altro valida i token JWT, un terzo esegue pesanti query SQL con una dozzina di JOIN. Dal 2021, l'OWASP classifica i fallimenti nel controllo degli accessi (Broken Access Control) come la principale minaccia per la sicurezza delle applicazioni web.
Google ha affrontato questo problema molti anni fa. Per Google Drive, YouTube e Cloud IAM, l'azienda ha sviluppato un sistema di autorizzazione centralizzato unificato chiamato Zanzibar. Nel 2019, gli ingegneri hanno pubblicato un articolo che descriveva la sua architettura, e il team di Authzed ha preso questa idea e ha creato SpiceDB — un database open-source per la gestione del controllo degli accessi.
Perché Spostare l'Autorizzazione in un Database Separato
I database tradizionali sono bravi a memorizzare entità di business, ma faticano con grafi di permessi complessi. Immagina un documento all'interno di una cartella che a sua volta è dentro un'altra cartella, condivisa con un gruppo di utenti che include un reparto aziendale separato. Calcolare se un dipendente specifico ha accesso al file diventa doloroso e lento usando un DBMS standard.
SpiceDB si assume questo compito. Invi una semplice query al database: "L'utente X può eseguire l'azione Y sulla risorsa Z?". La risposta è una rapida risposta binaria.
Allo stesso tempo, SpiceDB gestisce solo l'autorizzazione (permessi di accesso) e non sa nulla dell'autenticazione (verifica dell'identità). La verifica delle password, l'accesso degli utenti e l'emissione di token dovrebbero essere ancora gestiti dal tuo provider di identità come Keycloak o Auth0.
Come Funzionano lo Schema e il Linguaggio delle Relazioni
Lavorare con SpiceDB inizia con la descrizione di uno schema. Lo schema definisce i tipi di oggetti e le regole per il calcolo dei permessi.
La sintassi dello schema è leggibile e concisa:
definition user {}
definition folder {
relation parent: folder
relation viewer: user
permission view = viewer + parent->view
}
definition document {
relation folder: folder
relation viewer: user
permission view = viewer + folder->view
}
In questo esempio, l'accesso view a un documento viene concesso automaticamente agli utenti elencati direttamente in viewer, così come a chi ha il permesso view sulla cartella padre. La catena di annidamento può avere qualsiasi profondità.
I dati effettivi vengono memorizzati come relazioni. Queste sono semplici fatti sul sistema, ad esempio:
folder:finance— un oggetto di tipo cartella con IDfinanceviewer— una relazioneuser:mikhail— un soggetto
Registrare una tale relazione significa che Mikhail è diventato un lettore della cartella finance.
ReBAC e Attributi: L'Esperienza di Netflix
A differenza del classico RBAC (Role-Based Access Control), SpiceDB implementa ReBAC (Relationship-Based Access Control). L'accesso viene determinato attraverso le relazioni tra gli oggetti in un grafo.
Ma a volte le aziende hanno bisogno di qualcosa di più del sapere che un utente fa parte di un team. Hanno bisogno di verificare una condizione contestuale: ad esempio, che la persona stia accedendo da un indirizzo IP aziendale o che la richiesta sia stata effettuata durante l'orario di lavoro.
Per questi scenari, gli ingegneri di Netflix hanno contribuito ad aggiungere un meccanismo di caveats a SpiceDB. Questo combina ReBAC e ABAC (Attribute-Based Access Control). Una funzione contestuale viene associata a una relazione, calcolata nel momento della verifica dei permessi.
Architettura e Prestazioni Sotto Carico
SpiceDB è scritto in Go e progettato per carichi elevati. Gli autori dichiarano una latenza di 5ms al p95 con milioni di query al secondo e miliardi di relazioni nel database.
Come storage (datastores), puoi collegare DBMS familiari:
- PostgreSQL
- CockroachDB
- MySQL (il driver per MySQL è stato scritto dal team di autorizzazione di GitHub)
- Google Cloud Spanner
Una caratteristica interessante è la gestione della consistenza a livello di singola query. Se un utente ha appena modificato i permessi di accesso e vuole vedere il risultato immediatamente, l'applicazione invia una richiesta che richiede dati completamente consistenti. Tuttavia, se stiamo visualizzando un catalogo pubblico dove un paio di secondi di ritardo non sono critici, permettiamo la cache e riduciamo il carico sul database.
SpiceDB può anche rispondere a domande "inverse": "A quali risorse ha accesso l'utente?" o "Chi può visualizzare questo documento?". Per questo utilizza internamente indici inversi.
Quick Start con Docker e curl
Puoi avviare SpiceDB per esperimenti con un singolo comando Docker:
docker run --rm -p 50051:50051 -p 8443:8443 \
authzed/spicedb serve \
--http-enabled true \
--grpc-preshared-key "somerandomkeyhere"
Dopo l'avvio, carica lo schema tramite l'API HTTP:
curl --location 'http://localhost:8443/v1/schema/write' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer somerandomkeyhere' \
--data '{
"schema": "definition user {} \n definition folder { \n relation viewer: user \n permission view = viewer \n }"
}'
Aggiungi una relazione che indica che l'utente anne può visualizzare la cartella budget:
curl --location 'http://localhost:8443/v1/relationships/write' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer somerandomkeyhere' \
--data '{
"updates": [
{
"operation": "OPERATION_TOUCH",
"relationship": {
"resource": { "objectType": "folder", "objectId": "budget" },
"relation": "viewer",
"subject": { "object": { "objectType": "user", "objectId": "anne" } }
}
}
]
}'
Ora verifica i permessi:
curl --location 'http://localhost:8443/v1/permissions/check' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer somerandomkeyhere' \
--data '{
"resource": { "objectType": "folder", "objectId": "budget" },
"permission": "view",
"subject": { "object": { "objectType": "user", "objectId": "anne" } }
}'
Riceveremo lo stato PERMISSIONSHIP_HAS_PERMISSION in risposta.
Oltre alle API REST e gRPC, gli sviluppatori offrono un'utilità da riga di comando zed e una sandbox basata su browser chiamata Playground (play.authzed.com). È comoda per delineare un modello di permessi, popolarlo con dati di test e testare ipotesi prima di scrivere codice.
Per Chi È Questo Strumento
SpiceDB è già in produzione presso Red Hat, IBM, GitPod e Tubi.
Introdurre un tale sistema in un piccolo monolite dove tutti i permessi sono limitati a un pannello di amministrazione e un paio di ruoli ha poco senso — è una complessità infrastrutturale non necessaria. Tuttavia, lo strumento è perfetto quando:
- Hai una dozzina di microservizi, e ognuno cerca di verificare i permessi a modo suo.
- La logica del tuo prodotto richiede la condivisione di file, gerarchie di cartelle complesse o account di team.
- Hai bisogno di un audit di sicurezza e di un unico punto di gestione del controllo degli accessi.
Per il deployment in Kubernetes, Authzed fornisce un operatore ufficiale. Il progetto si sta sviluppando attivamente, e il repository GitHub ha già quasi 7.000 stelle.
Progetti correlati