Set up Maester in GitHub
This guide will walk you through setting up Maester in GitHub and automate the running of tests using GitHub Actions.
Why GitHub?
Section titled “Why GitHub?”GitHub is the quickest and easiest way to get started with automating Maester. The free tier includes 2,000 minutes per month for private repositories which is more than enough to run your Maester tests daily.
Set up your Maester tests repository in GitHub
Section titled “Set up your Maester tests repository in GitHub”Pre-requisites
Section titled “Pre-requisites”- If you are new to GitHub, create an account at github.com
Create a new GitHub repository
Section titled “Create a new GitHub repository”- Open https://github.com/new
- Fill in the following fields:
- Repository name: E.g.
maester-tests - Private: Select this option to keep your tests private
- Repository name: E.g.
- Select Create repository
Set up the GitHub Actions workflow
Section titled “Set up the GitHub Actions workflow”There are many ways to authenticate with Microsoft Entra from GitHub Actions. We recommend using workload identity federation as it is more secure, requires less maintenance and is the easiest to set up.
If you’re unable to use more advanced options like certificates stored in Azure Key Vault, which need an Azure subscription, there’s also guidance available for using client secrets.
- Workload identity federation (recommended) uses OpenID Connect (OIDC) to authenticate with Microsoft Entra protected resources without using secrets.
- Client secret uses a secret to authenticate with Microsoft Entra protected resources.
This guide is based on Use GitHub Actions to connect to Azure and uses the maester GitHub action.
Pre-requisites Workload identity federation
Section titled “Pre-requisites Workload identity federation”Create an Entra Application
Section titled “Create an Entra Application”- Open Entra admin center > Identity > Applications > App registrations
- Tip: enappreg.cmd.ms is a shortcut to the App registrations page.
- Select New registration
- Enter a name for the application (e.g.
Maester DevOps Account) - Select Register
Grant permissions to Microsoft Graph
Section titled “Grant permissions to Microsoft Graph”- Open the application you created in the previous step
- Select API permissions > Add a permission
- Select Microsoft Graph > Application permissions
- Search for each of the permissions and check the box next to each permission:
- AuditLog.Read.All
- DeviceManagementConfiguration.Read.All
- DeviceManagementManagedDevices.Read.All
- DeviceManagementRBAC.Read.All
- DeviceManagementServiceConfig.Read.All
- Directory.Read.All
- DirectoryRecommendations.Read.All
- EntitlementManagement.Read.All
- IdentityRiskEvent.Read.All
- NetworkAccess.Read.All
- OnPremDirectorySynchronization.Read.All
- OrgSettings-AppsAndServices.Read.All
- OrgSettings-Forms.Read.All
- Policy.Read.All
- Policy.Read.ConditionalAccess
- Reports.Read.All
- ReportSettings.Read.All
- RoleEligibilitySchedule.Read.Directory
- RoleManagement.Read.All
- RoleManagementAlert.Read.Directory
- SecurityIdentitiesSensors.Read.All
- SecurityIdentitiesHealth.Read.All
- SharePointTenantSettings.Read.All
- ThreatHunting.Read.All
- UserAuthenticationMethod.Read.All
To run preview Agent ID tests, also grant these application permissions:
- AgentIdentity.Read.All
- AgentIdentityBlueprint.Read.All
- AgentIdentityBlueprintPrincipal.Read.All
- Application.Read.All
- Optionally, search for each of the permissions if you want to allow privileged permissions:
- ReportSettings.ReadWrite.All
- Required to disable report obfuscation
- ReportSettings.ReadWrite.All
- Select Add permissions
- Select Grant admin consent for [your organization]
- Select Yes to confirm
(Optional) Grant permissions to Exchange Online
(Optional) Grant permissions to Exchange Online
Section titled “(Optional) Grant permissions to Exchange Online”The Exchange Online role-based access control (RBAC) implementation uses service-specific roles for applications. The configuration below establishes the authorization chain for the app registration you created in the previous steps.
The Exchange Online permissions are necessary to support tests that validate Exchange Online configurations, such as the CISA tests.
- Open the application you created in the previous step
- Select API permissions > Add a permission
- Select APIs that my organization uses > search for Office 365 Exchange Online > Application permissions
- Search for
Exchange.ManageAsApp - Select Add permissions
- Select Grant admin consent for [your organization]
- Select Yes to confirm
- Connect to the Exchange Online Management tools and use the following to set the appropriate permissions:
New-ServicePrincipal -AppId <Application ID> -ObjectId <Object ID> -DisplayName <Name>New-ManagementRoleAssignment -Role "View-Only Configuration" -App <DisplayName from previous command>(Optional) Grant permissions to Teams
(Optional) Grant permissions to Teams
Section titled “(Optional) Grant permissions to Teams”The Teams role-based access control (RBAC) implementation uses service-specific roles for applications. The configuration below establishes the authorization chain for the app registration you created in the previous steps.
The Teams permissions are necessary to support tests that validate Teams configurations.
- Open Roles and administrators
- Search and select Teams Reader
- Select Add assigment
- Select No member selected
- Search for the name of previously created application
- Select previously created application and select Select to confirm
- Select Next to confirm
- Ensure that Active and Permanently assigned are ticked
- Enter Justification
- Select Assign to confirm
(Optional) Grant permissions to Azure
(Optional) Grant permissions to Azure
Section titled “(Optional) Grant permissions to Azure”The Azure Role-Based Access Control (RBAC) implementation uses Uniform Resource Names (URNs) with a ”/” separator for hierarchical scoping. Some resources exist within the root (e.g., ”/”) scope, and Microsoft retains strict control over them by limiting supported interactions. As a Global Administrator, you can elevate access to become authorized for these limited interactions.
The Azure RBAC permissions are necessary to support tests that validate Azure configurations, such as the CISA tests.
The following PowerShell script will enable you, with a Global Administrator role assignment, to:
- Identify the Service Principal Object ID that will be authorized as a Reader (Enterprise app Object ID)
- Install the necessary Az module and prompt for connection
- Elevate your account access to the root scope
- Create a role assignment for Reader access over the Root Scope
- Create a role assignment for Reader access over the Entra ID (i.e., aadiam provider)
- Identify the role assignment authorizing your account access to the root scope
- Delete the root scope role assignment for your account
$servicePrincipal = "<Object ID of the Entra App>"$subscription = "<Subscription ID>"Install-Module Az.Accounts -ForceInstall-Module Az.Resources -ForceConnect-AzAccount#Elevate to root scope access$elevateAccess = Invoke-AzRestMethod -Path "/providers/Microsoft.Authorization/elevateAccess?api-version=2015-07-01" -Method POST
#Assign permissions to Enterprise AppNew-AzRoleAssignment -ObjectId $servicePrincipal -Scope "/" -RoleDefinitionName "Reader" -ObjectType "ServicePrincipal"New-AzRoleAssignment -ObjectId $servicePrincipal -Scope "/providers/Microsoft.aadiam" -RoleDefinitionName "Reader" -ObjectType "ServicePrincipal"
#Remove root scope access$assignment = Get-AzRoleAssignment -RoleDefinitionId 18d7d88d-d35e-4fb5-a5c3-7773c20a72d9|?{$_.Scope -eq "/" -and $_.SignInName -eq (Get-AzContext).Account.Id}$deleteAssignment = Invoke-AzRestMethod -Path "$($assignment.RoleAssignmentId)?api-version=2018-07-01" -Method DELETE(Optional) Grant permissions to SharePoint Online
(Optional) Grant permissions to SharePoint Online
Section titled “(Optional) Grant permissions to SharePoint Online”SharePoint Online tests require the PnP.PowerShell module and an Entra ID app registration configured for interactive login with SharePoint delegated permissions.
The SharePoint Online permissions are necessary to support tests that validate SharePoint Online configurations, such as the CISA SharePoint baseline controls.
Install PnP.PowerShell
Section titled “Install PnP.PowerShell”Install-Module PnP.PowerShell -Scope CurrentUserThe easiest way to create the required app registration is to follow the official PnP PowerShell guide:
Option A — Automatically create a new PnP app registration
Section titled “Option A — Automatically create a new PnP app registration”PnP provides a built-in cmdlet to create a dedicated app registration for interactive login. This is the quickest option and the one recommended in the PnP docs:
Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "Maester PnP" -Tenant [yourtenant].onmicrosoft.com -SharePointDelegatePermissions "AllSites.FullControl"This will:
- Create an Entra ID app registration with the required delegated permissions
- Configure
http://localhostas the redirect URI automatically - Prompt you to authenticate and provide consent
- Output the Client ID you will need for
Connect-Maester
If you prefer to start from the exact example in the PnP docs, run Register-PnPEntraIDAppForInteractiveLogin with their default parameters and add -SharePointDelegatePermissions "AllSites.FullControl" for Maester’s SharePoint tests.
Note: Maester’s SharePoint tests are read-only.
AllSites.FullControl(delegated) is sufficient.Important: After registering the app, open a new PowerShell session before running
Connect-Maester, as the registration process loads PnP assemblies that can conflict with Microsoft Graph.
Option B — Reuse the existing Maester app registration
Section titled “Option B — Reuse the existing Maester app registration”If you prefer not to create a separate app, you can update the Maester app registration you created earlier to also support PnP PowerShell interactive login.
1. Add the localhost redirect URI
- Open your Maester app registration in the Entra admin center
- Select Authentication > Add a platform > Mobile and desktop applications
- In the Custom redirect URIs field, enter
http://localhost(note:http, nothttps) - Select Configure
2. Add SharePoint delegated permissions
- Select API permissions > Add a permission
- Select SharePoint > Delegated permissions
- Search for and check
AllSites.FullControl - Select Add permissions
- Select Grant admin consent for [your organization] and confirm
3. Connect using the existing Client ID
You can retrieve the Client ID of your Maester app from Graph without looking it up manually. First connect to Graph, then query for the app by its display name:
# Connect to Graph firstConnect-Maester -Service Graph
# Retrieve the Client ID of the Maester app registration$clientId = (Get-MgApplication -Filter "displayName eq 'Maester DevOps Account'").AppIdThen connect to SharePoint Online in a new session using the retrieved Client ID. The SharePoint admin URL is auto-discovered from your tenant — no need to specify it manually:
# Open a new PowerShell session, then:Connect-Maester -Service Graph,SharePointOnline -SharePointClientId $clientIdImportant: After registering the app, open a new PowerShell session before running
Connect-Maester, as PnP assemblies loaded during the session can conflict with Microsoft Graph.
Option C — App-only access (automation / non-interactive)
Section titled “Option C — App-only access (automation / non-interactive)”For unattended runs (CI pipelines, scheduled tasks) where interactive login is not possible, use application permissions with certificate-based authentication.
1. Add SharePoint application permission
- Open your app registration in the Entra admin center
- Select API permissions > Add a permission
- Select SharePoint > Application permissions
- Search for and check
Sites.FullControl.All - Select Add permissions
- Select Grant admin consent for [your organization] and confirm
2. Upload a certificate
- Select Certificates & secrets > Certificates > Upload certificate
- Upload the public key (
.cer) of your certificate
3. Connect using Connect-Maester
Pass the certificate thumbprint directly to Connect-Maester using -SharePointCertificateThumbprint. -TenantId is required for thumbprint-based auth:
$params = @{ Service = @('Graph', 'SharePointOnline') SharePointClientId = "<App Client ID>" SharePointCertificateThumbprint = "<Certificate Thumbprint>" TenantId = "<Tenant ID or domain>"}Connect-Maester @paramsThe certificate must be present in the current user’s Windows certificate store. The SharePoint admin URL is auto-discovered — supply -SharePointAdminUrl to override it if needed.
Use the Client ID from Option A or Option B when connecting:
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>"The SharePoint admin URL is auto-discovered from your tenant’s initial domain. If auto-discovery does not work (e.g. government or custom-domain tenants), supply it explicitly:
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>" -SharePointAdminUrl "https://contoso-admin.sharepoint.com"For device code flow (e.g. non-interactive sessions):
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>" -UseDeviceCode(Optional) Grant Dataverse permissions for Copilot Studio tests
(Optional) Grant Dataverse permissions for Copilot Studio
Section titled “(Optional) Grant Dataverse permissions for Copilot Studio”Dataverse access is required for the Copilot Studio security tests (MT.1113–MT.1122) that evaluate Copilot Studio agent configurations.
Create an Application User in Power Platform
Section titled “Create an Application User in Power Platform”- Go to the Power Platform Admin Center → select your environment → Settings → Users + permissions → Application users
- Click New app user → Add an app → select the app registration created above
- Select the correct Business unit
- Assign a security role with read access:
- Basic User for simplicity, or
- A custom role (e.g.
Maester Security Reader) with Organization-level Read on: Agent (bot), Agent component (botcomponent), User (systemuser), and Connection Reference (connectionreference)
- Click Create
Configure Maester
Section titled “Configure Maester”Add the environment URL to maester-config.json:
{ "GlobalSettings": { "DataverseEnvironmentUrl": "https://org12345.crm.dynamics.com" }}Add federated credentials
Section titled “Add federated credentials”- Select Certificates & secrets
- Select Federated credentials, select Add credential
- For Federated credential scenario, select GitHub Actions deploying Azure resources
- Fill in the following fields
- Organization: Your GitHub organization name or GitHub username. E.g.
jasonf - Repository: Your GitHub repository name (from the previous step). E.g.
maester-tests - Entity type:
Branch - GitHub branch name:
main - Credential details > Name: E.g.
maester-devops
- Organization: Your GitHub organization name or GitHub username. E.g.
- Select Add
Add Entra tenant info to GitHub repo
Section titled “Add Entra tenant info to GitHub repo”- Open your
maester-testsGitHub repository and go to Settings - Select Security > Secrets and variables > Actions
- Add the secrets listed below by selecting New repository secret
- To look up these values you will need to use the Entra portal, open the application you created earlier and copy the following values from the Overview page:
- Name: AZURE_TENANT_ID, Value: The Directory (tenant) ID of the Entra tenant
- Name: AZURE_CLIENT_ID, Value: The Application (client) ID of the Entra application you created
- Save each secret by selecting Add secret.
Create GitHub Action worklow for Maester
Section titled “Create GitHub Action worklow for Maester”- Open your
maester-testsGitHub repository and go to Actions - Select Skip this and set up a workflow yourself
- Copy and paste the code below into the editor
- Select Commit changes… to save the workflow
- Select Actions > maester-daily-tests to view the status of the pipeline
name: Run Maester 🔥
on: push: branches: - main
schedule: # Daily at 7:30 UTC, change accordingly - cron: "30 7 * * *"
# Allows to run this workflow manually from the Actions tab workflow_dispatch:
jobs: test: runs-on: ubuntu-latest permissions: id-token: write contents: read
steps: - name: Run Maester 🔥 id: maester # Set the action version to a specific version, to keep using that exact version. uses: maester365/maester-action@main with: tenant_id: ${{ secrets.AZURE_TENANT_ID }} client_id: ${{ secrets.AZURE_CLIENT_ID }} include_public_tests: true include_private_tests: false include_exchange: false include_teams: false # Set a specific version of the powershell module here or 'latest' or 'preview' # check out https://www.powershellgallery.com/packages/Maester/ maester_version: latest disable_telemetry: false step_summary: true
- name: Write status 📃 shell: bash run: | echo "The result of the test run is: ${{ steps.maester.outputs.result }}" echo "Total tests: ${{ steps.maester.outputs.tests_total }}" echo "Passed tests: ${{ steps.maester.outputs.tests_passed }}" echo "Failed tests: ${{ steps.maester.outputs.tests_failed }}" echo "Skipped tests: ${{ steps.maester.outputs.tests_skipped }}"This guide is based on Use GitHub Actions to connect to Azure
Pre-requisites
Section titled “Pre-requisites”- An Azure subscription is required for this method. This Azure subscription is required to set up workload identity federation authentication. No Azure resources will be created and there are no costs associated with it.
- If you don’t have an Azure subscription, you can create one by following Create a Microsoft Customer Agreement subscription or ask your Azure administrator to create one.
Create an Entra Application
Section titled “Create an Entra Application”- Open Entra admin center > Identity > Applications > App registrations
- Tip: enappreg.cmd.ms is a shortcut to the App registrations page.
- Select New registration
- Enter a name for the application (e.g.
Maester DevOps Account) - Select Register
Grant permissions to Microsoft Graph
Section titled “Grant permissions to Microsoft Graph”- Open the application you created in the previous step
- Select API permissions > Add a permission
- Select Microsoft Graph > Application permissions
- Search for each of the permissions and check the box next to each permission:
- AuditLog.Read.All
- DeviceManagementConfiguration.Read.All
- DeviceManagementManagedDevices.Read.All
- DeviceManagementRBAC.Read.All
- DeviceManagementServiceConfig.Read.All
- Directory.Read.All
- DirectoryRecommendations.Read.All
- EntitlementManagement.Read.All
- IdentityRiskEvent.Read.All
- NetworkAccess.Read.All
- OnPremDirectorySynchronization.Read.All
- OrgSettings-AppsAndServices.Read.All
- OrgSettings-Forms.Read.All
- Policy.Read.All
- Policy.Read.ConditionalAccess
- Reports.Read.All
- ReportSettings.Read.All
- RoleEligibilitySchedule.Read.Directory
- RoleManagement.Read.All
- RoleManagementAlert.Read.Directory
- SecurityIdentitiesSensors.Read.All
- SecurityIdentitiesHealth.Read.All
- SharePointTenantSettings.Read.All
- ThreatHunting.Read.All
- UserAuthenticationMethod.Read.All
To run preview Agent ID tests, also grant these application permissions:
- AgentIdentity.Read.All
- AgentIdentityBlueprint.Read.All
- AgentIdentityBlueprintPrincipal.Read.All
- Application.Read.All
- Optionally, search for each of the permissions if you want to allow privileged permissions:
- ReportSettings.ReadWrite.All
- Required to disable report obfuscation
- ReportSettings.ReadWrite.All
- Select Add permissions
- Select Grant admin consent for [your organization]
- Select Yes to confirm
(Optional) Grant permissions to Exchange Online
(Optional) Grant permissions to Exchange Online
Section titled “(Optional) Grant permissions to Exchange Online”The Exchange Online role-based access control (RBAC) implementation uses service-specific roles for applications. The configuration below establishes the authorization chain for the app registration you created in the previous steps.
The Exchange Online permissions are necessary to support tests that validate Exchange Online configurations, such as the CISA tests.
- Open the application you created in the previous step
- Select API permissions > Add a permission
- Select APIs that my organization uses > search for Office 365 Exchange Online > Application permissions
- Search for
Exchange.ManageAsApp - Select Add permissions
- Select Grant admin consent for [your organization]
- Select Yes to confirm
- Connect to the Exchange Online Management tools and use the following to set the appropriate permissions:
New-ServicePrincipal -AppId <Application ID> -ObjectId <Object ID> -DisplayName <Name>New-ManagementRoleAssignment -Role "View-Only Configuration" -App <DisplayName from previous command>(Optional) Grant permissions to Teams
(Optional) Grant permissions to Teams
Section titled “(Optional) Grant permissions to Teams”The Teams role-based access control (RBAC) implementation uses service-specific roles for applications. The configuration below establishes the authorization chain for the app registration you created in the previous steps.
The Teams permissions are necessary to support tests that validate Teams configurations.
- Open Roles and administrators
- Search and select Teams Reader
- Select Add assigment
- Select No member selected
- Search for the name of previously created application
- Select previously created application and select Select to confirm
- Select Next to confirm
- Ensure that Active and Permanently assigned are ticked
- Enter Justification
- Select Assign to confirm
(Optional) Grant permissions to Azure
(Optional) Grant permissions to Azure
Section titled “(Optional) Grant permissions to Azure”The Azure Role-Based Access Control (RBAC) implementation uses Uniform Resource Names (URNs) with a ”/” separator for hierarchical scoping. Some resources exist within the root (e.g., ”/”) scope, and Microsoft retains strict control over them by limiting supported interactions. As a Global Administrator, you can elevate access to become authorized for these limited interactions.
The Azure RBAC permissions are necessary to support tests that validate Azure configurations, such as the CISA tests.
The following PowerShell script will enable you, with a Global Administrator role assignment, to:
- Identify the Service Principal Object ID that will be authorized as a Reader (Enterprise app Object ID)
- Install the necessary Az module and prompt for connection
- Elevate your account access to the root scope
- Create a role assignment for Reader access over the Root Scope
- Create a role assignment for Reader access over the Entra ID (i.e., aadiam provider)
- Identify the role assignment authorizing your account access to the root scope
- Delete the root scope role assignment for your account
$servicePrincipal = "<Object ID of the Entra App>"$subscription = "<Subscription ID>"Install-Module Az.Accounts -ForceInstall-Module Az.Resources -ForceConnect-AzAccount#Elevate to root scope access$elevateAccess = Invoke-AzRestMethod -Path "/providers/Microsoft.Authorization/elevateAccess?api-version=2015-07-01" -Method POST
#Assign permissions to Enterprise AppNew-AzRoleAssignment -ObjectId $servicePrincipal -Scope "/" -RoleDefinitionName "Reader" -ObjectType "ServicePrincipal"New-AzRoleAssignment -ObjectId $servicePrincipal -Scope "/providers/Microsoft.aadiam" -RoleDefinitionName "Reader" -ObjectType "ServicePrincipal"
#Remove root scope access$assignment = Get-AzRoleAssignment -RoleDefinitionId 18d7d88d-d35e-4fb5-a5c3-7773c20a72d9|?{$_.Scope -eq "/" -and $_.SignInName -eq (Get-AzContext).Account.Id}$deleteAssignment = Invoke-AzRestMethod -Path "$($assignment.RoleAssignmentId)?api-version=2018-07-01" -Method DELETE(Optional) Grant permissions to SharePoint Online
(Optional) Grant permissions to SharePoint Online
Section titled “(Optional) Grant permissions to SharePoint Online”SharePoint Online tests require the PnP.PowerShell module and an Entra ID app registration configured for interactive login with SharePoint delegated permissions.
The SharePoint Online permissions are necessary to support tests that validate SharePoint Online configurations, such as the CISA SharePoint baseline controls.
Install PnP.PowerShell
Section titled “Install PnP.PowerShell”Install-Module PnP.PowerShell -Scope CurrentUserThe easiest way to create the required app registration is to follow the official PnP PowerShell guide:
Option A — Automatically create a new PnP app registration
Section titled “Option A — Automatically create a new PnP app registration”PnP provides a built-in cmdlet to create a dedicated app registration for interactive login. This is the quickest option and the one recommended in the PnP docs:
Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "Maester PnP" -Tenant [yourtenant].onmicrosoft.com -SharePointDelegatePermissions "AllSites.FullControl"This will:
- Create an Entra ID app registration with the required delegated permissions
- Configure
http://localhostas the redirect URI automatically - Prompt you to authenticate and provide consent
- Output the Client ID you will need for
Connect-Maester
If you prefer to start from the exact example in the PnP docs, run Register-PnPEntraIDAppForInteractiveLogin with their default parameters and add -SharePointDelegatePermissions "AllSites.FullControl" for Maester’s SharePoint tests.
Note: Maester’s SharePoint tests are read-only.
AllSites.FullControl(delegated) is sufficient.Important: After registering the app, open a new PowerShell session before running
Connect-Maester, as the registration process loads PnP assemblies that can conflict with Microsoft Graph.
Option B — Reuse the existing Maester app registration
Section titled “Option B — Reuse the existing Maester app registration”If you prefer not to create a separate app, you can update the Maester app registration you created earlier to also support PnP PowerShell interactive login.
1. Add the localhost redirect URI
- Open your Maester app registration in the Entra admin center
- Select Authentication > Add a platform > Mobile and desktop applications
- In the Custom redirect URIs field, enter
http://localhost(note:http, nothttps) - Select Configure
2. Add SharePoint delegated permissions
- Select API permissions > Add a permission
- Select SharePoint > Delegated permissions
- Search for and check
AllSites.FullControl - Select Add permissions
- Select Grant admin consent for [your organization] and confirm
3. Connect using the existing Client ID
You can retrieve the Client ID of your Maester app from Graph without looking it up manually. First connect to Graph, then query for the app by its display name:
# Connect to Graph firstConnect-Maester -Service Graph
# Retrieve the Client ID of the Maester app registration$clientId = (Get-MgApplication -Filter "displayName eq 'Maester DevOps Account'").AppIdThen connect to SharePoint Online in a new session using the retrieved Client ID. The SharePoint admin URL is auto-discovered from your tenant — no need to specify it manually:
# Open a new PowerShell session, then:Connect-Maester -Service Graph,SharePointOnline -SharePointClientId $clientIdImportant: After registering the app, open a new PowerShell session before running
Connect-Maester, as PnP assemblies loaded during the session can conflict with Microsoft Graph.
Option C — App-only access (automation / non-interactive)
Section titled “Option C — App-only access (automation / non-interactive)”For unattended runs (CI pipelines, scheduled tasks) where interactive login is not possible, use application permissions with certificate-based authentication.
1. Add SharePoint application permission
- Open your app registration in the Entra admin center
- Select API permissions > Add a permission
- Select SharePoint > Application permissions
- Search for and check
Sites.FullControl.All - Select Add permissions
- Select Grant admin consent for [your organization] and confirm
2. Upload a certificate
- Select Certificates & secrets > Certificates > Upload certificate
- Upload the public key (
.cer) of your certificate
3. Connect using Connect-Maester
Pass the certificate thumbprint directly to Connect-Maester using -SharePointCertificateThumbprint. -TenantId is required for thumbprint-based auth:
$params = @{ Service = @('Graph', 'SharePointOnline') SharePointClientId = "<App Client ID>" SharePointCertificateThumbprint = "<Certificate Thumbprint>" TenantId = "<Tenant ID or domain>"}Connect-Maester @paramsThe certificate must be present in the current user’s Windows certificate store. The SharePoint admin URL is auto-discovered — supply -SharePointAdminUrl to override it if needed.
Use the Client ID from Option A or Option B when connecting:
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>"The SharePoint admin URL is auto-discovered from your tenant’s initial domain. If auto-discovery does not work (e.g. government or custom-domain tenants), supply it explicitly:
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>" -SharePointAdminUrl "https://contoso-admin.sharepoint.com"For device code flow (e.g. non-interactive sessions):
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>" -UseDeviceCode(Optional) Grant Dataverse permissions for Copilot Studio tests
(Optional) Grant Dataverse permissions for Copilot Studio
Section titled “(Optional) Grant Dataverse permissions for Copilot Studio”Dataverse access is required for the Copilot Studio security tests (MT.1113–MT.1122) that evaluate Copilot Studio agent configurations.
Create an Application User in Power Platform
Section titled “Create an Application User in Power Platform”- Go to the Power Platform Admin Center → select your environment → Settings → Users + permissions → Application users
- Click New app user → Add an app → select the app registration created above
- Select the correct Business unit
- Assign a security role with read access:
- Basic User for simplicity, or
- A custom role (e.g.
Maester Security Reader) with Organization-level Read on: Agent (bot), Agent component (botcomponent), User (systemuser), and Connection Reference (connectionreference)
- Click Create
Configure Maester
Section titled “Configure Maester”Add the environment URL to maester-config.json:
{ "GlobalSettings": { "DataverseEnvironmentUrl": "https://org12345.crm.dynamics.com" }}Add federated credentials
Section titled “Add federated credentials”- Select Certificates & secrets
- Select Federated credentials, select Add credential
- For Federated credential scenario, select GitHub Actions deploying Azure resources
- Fill in the following fields
- Organization: Your GitHub organization name or GitHub username. E.g.
jasonf - Repository: Your GitHub repository name (from the previous step). E.g.
maester-tests - Entity type:
Branch - GitHub branch name:
main - Credential details > Name: E.g.
maester-devops
- Organization: Your GitHub organization name or GitHub username. E.g.
- Select Add
Create GitHub secrets
Section titled “Create GitHub secrets”- Open your
maester-testsGitHub repository and go to Settings - Select Security > Secrets and variables > Actions
- Add the secrets listed below by selecting New repository secret
- To look up these values you will need to use the Entra portal, open the application you created earlier and copy the following values from the Overview page:
- Name: AZURE_TENANT_ID, Value: The Directory (tenant) ID of the Entra tenant
- Name: AZURE_CLIENT_ID, Value: The Application (client) ID of the Entra application you created
- Save each secret by selecting Add secret.
Create GitHub Action worklow for Maester
Section titled “Create GitHub Action worklow for Maester”- Open your
maester-testsGitHub repository and go to Actions - Select Skip this and set up a workflow yourself
- Copy and paste the code below into the editor
- Select Commit changes… to save the workflow
- Select Actions > maester-daily-tests to view the status of the pipeline
name: Maester Daily Tests
on: push: branches: ["main"] # Run once a day at midnight schedule: - cron: "0 0 * * *" # Allows to run this workflow manually from the Actions tab workflow_dispatch:
permissions: id-token: write contents: read checks: write
jobs: run-maester-tests: name: Run Maester Tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set current date as env variable run: echo "NOW=$(date +'%Y-%m-%d-T%H%M%S')" >> $GITHUB_ENV - name: 'Az CLI login' uses: azure/login@v2 with: tenant-id: ${{ secrets.AZURE_TENANT_ID }} client-id: ${{ secrets.AZURE_CLIENT_ID }} allow-no-subscriptions: true - name: Run Maester uses: azure/powershell@v2 with: inlineScript: | # Get Token $token = az account get-access-token --resource-type ms-graph
# Connect to Microsoft Graph $accessToken = ($token | ConvertFrom-Json).accessToken | ConvertTo-SecureString -AsPlainText -Force Connect-MgGraph -AccessToken $accessToken
# Install Maester Install-Module Maester -Force
# Install Tests Install-MaesterTests -Path ./tests
# Configure test results $PesterConfiguration = New-PesterConfiguration $PesterConfiguration.Output.Verbosity = 'None'
# Run Maester tests $results = Invoke-Maester -Path ./tests -PesterConfiguration $PesterConfiguration -OutputFolder test-results -OutputFolderFileName "test-results" -PassThru
# Add step summary $summary = Get-Content test-results/test-results.md Add-Content -Path $env:GITHUB_STEP_SUMMARY -Value $summary
# Flag status to GitHub - Uncomment the block below to fail the build if tests fail #if ($results.Result -ne 'Passed'){ # Write-Error "Status = $($results.Result): See Maester Test Report below for details." #} azPSVersion: "latest"
- name: Archive Maester Html Report uses: actions/upload-artifact@v4 if: always() with: name: maester-test-results-${{ env.NOW }} path: test-resultsCreate an Entra Application
Section titled “Create an Entra Application”- Open Entra admin center > Identity > Applications > App registrations
- Tip: enappreg.cmd.ms is a shortcut to the App registrations page.
- Select New registration
- Enter a name for the application (e.g.
Maester DevOps Account) - Select Register
Grant permissions to Microsoft Graph
Section titled “Grant permissions to Microsoft Graph”- Open the application you created in the previous step
- Select API permissions > Add a permission
- Select Microsoft Graph > Application permissions
- Search for each of the permissions and check the box next to each permission:
- AuditLog.Read.All
- DeviceManagementConfiguration.Read.All
- DeviceManagementManagedDevices.Read.All
- DeviceManagementRBAC.Read.All
- DeviceManagementServiceConfig.Read.All
- Directory.Read.All
- DirectoryRecommendations.Read.All
- EntitlementManagement.Read.All
- IdentityRiskEvent.Read.All
- NetworkAccess.Read.All
- OnPremDirectorySynchronization.Read.All
- OrgSettings-AppsAndServices.Read.All
- OrgSettings-Forms.Read.All
- Policy.Read.All
- Policy.Read.ConditionalAccess
- Reports.Read.All
- ReportSettings.Read.All
- RoleEligibilitySchedule.Read.Directory
- RoleManagement.Read.All
- RoleManagementAlert.Read.Directory
- SecurityIdentitiesSensors.Read.All
- SecurityIdentitiesHealth.Read.All
- SharePointTenantSettings.Read.All
- ThreatHunting.Read.All
- UserAuthenticationMethod.Read.All
To run preview Agent ID tests, also grant these application permissions:
- AgentIdentity.Read.All
- AgentIdentityBlueprint.Read.All
- AgentIdentityBlueprintPrincipal.Read.All
- Application.Read.All
- Optionally, search for each of the permissions if you want to allow privileged permissions:
- ReportSettings.ReadWrite.All
- Required to disable report obfuscation
- ReportSettings.ReadWrite.All
- Select Add permissions
- Select Grant admin consent for [your organization]
- Select Yes to confirm
(Optional) Grant permissions to Exchange Online
(Optional) Grant permissions to Exchange Online
Section titled “(Optional) Grant permissions to Exchange Online”The Exchange Online role-based access control (RBAC) implementation uses service-specific roles for applications. The configuration below establishes the authorization chain for the app registration you created in the previous steps.
The Exchange Online permissions are necessary to support tests that validate Exchange Online configurations, such as the CISA tests.
- Open the application you created in the previous step
- Select API permissions > Add a permission
- Select APIs that my organization uses > search for Office 365 Exchange Online > Application permissions
- Search for
Exchange.ManageAsApp - Select Add permissions
- Select Grant admin consent for [your organization]
- Select Yes to confirm
- Connect to the Exchange Online Management tools and use the following to set the appropriate permissions:
New-ServicePrincipal -AppId <Application ID> -ObjectId <Object ID> -DisplayName <Name>New-ManagementRoleAssignment -Role "View-Only Configuration" -App <DisplayName from previous command>(Optional) Grant permissions to Teams
(Optional) Grant permissions to Teams
Section titled “(Optional) Grant permissions to Teams”The Teams role-based access control (RBAC) implementation uses service-specific roles for applications. The configuration below establishes the authorization chain for the app registration you created in the previous steps.
The Teams permissions are necessary to support tests that validate Teams configurations.
- Open Roles and administrators
- Search and select Teams Reader
- Select Add assigment
- Select No member selected
- Search for the name of previously created application
- Select previously created application and select Select to confirm
- Select Next to confirm
- Ensure that Active and Permanently assigned are ticked
- Enter Justification
- Select Assign to confirm
(Optional) Grant permissions to Azure
(Optional) Grant permissions to Azure
Section titled “(Optional) Grant permissions to Azure”The Azure Role-Based Access Control (RBAC) implementation uses Uniform Resource Names (URNs) with a ”/” separator for hierarchical scoping. Some resources exist within the root (e.g., ”/”) scope, and Microsoft retains strict control over them by limiting supported interactions. As a Global Administrator, you can elevate access to become authorized for these limited interactions.
The Azure RBAC permissions are necessary to support tests that validate Azure configurations, such as the CISA tests.
The following PowerShell script will enable you, with a Global Administrator role assignment, to:
- Identify the Service Principal Object ID that will be authorized as a Reader (Enterprise app Object ID)
- Install the necessary Az module and prompt for connection
- Elevate your account access to the root scope
- Create a role assignment for Reader access over the Root Scope
- Create a role assignment for Reader access over the Entra ID (i.e., aadiam provider)
- Identify the role assignment authorizing your account access to the root scope
- Delete the root scope role assignment for your account
$servicePrincipal = "<Object ID of the Entra App>"$subscription = "<Subscription ID>"Install-Module Az.Accounts -ForceInstall-Module Az.Resources -ForceConnect-AzAccount#Elevate to root scope access$elevateAccess = Invoke-AzRestMethod -Path "/providers/Microsoft.Authorization/elevateAccess?api-version=2015-07-01" -Method POST
#Assign permissions to Enterprise AppNew-AzRoleAssignment -ObjectId $servicePrincipal -Scope "/" -RoleDefinitionName "Reader" -ObjectType "ServicePrincipal"New-AzRoleAssignment -ObjectId $servicePrincipal -Scope "/providers/Microsoft.aadiam" -RoleDefinitionName "Reader" -ObjectType "ServicePrincipal"
#Remove root scope access$assignment = Get-AzRoleAssignment -RoleDefinitionId 18d7d88d-d35e-4fb5-a5c3-7773c20a72d9|?{$_.Scope -eq "/" -and $_.SignInName -eq (Get-AzContext).Account.Id}$deleteAssignment = Invoke-AzRestMethod -Path "$($assignment.RoleAssignmentId)?api-version=2018-07-01" -Method DELETE(Optional) Grant permissions to SharePoint Online
(Optional) Grant permissions to SharePoint Online
Section titled “(Optional) Grant permissions to SharePoint Online”SharePoint Online tests require the PnP.PowerShell module and an Entra ID app registration configured for interactive login with SharePoint delegated permissions.
The SharePoint Online permissions are necessary to support tests that validate SharePoint Online configurations, such as the CISA SharePoint baseline controls.
Install PnP.PowerShell
Section titled “Install PnP.PowerShell”Install-Module PnP.PowerShell -Scope CurrentUserThe easiest way to create the required app registration is to follow the official PnP PowerShell guide:
Option A — Automatically create a new PnP app registration
Section titled “Option A — Automatically create a new PnP app registration”PnP provides a built-in cmdlet to create a dedicated app registration for interactive login. This is the quickest option and the one recommended in the PnP docs:
Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "Maester PnP" -Tenant [yourtenant].onmicrosoft.com -SharePointDelegatePermissions "AllSites.FullControl"This will:
- Create an Entra ID app registration with the required delegated permissions
- Configure
http://localhostas the redirect URI automatically - Prompt you to authenticate and provide consent
- Output the Client ID you will need for
Connect-Maester
If you prefer to start from the exact example in the PnP docs, run Register-PnPEntraIDAppForInteractiveLogin with their default parameters and add -SharePointDelegatePermissions "AllSites.FullControl" for Maester’s SharePoint tests.
Note: Maester’s SharePoint tests are read-only.
AllSites.FullControl(delegated) is sufficient.Important: After registering the app, open a new PowerShell session before running
Connect-Maester, as the registration process loads PnP assemblies that can conflict with Microsoft Graph.
Option B — Reuse the existing Maester app registration
Section titled “Option B — Reuse the existing Maester app registration”If you prefer not to create a separate app, you can update the Maester app registration you created earlier to also support PnP PowerShell interactive login.
1. Add the localhost redirect URI
- Open your Maester app registration in the Entra admin center
- Select Authentication > Add a platform > Mobile and desktop applications
- In the Custom redirect URIs field, enter
http://localhost(note:http, nothttps) - Select Configure
2. Add SharePoint delegated permissions
- Select API permissions > Add a permission
- Select SharePoint > Delegated permissions
- Search for and check
AllSites.FullControl - Select Add permissions
- Select Grant admin consent for [your organization] and confirm
3. Connect using the existing Client ID
You can retrieve the Client ID of your Maester app from Graph without looking it up manually. First connect to Graph, then query for the app by its display name:
# Connect to Graph firstConnect-Maester -Service Graph
# Retrieve the Client ID of the Maester app registration$clientId = (Get-MgApplication -Filter "displayName eq 'Maester DevOps Account'").AppIdThen connect to SharePoint Online in a new session using the retrieved Client ID. The SharePoint admin URL is auto-discovered from your tenant — no need to specify it manually:
# Open a new PowerShell session, then:Connect-Maester -Service Graph,SharePointOnline -SharePointClientId $clientIdImportant: After registering the app, open a new PowerShell session before running
Connect-Maester, as PnP assemblies loaded during the session can conflict with Microsoft Graph.
Option C — App-only access (automation / non-interactive)
Section titled “Option C — App-only access (automation / non-interactive)”For unattended runs (CI pipelines, scheduled tasks) where interactive login is not possible, use application permissions with certificate-based authentication.
1. Add SharePoint application permission
- Open your app registration in the Entra admin center
- Select API permissions > Add a permission
- Select SharePoint > Application permissions
- Search for and check
Sites.FullControl.All - Select Add permissions
- Select Grant admin consent for [your organization] and confirm
2. Upload a certificate
- Select Certificates & secrets > Certificates > Upload certificate
- Upload the public key (
.cer) of your certificate
3. Connect using Connect-Maester
Pass the certificate thumbprint directly to Connect-Maester using -SharePointCertificateThumbprint. -TenantId is required for thumbprint-based auth:
$params = @{ Service = @('Graph', 'SharePointOnline') SharePointClientId = "<App Client ID>" SharePointCertificateThumbprint = "<Certificate Thumbprint>" TenantId = "<Tenant ID or domain>"}Connect-Maester @paramsThe certificate must be present in the current user’s Windows certificate store. The SharePoint admin URL is auto-discovered — supply -SharePointAdminUrl to override it if needed.
Use the Client ID from Option A or Option B when connecting:
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>"The SharePoint admin URL is auto-discovered from your tenant’s initial domain. If auto-discovery does not work (e.g. government or custom-domain tenants), supply it explicitly:
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>" -SharePointAdminUrl "https://contoso-admin.sharepoint.com"For device code flow (e.g. non-interactive sessions):
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>" -UseDeviceCode(Optional) Grant Dataverse permissions for Copilot Studio tests
(Optional) Grant Dataverse permissions for Copilot Studio
Section titled “(Optional) Grant Dataverse permissions for Copilot Studio”Dataverse access is required for the Copilot Studio security tests (MT.1113–MT.1122) that evaluate Copilot Studio agent configurations.
Create an Application User in Power Platform
Section titled “Create an Application User in Power Platform”- Go to the Power Platform Admin Center → select your environment → Settings → Users + permissions → Application users
- Click New app user → Add an app → select the app registration created above
- Select the correct Business unit
- Assign a security role with read access:
- Basic User for simplicity, or
- A custom role (e.g.
Maester Security Reader) with Organization-level Read on: Agent (bot), Agent component (botcomponent), User (systemuser), and Connection Reference (connectionreference)
- Click Create
Configure Maester
Section titled “Configure Maester”Add the environment URL to maester-config.json:
{ "GlobalSettings": { "DataverseEnvironmentUrl": "https://org12345.crm.dynamics.com" }}Create a client secret
Section titled “Create a client secret”- Select Certificates & secrets > Client secrets > New client secret
- Enter a description for the secret (e.g.
Maester DevOps Secret) - Select Add
- Copy the value of the secret, we will use this value in the Azure Pipeline
Create GitHub secrets
Section titled “Create GitHub secrets”- Open your
maester-testsGitHub repository and go to Settings - Select Security > Secrets and variables > Actions
- Add the three secrets listed below by selecting New repository secret
- To look up these values you will need to use the Entra portal, open the application you created earlier and copy the following values from the Overview page:
- Name: AZURE_TENANT_ID, Value: The Directory (tenant) ID of the Entra tenant
- Name: AZURE_CLIENT_ID, Value: The Application (client) ID of the Entra application you created
- Name: AZURE_CLIENT_SECRET, Value: The client secret you copied in the previous step
- Save each secret by selecting Add secret.
Create GitHub Action worklow for Maester
Section titled “Create GitHub Action worklow for Maester”- Open your
maester-testsGitHub repository and go to Actions - Select Skip this and set up a workflow yourself
- Copy and paste the code below into the editor
- Select Commit changes… to save the workflow
- Select Actions > maester-daily-tests to view the status of the pipeline
name: Maester Daily Tests
on: push: branches: ["main"] # Run once a day at midnight schedule: - cron: "0 0 * * *" # Allows to run this workflow manually from the Actions tab workflow_dispatch:
permissions: id-token: write contents: read checks: write
jobs: run-maester-tests: name: Run Maester Tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set current date as env variable run: echo "NOW=$(date +'%Y-%m-%d-T%H%M%S')" >> $GITHUB_ENV - name: Run Maester shell: pwsh env: TENANTID: ${{ secrets.AZURE_TENANT_ID }} CLIENTID: ${{ secrets.AZURE_CLIENT_ID }} CLIENTSECRET: ${{ secrets.AZURE_CLIENT_SECRET }} run: | # Connect to Microsoft Graph $clientSecret = ConvertTo-SecureString -AsPlainText $env:CLIENTSECRET -Force [pscredential]$clientSecretCredential = New-Object System.Management.Automation.PSCredential($env:CLIENTID, $clientSecret) Connect-MgGraph -TenantId $env:TENANTID -ClientSecretCredential $clientSecretCredential
# Install Maester Install-Module Maester -Force
# Install Tests Install-MaesterTests -Path ./tests
# Configure test results $PesterConfiguration = New-PesterConfiguration $PesterConfiguration.Output.Verbosity = 'None'
# Run Maester tests $results = Invoke-Maester -Path ./tests/Maester/ -PesterConfiguration $PesterConfiguration -OutputFolder test-results -OutputFolderFileName "test-results" -PassThru
# Add step summary $summary = Get-Content test-results/test-results.md Add-Content -Path $env:GITHUB_STEP_SUMMARY -Value $summary
# Flag status to GitHub - Uncomment the block below to fail the build if tests fail #if ($results.Result -ne 'Passed'){ # Write-Error "Status = $($results.Result): See Maester Test Report below for details." #}
- name: Archive Maester Html Report uses: actions/upload-artifact@v4 if: always() with: name: maester-test-results-${{ env.NOW }} path: test-resultsStep-by-step video tutorial
Section titled “Step-by-step video tutorial”Manually running the Maester tests
Section titled “Manually running the Maester tests”To manually run the Maester tests workflow
- Open your
maester-testsGitHub repository and go to Actions - Select Maester Daily Tests from the left pane
- Select Run workflow drop-down from the right pane
- Select Run workflow button to start the workflow
- Select the running workflow to view the status
Viewing test results
Section titled “Viewing test results”- Open your
maester-testsGitHub repository and go to Actions - Select a workflow run to view the results e.g.
Maester Daily Tests
Summary view
Section titled “Summary view”The summary view shows the status of the workflow run, the duration, and the number of tests that passed, failed, and were skipped.

Maester report
Section titled “Maester report”The detailed Maester report can be downloaded by selecting the maester-test-results… file from the Artifacts section and opening the test-results.html page.

Summary Maester report
Section titled “Summary Maester report”A detailed summary of the Maester report can be viewed by scrolling down Summary page.

Logs view
Section titled “Logs view”Select the Run Maester Tests job from Jobs in the left pane to view the raw logs.

Keeping your Maester tests up to date
Section titled “Keeping your Maester tests up to date”The Maester team will add new tests over time. To get the latest updates, use the commands below to update your GitHub repository with the latest tests.
- Clone your fork of the maester-tests repository to your local computer. See Cloning a repository.
- Update the
MaesterPowerShell module to the latest version and load it. - Change to the
maester-tests\testsdirectory. - Run
Update-MaesterTests.
cd maester-tests\tests
Update-Module Maester -ForceImport-Module MaesterUpdate-MaesterTests