DLP Policy Change Detector
Scheduled poll retrieves current DLP policies via Power Platform for Admins and compares to a Dataverse snapshot. On delta detected, posts a before/after diff to a Teams security channel.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
The DLP Policy Change Detector is a scheduled governance flow that monitors Data Loss Prevention (DLP) policies across your Power Platform tenant. It retrieves the current DLP policy configuration from the Power Platform Admin API, compares each policy against a stored Dataverse snapshot, and posts a formatted Teams alert when new policies are detected or existing policies are modified.
Use Case
DLP policy changes in Power Platform can have wide-reaching impact — they control which connectors makers can combine in apps and flows. Unauthorized or accidental modifications can break production flows or expose sensitive data pathways. This flow provides automated change detection so IT admins are immediately notified when policy drift occurs. The before/after comparison uses a fingerprint hash stored in Dataverse, enabling drift detection without manual auditing.
The flow is ideal for teams that:
- A new DLP policy is created in the tenant
- An existing DLP policy is modified (connector group changes, scope changes, name changes)
Flow Architecture
Recurrence
RecurrenceRuns daily at 8:00 AM UTC.
Initialize Variables (10x Parallel)
Initialize variableHydrates 8 environment variables into runtime variables (Teams Group ID, Teams Channel ID, Admin Email, Target Environment, Tenant ID, Client ID, Client Secret, Snapshot Table Name) plus 2 working variables: varChangeAlertHtml (string accumulator) and varChangeCount (integer counter).
Get DLP Policies
HTTPGET https://api.bap.microsoft.com/providers/PowerPlatform.Governance/v2/policies with ActiveDirectoryOAuth authentication using the AAD app registration credentials from env vars. This is the BAP Admin API — no standard connector operation exists for DLP policy retrieval, making HTTP the correct approach here.
Parse DLP Policy List
Parse JSONParses the JSON response to extract the `value` array containing all DLP policies with their `name` (GUID), `properties.displayName`, `properties.connectorGroups`, `properties.environmentType`, `properties.createdTime`, and `properties.lastModifiedTime`.
For Each Policy
Apply to eachIterates over every DLP policy returned. For each policy: (a) Compose a deterministic fingerprint string `displayName|connectorGroups(serialized)|environmentType` that captures meaningful configuration state; (b) Query the existing snapshot from Dataverse (`flowlibs_dlppolicysnapshots` filtered by `flowlibs_policyid eq '{policyGuid}'` with $top=1); (c) Branch on whether a snapshot exists (see condition step below).
If Snapshot Exists
If conditionChecks whether the Dataverse query returned a prior snapshot record for this policy GUID.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_TeamsGroupId | String | <configure> | Teams group (team) ID for the alert channel. Set to your security Teams group ID. |
| flowlibs_TeamsChannelId | String | <configure> | Teams channel ID for posting alerts. Set to the channel ID inside the Teams group. |
| flowlibs_AdminNotificationEmail | String | admin@contoso.com | Admin email for notifications (used by the optional Outlook SendEmailV2 extension). |
| flowlibs_TargetEnvironmentName | String | <your-tenant-id> | Target Power Platform environment identifier (typically `default-<tenant-id>` for the default environment). |
| flowlibs_GraphTenantId | String | <your-tenant-id> | Azure AD tenant ID used for OAuth against the BAP Admin API. |
| flowlibs_GraphClientId | String | <configure> | AAD app registration client (application) ID. |
| flowlibs_GraphClientSecret | String | <configure> | AAD app registration client secret. |
| flowlibs_DlpSnapshotTableName | String | flowlibs_dlppolicysnapshots | Dataverse entity set (plural) name for the DLP policy snapshot table. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Microsoft Dataverse | shared_commondataserviceforapps | ListRecords (Query existing snapshot by policy GUID) CreateRecord (New snapshot for newly-detected policy) UpdateRecord (Refresh hash + snapshot date for modified policy) |
| Microsoft Teams | shared_teams | PostMessageToConversation (Posts HTML change alert to the security channel) |
| HTTP | shared_http | HTTP (GET DLP policies from BAP Admin API with ActiveDirectoryOAuth) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Create an Azure AD App Registration
- Register an app with https://api.bap.microsoft.com/.default API permission (Application type). Grant admin consent. Note the Client ID and create a Client Secret — these populate the Graph* env vars.
- Import the solution and set env vars
- Import the solution into your target environment, then set flowlibs_GraphTenantId, flowlibs_GraphClientId, flowlibs_GraphClientSecret, flowlibs_TeamsGroupId, and flowlibs_TeamsChannelId to your tenant-specific values.
- Authorize connections and turn on the flow
- Open the flow in the designer, authorize the Dataverse and Teams connections, then turn the flow on. It will run daily at 8:00 AM UTC.
- Change the schedule
- Edit the Recurrence trigger frequency or time of day to align with your governance review cadence.
- Add email notification
- Add an Outlook SendEmailV2 action after the Teams post, using varAdminEmail as the recipient, to also send change summaries via email.
- Detect deleted policies
- Add a second loop that queries Dataverse snapshots and flags any policy IDs that no longer appear in the API response, indicating deletion.
- Filter by environment type
- Add a Filter Array before the For Each loop to only monitor AllEnvironments or OnlyEnvironments policies, narrowing the alert scope.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Policy fingerprint
Deterministic per-policy fingerprint hashed and stored in Dataverse for drift detection.
EXPR.02Snapshot filter
OData $filter used on the Dataverse ListRecords call to locate the snapshot row for the current policy.
EXPR.03Change detection
Evaluates to true when the current fingerprint differs from the stored hash, triggering the modified-policy branch.
EXPR.04BAP Admin API URL
Endpoint used by the HTTP action to list all DLP policies in the tenant.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.