Navigation Permission Metadata — Phase 2¶
Scopo e autorità¶
Phase 2 aggiunge una rappresentazione diagnostica read-only della catena:
NavigationItem → FAB view/endpoint → FAB permission → role → capability metadata → ACL metadata
Le autorità restano:
- FAB SecurityManager e PermissionView: autorità per permission e ruolo;
- codice ACL esistente: autorità per tenant, cliente, ownership e query dati;
- Navigation Registry: osservazionale;
- Capability model: osservazionale.
Il codice Phase 2 non chiama has_access per concedere accesso, non sostituisce decorator FAB, non aggiorna ruoli/permission, non filtra menu e non decide ACL.
Modello permission¶
PermissionMetadata raccoglie, quando esposto dalla classe FAB:
- permission names;
- view/menu name;
- endpoint tecnico;
- class permission;
- mapping method → permission;
- base permissions;
- marker di decorator disponibili senza eseguire funzioni;
- origine;
- risoluzione
EXPLICIT,INFERREDoUNKNOWN.
Il legacy adapter legge base_permissions, class_permission_name, method_permission_name e marker già presenti. Non inventa associazioni: quando la classe non espone elementi dimostrabili mantiene UNKNOWN.
Role mapping¶
app/navigation/permissions.py interroga soltanto SecurityManager.get_all_roles() e le relazioni Role.permissions. Produce RolePermissionSnapshot con coppie permission/view-menu e ruolo. Non esegue mutazioni e non contiene utenti, tenant o clienti reali.
Capability metadata¶
Il vocabolario iniziale è volutamente piccolo e deriva dalle aree osservate nell'audit:
documents.view, documents.manage, ras.view, ras.manage, courses.view, courses.manage, commercial.view, commercial.manage, users.admin, configuration.admin.
Le capability non costituiscono RBAC. La funzione map_item_capabilities produce candidati descrittivi. Permission generiche come can_list, can_show, can_edit, can_add, can_delete, list e save risultano AMBIGUOUS quando non è possibile dimostrare una capability business esatta. Non viene creato un mapping globale autorizzativo.
ACL metadata¶
AclMetadata descrive solo il requisito osservato: NONE, ROLE_ONLY, TENANT, CLIENT, OWNERSHIP, CUSTOM, MULTIPLE o UNKNOWN, con evidenze testuali e sorgente autorevole current_acl_code. Le aree Documentale, RAS/DVR, Formazione e Commerciale sono marcate MULTIPLE perché l'audit rileva più livelli (tenant, Cliente.users, filtri query, ownership o policy di modulo). Nessun filtro viene eseguito da questo modello.
Authorization chain e matrice¶
authorization_chains() collega ogni item ai permission names rilevabili, al view-menu name e ai ruoli presenti nello snapshot FAB. role_navigation_matrix() produce righe item × ruolo con permission possedute dal ruolo e stati diagnostici.
Gli stati sono volutamente separati:
visible_by_current_menu_logic:UNKNOWNsenza un contesto utente/tenant e senza eseguire policy menu;authorized_by_fab: evidenza del match PermissionView/ruolo nello snapshot, oppureUNKNOWN/NOT_OBSERVED_IN_ROLE_SNAPSHOT;data_acl_required:DATA ACL REQUIREDquando i metadata rilevano ulteriori requisiti.
Pertanto menu visibility ≠ endpoint authorization ≠ data authorization.
Gap analysis¶
gap_analysis() segnala:
- item senza permission associabile;
- permission/view-menu presenti nei role snapshot ma senza item di navigazione;
- endpoint senza permission rilevabile;
- capability senza mapping (
UNMAPPED); - permission riutilizzate da più capability candidate;
- ACL custom/multiple da verificare nel codice autorevole;
- mapping ambigui;
- evidenze di controlli manuali su
current_user, ruolo, tenant,is_platform_admin,Cliente.userse query.
I gap sono dati diagnostici e non causano errori runtime.
Snapshot¶
authorization_snapshot() produce JSON serializzabile con semantica esplicita, item, ruoli, matrice e gap. Non include username, dati personali, tenant specifici, clienti o record operativi. L'ordine è deterministico dato lo snapshot FAB fornito.
Limiti¶
Non è stato aggiunto un endpoint web, una pagina admin o un comando Flask registrato nell'application factory: l'accesso è costituito da utility Python interne utilizzabili da test e diagnostica, senza ampliare la superficie operativa. Un futuro comando CLI potrà chiamare queste utility senza introdurre una nuova fonte di autorità.
Il modello non vede route/API non presenti nel menu, non può certificare has_access per una richiesta reale senza contesto autenticato e non può trasformare la descrizione ACL in una decisione. I risultati UNKNOWN, AMBIGUOUS e DATA ACL REQUIRED sono attesi.
Sintesi diagnostica del progetto¶
La baseline statica identifica 349 registrazioni add_*, 221 nomi permission, 625 ViewMenu e 1.422 PermissionView nel catalogo PROD. Phase 2 definisce 10 capability metadata. Poiché il registry non è collegato all'application factory e non è stato avviato il bootstrap reale (che può avere side effect), il numero di NavigationItem normalizzati runtime e il mapping ruolo/item completo restano da produrre in un harness isolato.
NAVIGATION_ITEMS: NOT_RUN_RUNTIME — 349 registrazioni add_* staticamente censite; snapshot runtime isolato non eseguito.
FAB_PERMISSIONS_MAPPED: metadata extraction disponibile; conteggio runtime dipende dal SecurityManager fornito.
CAPABILITIES_DEFINED: 10
EXACT_MAPPINGS: 0 dichiarati automaticamente.
PARTIAL_MAPPINGS: 0 dichiarati automaticamente.
AMBIGUOUS_MAPPINGS: prodotti per permission generiche con module scope.
UNMAPPED_ITEMS: prodotti nei gap quando endpoint/view non espongono permission.
CUSTOM_ACL_AREAS: Documentale, RAS/DVR, Formazione, Commerciale e policy IAM/moduli.
UNKNOWN_AUTHORIZATION_AREAS: menu condizionale per utente/tenant, API/blueprint non presenti nel menu e ACL dati non interrogate.
Prerequisiti Phase 3¶
Prima di introdurre enforcement o collegare il modello a una UI servono snapshot DEV/PROD congelati, matrice endpoint/ruolo/tenant/cliente, decisione sul mapping capability/FAB e test negativi per accesso diretto e isolamento dati. Phase 3 non è iniziata.