API Ruoli e Permessi
Auris implementa un modello di autorizzazione a tre livelli. Questa API copre due di quei livelli:
-
RBAC (Role-Based Access Control): I ruoli sono insiemi nominati di permessi. Gli utenti vengono assegnati ai ruoli. I permessi usano il formato
azione:risorsa(es.view:invoices,manage:users). Ogni permesso può essere impostato suALLOW,DENYoINHERIT(modello tri-stato). -
FGA (Fine-Grained Authorization): Un motore di tuple relazionali compatibile con Zanzibar per il controllo degli accessi a livello di oggetto. Il livello FGA viene usato quando l’RBAC a livello di ruolo è insufficiente — per esempio, “l’utente Alice può vedere il documento 42 nello specifico, anche se non ha
view:all_documents.”
RBAC — Gestione Ruoli
Tutti gli endpoint di gestione ruoli richiedono il permesso manage:roles e l’header x-tenant.
/api/rolesRequires: manage:rolesElenca tutti i ruoli definiti nel tenant. Restituisce i metadati del ruolo ma non l’elenco completo dei permessi.
Usa GET /api/roles/[id] o GET /api/roles/[id]/permissions per i dettagli dei permessi.
Parametri di query
| Parametro | Tipo | Descrizione |
|---|---|---|
page | integer | Numero di pagina (default: 1) |
limit | integer | Elementi per pagina (default: 20) |
search | string | Filtra per nome ruolo |
Risposta di successo
{
"ok": true,
"data": {
"data": [
{
"id": "role_abc123",
"name": "editor",
"description": "Può creare e modificare contenuti",
"color": "#3b82f6",
"userCount": 12,
"createdAt": "2025-01-01T00:00:00Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 5, "totalPages": 1 }
}
}/api/rolesRequires: manage:rolesCrea un nuovo ruolo. I nomi dei ruoli devono essere unici nel tenant e possono contenere solo caratteri alfanumerici, trattini e underscore.
Corpo della richiesta
{
"name": "billing-admin",
"description": "Gestisce fatture e metodi di pagamento",
"color": "#f59e0b"
}description e color sono opzionali.
Risposta di successo
{
"ok": true,
"data": {
"id": "role_def456",
"name": "billing-admin",
"description": "Gestisce fatture e metodi di pagamento",
"color": "#f59e0b",
"createdAt": "2025-02-18T10:00:00Z"
}
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
NAME_TAKEN | 409 | Esiste già un ruolo con questo nome |
VALIDATION_ERROR | 400 | Formato del nome ruolo non valido |
/api/roles/[id]Requires: manage:rolesOttieni un ruolo tramite ID, incluso l’elenco completo dei permessi con lo stato ALLOW/DENY per ciascun permesso.
Risposta di successo
{
"ok": true,
"data": {
"id": "role_abc123",
"name": "editor",
"description": "Può creare e modificare contenuti",
"color": "#3b82f6",
"permissions": [
{ "id": "perm_1", "key": "view:invoices", "state": "ALLOW" },
{ "id": "perm_2", "key": "create:invoices", "state": "ALLOW" },
{ "id": "perm_3", "key": "delete:invoices", "state": "DENY" }
]
}
}Stati dei permessi: ALLOW (esplicitamente concesso), DENY (esplicitamente bloccato), INHERIT (non impostato esplicitamente — utilizza il default di sistema, tipicamente deny).
/api/roles/[id]Requires: manage:rolesAggiorna il nome, la descrizione o il colore di un ruolo.
Corpo della richiesta
{
"description": "Può creare, modificare e pubblicare contenuti",
"color": "#8b5cf6"
}Risposta di successo
{
"ok": true,
"data": {
"id": "role_abc123",
"name": "editor",
"description": "Può creare, modificare e pubblicare contenuti",
"color": "#8b5cf6"
}
}/api/roles/[id]Requires: manage:rolesElimina un ruolo. Gli utenti che hanno questo ruolo assegnato lo perderanno immediatamente. Il ruolo viene rimosso da tutti gli utenti e poi eliminato dal tenant.
L’eliminazione di un ruolo influisce su tutti gli utenti che lo possiedono. Verifica l’impatto usando GET /api/roles/[id] che include userCount prima di eliminare.
Risposta di successo
{
"ok": true,
"data": { "deleted": true }
}RBAC — Gestione Permessi
/api/roles/[id]/permissionsRequires: manage:rolesElenca le impostazioni dei permessi per un ruolo, raggruppate per categoria. Ogni permesso ha uno stato di ALLOW, DENY o INHERIT.
Risposta di successo
{
"ok": true,
"data": {
"permissions": [
{
"category": "Documenti",
"items": [
{ "id": "perm_1", "key": "view:invoices", "label": "Visualizza Fatture", "state": "ALLOW" },
{ "id": "perm_2", "key": "create:invoices", "label": "Crea Fatture", "state": "ALLOW" },
{ "id": "perm_3", "key": "delete:invoices", "label": "Elimina Fatture", "state": "INHERIT" }
]
}
]
}
}/api/roles/[id]/permissionsRequires: manage:rolesAggiorna gli stati dei permessi per un ruolo. Invia un array di oggetti con lo stato del permesso. I permessi non inclusi nell’array vengono lasciati invariati.
Corpo della richiesta
{
"permissions": [
{ "permissionId": "perm_1", "state": "ALLOW" },
{ "permissionId": "perm_3", "state": "DENY" }
]
}Risposta di successo
{
"ok": true,
"data": {
"updated": 2,
"permissions": [
{ "id": "perm_1", "key": "view:invoices", "state": "ALLOW" },
{ "id": "perm_3", "key": "delete:invoices", "state": "DENY" }
]
}
}Verifica Permessi
/api/roles/checkRequires: authenticated userVerifica se l’utente autenticato corrente ha un insieme di permessi. Risolve i permessi attraverso l’intero stack RBAC: override diretti sull’utente, assegnazioni di ruoli e policy predefinite. Opzionalmente con scope per un’applicazione specifica.
Questo endpoint viene utilizzato dai resource server (inclusa la Dashboard Auris) per imporre l’autorizzazione prima di eseguire operazioni.
Corpo della richiesta
{
"permissions": ["view:invoices", "create:invoices", "approve:expenses"],
"applicationId": "app_abc123"
}applicationId è opzionale. Se fornito, vengono verificati solo i permessi configurati per lo scope di quell’applicazione.
Risposta di successo
{
"ok": true,
"data": {
"permissions": {
"view:invoices": true,
"create:invoices": true,
"approve:expenses": false
}
}
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
VALIDATION_ERROR | 400 | permissions non è un array di stringhe |
FGA — Modelli di Autorizzazione
Il motore di Autorizzazione Fine-Grana utilizza un modello basato su DSL per definire tipi di oggetti, relazioni e regole di riscrittura. Prima di scrivere le tuple, è necessario creare e attivare un modello di autorizzazione.
Tutti gli endpoint FGA richiedono l’header x-tenant.
/api/fga/modelsRequires: manage:fga_modelsElenca tutti i modelli di autorizzazione per il tenant. Solo un modello può essere attivo alla volta.
Risposta di successo
{
"ok": true,
"data": [
{
"id": "model_abc123",
"name": "Modello di Autorizzazione SaaS",
"version": 3,
"isActive": true,
"createdAt": "2025-02-10T00:00:00Z"
}
]
}/api/fga/modelsRequires: manage:fga_modelsCrea un nuovo modello di autorizzazione fornendo una definizione DSL. Il DSL viene analizzato e validato prima della memorizzazione. Se la validazione fallisce, viene restituito un messaggio di errore dettagliato.
Corpo della richiesta
{
"name": "Modello Accesso Documenti",
"dsl": "type user\n\ntype document\n relations\n define owner: [user]\n define viewer: [user] or owner\n"
}Risposta di successo
{
"ok": true,
"data": {
"id": "model_def456",
"name": "Modello Accesso Documenti",
"version": 1,
"isActive": false,
"schema": {
"typeDefinitions": [
{ "type": "user", "relations": {} },
{ "type": "document", "relations": { "owner": { "this": {} }, "viewer": { "union": {} } } }
]
}
}
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
DSL_PARSE_ERROR | 400 | Sintassi DSL non valida — l’errore include il numero di riga e la descrizione |
DSL_VALIDATION_ERROR | 400 | Il DSL è sintatticamente valido ma fa riferimento a tipi o relazioni non definiti |
/api/fga/models/[id]Requires: view:fga_modelsOttieni un modello di autorizzazione specifico, incluso lo schema analizzato completo e il testo DSL.
/api/fga/models/[id]Requires: manage:fga_modelsAggiorna il nome o il DSL di un modello. Il DSL viene ri-analizzato e ri-validato all’aggiornamento.
/api/fga/models/[id]/activateRequires: manage:fga_modelsImposta questo modello come modello di autorizzazione attivo per il tenant. Disattiva qualsiasi modello precedentemente attivo. Tutte le successive chiamate check, expand e list-objects usano questo modello.
Richiesta: Nessun corpo richiesto.
Risposta di successo
{
"ok": true,
"data": { "activated": true, "modelId": "model_def456" }
}FGA — Tuple Relazionali
Le tuple sono i fatti del sistema di autorizzazione. Ogni tupla afferma che un soggetto ha una relazione con un oggetto.
Formato tuple: tipoOggetto:idOggetto#relazione@tipoSoggetto:idSoggetto
Esempio: document:readme#viewer@user:alice — l’utente alice è un viewer del documento readme.
/api/fga/tuplesRequires: view:fga_tuplesElenca le tuple relazionali, con filtraggio opzionale.
Parametri di query
| Parametro | Tipo | Descrizione |
|---|---|---|
objectType | string | Filtra per tipo di oggetto (es. document) |
objectId | string | Filtra per ID oggetto |
relation | string | Filtra per nome relazione |
subjectType | string | Filtra per tipo soggetto |
subjectId | string | Filtra per ID soggetto |
page | integer | Numero di pagina |
limit | integer | Elementi per pagina |
Risposta di successo
{
"ok": true,
"data": {
"data": [
{
"id": "tuple_abc",
"objectType": "document",
"objectId": "readme",
"relation": "viewer",
"subjectType": "user",
"subjectId": "alice",
"createdAt": "2025-02-15T10:00:00Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
}
}/api/fga/tuplesRequires: manage:fga_tuplesScrivi una singola tupla relazionale. La tupla viene validata rispetto al modello di autorizzazione attivo prima della memorizzazione.
Corpo della richiesta
{
"objectType": "document",
"objectId": "readme",
"relation": "viewer",
"subjectType": "user",
"subjectId": "alice"
}Per riferimenti a subject-set (es. “tutti i membri del gruppo engineering possono vedere”):
{
"objectType": "document",
"objectId": "readme",
"relation": "viewer",
"subjectType": "group",
"subjectId": "engineering",
"subjectRelation": "member"
}Risposta di successo
{
"ok": true,
"data": {
"id": "tuple_abc",
"objectType": "document",
"objectId": "readme",
"relation": "viewer",
"subjectType": "user",
"subjectId": "alice"
}
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
NO_ACTIVE_MODEL | 400 | Nessun modello di autorizzazione attivo con cui validare |
INVALID_RELATION | 400 | La relazione non esiste su questo tipo di oggetto nel modello attivo |
TUPLE_EXISTS | 409 | Una tupla identica esiste già (preferisci la scrittura bulk — idempotente) |
/api/fga/tuplesRequires: manage:fga_tuplesElimina una tupla relazionale specifica fornendo i dati della tupla nel corpo della richiesta.
Corpo della richiesta
{
"objectType": "document",
"objectId": "readme",
"relation": "viewer",
"subjectType": "user",
"subjectId": "alice"
}Risposta di successo
{
"ok": true,
"data": { "deleted": true }
}/api/fga/tuples/bulkRequires: manage:fga_tuplesScrivi o elimina più tuple in una singola richiesta. Le operazioni vengono elaborate atomicamente — se qualsiasi operazione fallisce la validazione, l’intera richiesta bulk viene rifiutata.
Corpo della richiesta
{
"writes": [
{
"objectType": "document",
"objectId": "readme",
"relation": "editor",
"subjectType": "user",
"subjectId": "bob"
}
],
"deletes": [
{
"objectType": "document",
"objectId": "readme",
"relation": "viewer",
"subjectType": "user",
"subjectId": "alice"
}
]
}Risposta di successo
{
"ok": true,
"data": {
"written": 1,
"deleted": 1
}
}FGA — Query di Autorizzazione
/api/fga/checkRequires: debug:fgaVerifica se un soggetto ha una relazione specifica con un oggetto. Valuta le regole di riscrittura complete in modo ricorsivo. Opzionalmente restituisce l’albero di risoluzione per il debug.
Corpo della richiesta
{
"objectType": "document",
"objectId": "readme",
"relation": "viewer",
"subjectType": "user",
"subjectId": "alice",
"explain": true
}Imposta explain: true per ricevere l’albero di risoluzione (utile per il debug del motivo per cui un check è passato o fallito).
Risposta di successo
{
"ok": true,
"data": {
"allowed": true,
"resolution": {
"type": "union",
"result": true,
"children": [
{
"type": "this",
"relation": "viewer",
"result": true,
"tupleFound": "document:readme#viewer@user:alice"
}
]
}
}
}/api/fga/expandRequires: debug:fgaEspande una relazione per elencare tutti i soggetti (utenti o insiemi di utenti) che hanno una determinata relazione con un oggetto. Restituisce una struttura ad albero che segue le regole di riscrittura.
Corpo della richiesta
{
"objectType": "document",
"objectId": "readme",
"relation": "viewer"
}Risposta di successo
{
"ok": true,
"data": {
"tree": {
"root": {
"type": "union",
"nodes": [
{
"type": "leaf",
"subjects": [
{ "type": "user", "id": "alice" },
{ "type": "user", "id": "bob" }
]
},
{
"type": "computed_userset",
"relation": "owner",
"subjects": [{ "type": "user", "id": "charlie" }]
}
]
}
}
}
}/api/fga/list-objectsRequires: debug:fgaElenca tutti gli oggetti di un dato tipo a cui un soggetto può accedere tramite una relazione specifica. Usa la ricerca inversa attraverso il tuple store e le regole di riscrittura.
Corpo della richiesta
{
"objectType": "document",
"relation": "viewer",
"subjectType": "user",
"subjectId": "alice"
}Risposta di successo
{
"ok": true,
"data": {
"objectIds": ["readme", "api-spec", "changelog"],
"total": 3
}
}Gli endpoint check, expand e list-objects richiedono debug:fga perché espongono la struttura interna del modello di autorizzazione. In produzione, i resource server dovrebbero chiamare questi endpoint usando un token M2M con questo permesso anziché esporli agli utenti finali.
Pagine Correlate
- Guida Ruoli e Permessi — Come funziona l’RBAC in Auris
- Autorizzazione Fine-Grana — Autorizzazione avanzata con FGA
- Utenti e Ruoli — Assegna ruoli dalla Console
- API Autorizzazione Fine-Grana — Verifiche di autorizzazione in stile Zanzibar