TenantAtlas/docs/PERMISSIONS.md
Ahmed Darrazi 0e42164937 docs(004): Add Graph API permissions documentation
- Created docs/PERMISSIONS.md with complete permission requirements
- Added logging for 403 errors in ScopeTagResolver
- Updated README with link to permissions documentation

Issue: Scope tags show 'Unknown (ID: 0)' due to missing permission
Required: DeviceManagementRBAC.Read.All with admin consent

User must:
1. Go to Azure Portal → App Registration
2. Add DeviceManagementRBAC.Read.All permission
3. Grant admin consent
4. Wait 5-10 min for propagation
5. Clear cache: php artisan cache:clear
2025-12-22 16:03:21 +01:00

5.8 KiB

Microsoft Graph API Permissions

This document lists all required Microsoft Graph API permissions for TenantPilot to function correctly.

Required Permissions

The Azure AD / Entra ID App Registration used by TenantPilot requires the following Application Permissions (not Delegated):

Core Policy Management (Required)

  • DeviceManagementConfiguration.Read.All - Read Intune device configuration policies
  • DeviceManagementConfiguration.ReadWrite.All - Write/restore Intune policies
  • DeviceManagementApps.Read.All - Read app configuration policies
  • DeviceManagementApps.ReadWrite.All - Write app policies

Scope Tags (Feature 004 - Required for Phase 3)

  • DeviceManagementRBAC.Read.All - Read scope tags and RBAC settings
    • Purpose: Resolve scope tag IDs to display names (e.g., "0" → "Default")
    • Missing: Backup items will show "Unknown (ID: 0)" instead of scope tag names
    • Impact: Metadata display only - backups still work without this permission

Group Resolution (Feature 004 - Required for Phase 2)

  • Group.Read.All - Resolve group IDs to names for assignments
  • Directory.Read.All - Batch resolve directory objects (groups, users, devices)

How to Add Permissions

Azure Portal (Entra ID)

  1. Go to Azure PortalEntra ID (Azure Active Directory)
  2. Navigate to App registrations → Select your TenantPilot app
  3. Click API permissions in the left menu
  4. Click + Add a permission
  5. Select Microsoft GraphApplication permissions
  6. Search for and select the required permissions:
    • DeviceManagementRBAC.Read.All
    • (Add others as needed)
  7. Click Add permissions
  8. IMPORTANT: Click Grant admin consent for [Your Organization]
    • ⚠️ Without admin consent, the permissions won't be active!

PowerShell (Alternative)

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Application.ReadWrite.All"

# Get your app registration
$appId = "YOUR-APP-CLIENT-ID"
$app = Get-MgApplication -Filter "appId eq '$appId'"

# Add DeviceManagementRBAC.Read.All permission
$graphServicePrincipal = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"
$rbacPermission = $graphServicePrincipal.AppRoles | Where-Object {$_.Value -eq "DeviceManagementRBAC.Read.All"}

$requiredResourceAccess = @{
    ResourceAppId = "00000003-0000-0000-c000-000000000000"
    ResourceAccess = @(
        @{
            Id = $rbacPermission.Id
            Type = "Role"
        }
    )
}

Update-MgApplication -ApplicationId $app.Id -RequiredResourceAccess $requiredResourceAccess

# Grant admin consent
# (Must be done manually or via Graph API with RoleManagement.ReadWrite.Directory scope)

Verification

After adding permissions and granting admin consent:

  1. Go to App registrations → Your app → API permissions
  2. Verify status shows Granted for [Your Organization] with a green checkmark
  3. Clear cache in TenantPilot:
    php artisan cache:clear
    
  4. Test scope tag resolution:
    php artisan tinker
    >>> use App\Services\Graph\ScopeTagResolver;
    >>> use App\Models\Tenant;
    >>> $tenant = Tenant::first();
    >>> $resolver = app(ScopeTagResolver::class);
    >>> $tags = $resolver->resolve(['0'], $tenant);
    >>> dd($tags);
    
    Expected output:
    [
      [
        "id" => "0",
        "displayName" => "Default"
      ]
    ]
    

Troubleshooting

Error: "Application is not authorized to perform this operation"

Symptoms:

  • Backup items show "Unknown (ID: 0)" for scope tags
  • Logs contain: Application must have one of the following scopes: DeviceManagementRBAC.Read.All

Solution:

  1. Add DeviceManagementRBAC.Read.All permission (see above)
  2. Grant admin consent (critical step!)
  3. Wait 5-10 minutes for Azure to propagate permissions
  4. Clear cache: php artisan cache:clear
  5. Test again

Error: "Insufficient privileges to complete the operation"

Cause: The user account used to grant admin consent doesn't have sufficient permissions.

Solution:

  • Use an account with Global Administrator or Privileged Role Administrator role
  • Or have the IT admin grant consent for the organization

Permissions showing but still getting 403

Possible causes:

  1. Admin consent not granted (click the button!)
  2. Permissions not yet propagated (wait 5-10 minutes)
  3. Wrong tenant (check tenant ID in app config)
  4. Cached token needs refresh (clear cache + restart)

Feature Impact Matrix

Feature Required Permissions Without Permission Impact Level
Basic Policy Backup DeviceManagementConfiguration.Read.All Cannot backup 🔴 Critical
Policy Restore DeviceManagementConfiguration.ReadWrite.All Cannot restore 🔴 Critical
Scope Tag Names (004) DeviceManagementRBAC.Read.All Shows "Unknown (ID: X)" 🟡 Medium
Assignment Names (004) Group.Read.All + Directory.Read.All Shows group IDs only 🟡 Medium
Group Mapping (004) Group.Read.All Manual ID mapping required 🟡 Medium

Security Notes

  • All permissions are Application Permissions (app-level, not user-level)
  • Requires admin consent from Global Administrator
  • Use least privilege principle: Only add permissions for features you use
  • Consider creating separate app registrations for different environments (dev/staging/prod)
  • Rotate client secrets regularly (recommended: every 6 months)

References