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¶
- Sign in to the Microsoft Entra admin center
- Navigate to Identity → Applications → App registrations
- Click + New registration
- Configure:
- Name:
ACM-AuditComplianceManager - Supported account types: Accounts in this organizational directory only (Single tenant)
- Redirect URI: Leave blank (not needed for service principal authentication)
- Click Register
- Record the following values from the Overview page:
- Application (client) ID — used as
--client-idin Python scripts andClientIdin Power Automate flows - Directory (tenant) ID — used as
--tenant-id
1.2 Configure Authentication¶
- Navigate to Authentication in the app registration
- Under Advanced settings:
- For production (certificate / Managed Identity / app-only): set Allow public client flows to No. No redirect URI required.
- For interactive setup (the
--interactivequick-start path used bydeploy.py,create_*_schema.py, andACVClient/ALCAClient): you must set Allow public client flows to Yes AND register a public-client/native-app redirect URI ofhttp://localhost. The interactive scripts usemsal.PublicClientApplication.acquire_token_interactive(), which requires a public-client app registration. - 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. |
2.5 Grant Admin Consent¶
After adding all permissions:
- Click Grant admin consent for [Your Organization]
- Confirm by clicking Yes
- 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:
- Navigate to your app registration → Certificates & secrets → Certificates tab
- Click Upload certificate
- Select the
.cerfile - 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:
- Navigate to Azure Automation Account → Certificates
- Click + Add a certificate
- Upload the
.pfxfile with the password - Record the certificate name for use in runbook parameters
3.4 Certificate Renewal¶
Certificates should be renewed before expiration:
- Generate a new certificate using the same steps above
- Upload the new public key to the app registration (old cert can remain until cutover)
- Upload the new private key to Azure Automation
- Update the
CertificateThumbprintvariable in all Power Automate flows - 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¶
- Navigate to your app registration → Certificates & secrets → Client secrets tab
- Click + New client secret
- Configure:
- Description:
ACM Development(or descriptive name) - Expires: 6 months (recommended maximum for production; 24 months available)
- Click Add
- 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¶
- Navigate to Azure Portal → Automation Accounts → your account
- Under Account Settings, click Identity
- On the System assigned tab, set Status to On
- Click Save and confirm
- 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:
- Navigate to the Power Platform admin center
- Select the target environment → Settings → Users + permissions → Application users
- Click + New app user
- Click + Add an app and search for the Managed Identity by its Object ID or name
- Select the Business unit (root business unit)
- Under Security roles, assign System Administrator
- Click Create
Repeat for each environment the solution will monitor.
Important: Without the Application User configuration, remediation will fail with
401 Unauthorizederrors. 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)