Skip to Content

API Ruoli e Permessi

Auris implementa un modello di autorizzazione a tre livelli. Questa API copre due di quei livelli:

  1. 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 su ALLOW, DENY o INHERIT (modello tri-stato).

  2. 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.

GET/api/rolesRequires: manage:roles

Elenca 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

ParametroTipoDescrizione
pageintegerNumero di pagina (default: 1)
limitintegerElementi per pagina (default: 20)
searchstringFiltra 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 } } }

POST/api/rolesRequires: manage:roles

Crea 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

CodiceHTTPDescrizione
NAME_TAKEN409Esiste già un ruolo con questo nome
VALIDATION_ERROR400Formato del nome ruolo non valido

GET/api/roles/[id]Requires: manage:roles

Ottieni 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).


PUT/api/roles/[id]Requires: manage:roles

Aggiorna 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" } }

DELETE/api/roles/[id]Requires: manage:roles

Elimina 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

GET/api/roles/[id]/permissionsRequires: manage:roles

Elenca 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" } ] } ] } }

PUT/api/roles/[id]/permissionsRequires: manage:roles

Aggiorna 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

POST/api/roles/checkRequires: authenticated user

Verifica 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

CodiceHTTPDescrizione
VALIDATION_ERROR400permissions 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.

GET/api/fga/modelsRequires: manage:fga_models

Elenca 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" } ] }

POST/api/fga/modelsRequires: manage:fga_models

Crea 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

CodiceHTTPDescrizione
DSL_PARSE_ERROR400Sintassi DSL non valida — l’errore include il numero di riga e la descrizione
DSL_VALIDATION_ERROR400Il DSL è sintatticamente valido ma fa riferimento a tipi o relazioni non definiti

GET/api/fga/models/[id]Requires: view:fga_models

Ottieni un modello di autorizzazione specifico, incluso lo schema analizzato completo e il testo DSL.


PUT/api/fga/models/[id]Requires: manage:fga_models

Aggiorna il nome o il DSL di un modello. Il DSL viene ri-analizzato e ri-validato all’aggiornamento.


POST/api/fga/models/[id]/activateRequires: manage:fga_models

Imposta 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.

GET/api/fga/tuplesRequires: view:fga_tuples

Elenca le tuple relazionali, con filtraggio opzionale.

Parametri di query

ParametroTipoDescrizione
objectTypestringFiltra per tipo di oggetto (es. document)
objectIdstringFiltra per ID oggetto
relationstringFiltra per nome relazione
subjectTypestringFiltra per tipo soggetto
subjectIdstringFiltra per ID soggetto
pageintegerNumero di pagina
limitintegerElementi 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 } } }

POST/api/fga/tuplesRequires: manage:fga_tuples

Scrivi 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

CodiceHTTPDescrizione
NO_ACTIVE_MODEL400Nessun modello di autorizzazione attivo con cui validare
INVALID_RELATION400La relazione non esiste su questo tipo di oggetto nel modello attivo
TUPLE_EXISTS409Una tupla identica esiste già (preferisci la scrittura bulk — idempotente)

DELETE/api/fga/tuplesRequires: manage:fga_tuples

Elimina 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 } }

POST/api/fga/tuples/bulkRequires: manage:fga_tuples

Scrivi 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

POST/api/fga/checkRequires: debug:fga

Verifica 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" } ] } } }

POST/api/fga/expandRequires: debug:fga

Espande 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" }] } ] } } } }

POST/api/fga/list-objectsRequires: debug:fga

Elenca 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