Skip to content

Authentication Guide — Audit Compliance Manager

This guide covers all authentication methods used by the Audit Compliance Manager (ACM) solution, including Entra ID app registration, API permissions, certificate-based auth, client secrets, Managed Identity, and interactive authentication for development.

1. Entra ID App Registration

The ACV component uses a Service Principal (app registration) for certificate-based authentication. The ALCA component uses Managed Identity (see Section 5).

1.1 Create the App Registration

  1. Sign in to the Microsoft Entra admin center
  2. Navigate to IdentityApplicationsApp registrations
  3. Click + New registration
  4. Configure:
  5. Name: ACM-AuditComplianceManager
  6. Supported account types: Accounts in this organizational directory only (Single tenant)
  7. Redirect URI: Leave blank (not needed for service principal authentication)
  8. Click Register
  9. Record the following values from the Overview page:
  10. Application (client) ID — used as --client-id in Python scripts and ClientId in Power Automate flows
  11. Directory (tenant) ID — used as --tenant-id

1.2 Configure Authentication

  1. Navigate to Authentication in the app registration
  2. Under Advanced settings:
  3. For production (certificate / Managed Identity / app-only): set Allow public client flows to No. No redirect URI required.
  4. For interactive setup (the --interactive quick-start path used by deploy.py, create_*_schema.py, and ACVClient / ALCAClient): you must set Allow public client flows to Yes AND register a public-client/native-app redirect URI of http://localhost. The interactive scripts use msal.PublicClientApplication.acquire_token_interactive(), which requires a public-client app registration.
  5. The recommended pattern is two app registrations: one public-client app for interactive bootstrap, one confidential-client (or system-assigned MI) for production runbooks.

2. API Permissions

Navigate to API permissions+ Add a permission and add the following:

2.1 Microsoft Graph

Permission Type Purpose
Mail.Send Application Send compliance notification emails via shared mailbox
SecurityEvents.Read.All Application Query Purview retention policies (tenant validation)

2.2 Dynamics CRM (Dataverse)

Permission Type Purpose
user_impersonation Delegated Interactive Dataverse access during initial setup and testing

Note: For automated (non-interactive) Dataverse access, configure the service principal or Managed Identity as a Dataverse Application User instead of using delegated permissions. See Section 5.3.

2.3 Exchange Online

Permission Type Purpose
Exchange.ManageAsApp Application Service principal access to Exchange Online cmdlets (Get-AdminAuditLogConfig, Search-UnifiedAuditLog)

2.4 Office 365 Security & Compliance Center (Purview / IPPS)

Permission Type Purpose
Compliance.ManageAsApp (Office 365 Exchange Online > Application permissions) Application Service principal access to Connect-IPPSSession for Purview retention validation (used by Test-PurviewRetention.ps1 and Connect-AuditServices.ps1). Pair with the Compliance Administrator Entra role on the SP.

After adding all permissions:

  1. Click Grant admin consent for [Your Organization]
  2. Confirm by clicking Yes
  3. Verify all permissions show Status: Granted with a green checkmark

3. Certificate-Based Authentication

Certificate-based authentication is used by the ACV component for non-interactive, automated validation runs via Azure Automation runbooks and Power Automate flows.

3.1 Generate a Self-Signed Certificate

Run in PowerShell 7.2+:

# Generate a self-signed certificate valid for 2 years
$cert = New-SelfSignedCertificate `
    -Subject "CN=ACM-AuditComplianceManager" `
    -CertStoreLocation "Cert:\CurrentUser\My" `
    -KeyExportPolicy Exportable `
    -KeySpec Signature `
    -KeyLength 2048 `
    -KeyAlgorithm RSA `
    -HashAlgorithm SHA256 `
    -NotAfter (Get-Date).AddYears(2)

# Display the thumbprint (save this value)
Write-Output "Certificate Thumbprint: $($cert.Thumbprint)"

3.2 Export the Public Key (.cer)

# Export public key for upload to Entra ID app registration
Export-Certificate `
    -Cert "Cert:\CurrentUser\My\$($cert.Thumbprint)" `
    -FilePath ".\ACM-AuditComplianceManager.cer"

Upload to Entra ID:

  1. Navigate to your app registration → Certificates & secretsCertificates tab
  2. Click Upload certificate
  3. Select the .cer file
  4. Click Add

3.3 Export the Private Key (.pfx)

# Export private key for upload to Azure Automation
$password = ConvertTo-SecureString -String "<your-pfx-password>" -Force -AsPlainText
Export-PfxCertificate `
    -Cert "Cert:\CurrentUser\My\$($cert.Thumbprint)" `
    -FilePath ".\ACM-AuditComplianceManager.pfx" `
    -Password $password

Upload to Azure Automation:

  1. Navigate to Azure Automation AccountCertificates
  2. Click + Add a certificate
  3. Upload the .pfx file with the password
  4. Record the certificate name for use in runbook parameters

3.4 Certificate Renewal

Certificates should be renewed before expiration:

  1. Generate a new certificate using the same steps above
  2. Upload the new public key to the app registration (old cert can remain until cutover)
  3. Upload the new private key to Azure Automation
  4. Update the CertificateThumbprint variable in all Power Automate flows
  5. Remove the old certificate after verifying the new one works

4. Client Secret Authentication (Alternative)

Client secrets are simpler but less secure than certificates. Use only for development/testing or when certificate management is not feasible.

4.1 Create a Client Secret

  1. Navigate to your app registration → Certificates & secretsClient secrets tab
  2. Click + New client secret
  3. Configure:
  4. Description: ACM Development (or descriptive name)
  5. Expires: 6 months (recommended maximum for production; 24 months available)
  6. Click Add
  7. Immediately copy the secret value — it is only shown once

4.2 Usage in Scripts

# Use client secret instead of certificate for Python scripts
python scripts/deploy.py \
    --environment-url https://org.crm.dynamics.com \
    --tenant-id <your-tenant-id> \
    --client-id <your-app-client-id> \
    --client-secret <your-secret-value>

Security Warning: Never commit client secrets to source control. Use environment variables or Azure Key Vault for production deployments.

5. Managed Identity Setup for Azure Automation

The ALCA component (detection and remediation runbooks) uses System-Assigned Managed Identity for authentication. This is the recommended production authentication method — no certificates or secrets to manage.

5.1 Enable System-Assigned Managed Identity

  1. Navigate to Azure PortalAutomation Accounts → your account
  2. Under Account Settings, click Identity
  3. On the System assigned tab, set Status to On
  4. Click Save and confirm
  5. Record the Object (principal) ID — needed for permission assignments

5.2 Assign Entra ID Roles

Assign the following roles to the Managed Identity using PowerShell or the Entra admin center:

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory"

$miObjectId = "<managed-identity-object-id>"

# Assign Power Platform Administrator role
$ppAdminRole = Get-MgDirectoryRole -Filter "displayName eq 'Power Platform Administrator'"
New-MgDirectoryRoleMember -DirectoryRoleId $ppAdminRole.Id `
    -BodyParameter @{ "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$miObjectId" }

# Assign Exchange Online Admin (Entra role display name = 'Exchange Administrator')
$exAdminRole = Get-MgDirectoryRole -Filter "displayName eq 'Exchange Administrator'"
New-MgDirectoryRoleMember -DirectoryRoleId $exAdminRole.Id `
    -BodyParameter @{ "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$miObjectId" }

5.3 Grant Dataverse Application User Access

The Managed Identity must be configured as an Application User in every Dataverse environment you want to scan or remediate:

  1. Navigate to the Power Platform admin center
  2. Select the target environment → SettingsUsers + permissionsApplication users
  3. Click + New app user
  4. Click + Add an app and search for the Managed Identity by its Object ID or name
  5. Select the Business unit (root business unit)
  6. Under Security roles, assign System Administrator
  7. Click Create

Repeat for each environment the solution will monitor.

Important: Without the Application User configuration, remediation will fail with 401 Unauthorized errors. This is a per-environment setting — there is no tenant-wide option.

5.4 Grant Microsoft Graph API Permissions

# Grant Mail.Send permission to the Managed Identity
Connect-MgGraph -Scopes "Application.Read.All", "AppRoleAssignment.ReadWrite.All"

$miObjectId = "<managed-identity-object-id>"
$graphApp = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"
$mailSendRole = $graphApp.AppRoles | Where-Object { $_.Value -eq "Mail.Send" }

New-MgServicePrincipalAppRoleAssignment `
    -ServicePrincipalId (Get-MgServicePrincipal -Filter "displayName eq '<automation-account-name>'").Id `
    -PrincipalId $miObjectId `
    -ResourceId $graphApp.Id `
    -AppRoleId $mailSendRole.Id

6. Interactive Authentication (Development/Testing)

For local development and initial setup, use interactive authentication to avoid configuring service principals or Managed Identities.

6.1 Python Scripts (MSAL Interactive)

# The --interactive flag triggers browser-based OAuth login
python scripts/deploy.py \
    --environment-url https://org.crm.dynamics.com \
    --tenant-id <your-tenant-id> \
    --client-id <your-app-client-id> \
    --interactive

The --interactive flag uses MSAL's interactive auth flow, which opens a browser window for sign-in. The signed-in user must have sufficient permissions (Entra Global Admin or Dataverse System Administrator).

6.2 PowerShell Scripts (ACV Validators)

# ACV validators use the -Interactive switch for local testing
.\scripts\Invoke-TenantAuditValidation.ps1 -Zone Zone3 -Interactive -Verbose

.\scripts\Invoke-EnvironmentDiscovery.ps1 `
    -DataverseUrl "https://org.crm.dynamics.com" `
    -TenantId "<your-tenant-id>" `
    -Interactive

6.3 PowerShell Scripts (ALCA Runbooks)

ALCA scripts (Test-AuditLoggingCompliance.ps1, Enable-AuditLogging.ps1) are designed for Azure Automation and use Managed Identity by default. For local testing outside Azure Automation, authentication is not directly supported — use the ACV validators for local validation, and test ALCA runbooks via the Azure Automation Test pane.

7. Troubleshooting

Common Authentication Errors

Error Cause Solution
AADSTS700016: Application not found Incorrect --client-id or app not in the specified tenant Verify the Application (client) ID matches the app registration
AADSTS7000215: Invalid client secret Client secret expired or incorrect Regenerate the client secret and update the configuration
AADSTS700027: Certificate validation failed Certificate not uploaded to app registration or thumbprint mismatch Re-upload the .cer file and verify the thumbprint
401 Unauthorized on Dataverse API Managed Identity or Service Principal not configured as Application User Add the identity as an Application User with System Administrator role
403 Forbidden on Exchange Online Missing Exchange.ManageAsApp permission or Exchange Online Admin role Add the API permission and assign the Exchange Online Admin (Exchange Administrator) Entra role
Connect-ExchangeOnline: Access denied Managed Identity missing Exchange Online Admin role Assign the Exchange Online Admin (Exchange Administrator) Entra ID role to the MI
Get-AdminPowerAppEnvironment: Unauthorized Missing Power Platform Administrator role Assign the Power Platform Administrator Entra ID role
Send-MgUserMail: Insufficient privileges Missing Mail.Send permission or admin consent not granted Add Mail.Send (Application) permission and grant admin consent
Certificate not found in Automation Account Certificate not uploaded or name mismatch Navigate to Automation Account → Certificates and verify upload

Verifying Permissions

# Check Entra ID role assignments for a Managed Identity
Connect-MgGraph -Scopes "Directory.Read.All"
$mi = Get-MgServicePrincipal -Filter "displayName eq '<automation-account-name>'"
Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $mi.Id | Format-Table

# Check Dataverse Application User
# Navigate to: Power Platform admin center → Environment → Settings → Application users
# Verify the MI appears with System Administrator role

Version: 1.0.2 Last Updated: 2026-02-16 Solution: Audit Compliance Manager (ACM)