mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-25 21:19:38 +00:00
879bd0c59b
Grant tenant member roles via Entra ID app-role assignments on the Enterprise App (the token's "roles" claim), in addition to the TenantAdmins table. Per-tenant opt-in via the new GA-only EntraAppRolesEnabled flag (backend-only, no ConfigVersion bump). Resolution is table-first and tri-state (NotPresent/Disabled/Enabled): an enabled table row wins, a disabled row is an explicit deny that suppresses the claim entirely (a disabled member can never be re-authorized through their app-role assignment), and only a missing row falls back to the claim. Only Admin and Operator are claim-mappable (Admin outranks Operator); Viewer and the platform GlobalAdmin role are never claim-derived. All effective-role consumers share one pure decision authority (EntraAppRoleResolver.Resolve): PolicyEnforcementMiddleware, auth/me, and feedback/status — the latter previously used a table-only check, so Entra-only members did not see the feedback bubble. GA toggle wired through the BootstrapToken pattern: TableConfigRepository persistence, UpdateTenantConfigurationFunction GA-only protection, and a checkbox in the admin tenant editor. Tests: EntraAppRoleResolverTests (incl. disabled-row deny) + an auto-promote regression guard; 2308/2308 backend green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>