DLPaC (DLP-as-Code) is a PowerShell module that enables infrastructure-as-code management of Microsoft 365 Data Loss Prevention (DLP) policies. It follows a Terraform-like workflow, allowing you to define, plan, apply, and destroy DLP policies using YAML configuration files.
- Infrastructure-as-Code: Define your DLP policies as YAML files
- Plan-Apply Workflow: Preview changes before applying them
- State Management: Track the state of your DLP policies
- Idempotent Operations: Apply the same configuration multiple times without side effects
- Import Existing: Import existing DLP policies from your tenant
- Validation: Validate your YAML configurations against a schema
- PowerShell 5.1 or higher
- ExchangeOnlineManagement module 3.0.0 or higher
- powershell-yaml module 0.4.2 or higher
-
Clone the repository:
git clone https://github.com/DLPaC/DLPaC.git
-
Import the module:
Import-Module ./DLPaC/DLPaC.psd1
Initialize-DLPaCWorkspace -Path "./dlp-workspace"Create a YAML file in the configs directory of your workspace:
# financial-data-policy.yaml
policies:
- name: "Financial Data Protection"
mode: "Enable" # Enable, Test, or Disable
priority: 1
description: "Protects financial data from unauthorized sharing"
# Policy scope
scope:
exchange: true
sharepoint: true
onedrive: true
teams: true
devices: false
# Policy rules
rules:
- name: "Credit Card Rule"
conditions:
- type: "ContentContainsPattern"
pattern: "CreditCardNumber"
minCount: 1
- type: "RecipientDomain"
operator: "NotEquals"
value: "contoso.com"
actions:
- type: "BlockAccess"
notifyUser: true
notifyAdmin: true
- name: "Banking Information Rule"
conditions:
- type: "SensitiveInfoType"
infoType: "BankAccountNumber"
minCount: 1
actions:
- type: "Encrypt"
encryptionMethod: "Office365Message"Test-DLPaCConfiguration -Path "./dlp-workspace/configs/financial-data-policy.yaml"Get-DLPaCPlan -ConfigPath "./dlp-workspace/configs" -DetailedInvoke-DLPaCApplyInvoke-DLPaCDestroy -ConfigPath "./dlp-workspace/configs/financial-data-policy.yaml"DLPaC follows a Terraform-like workflow for managing DLP policies. Here's a detailed guide to the workflow:
The first step is to initialize a workspace:
Initialize-DLPaCWorkspace -Path "./dlp-workspace" -TenantName "contoso.onmicrosoft.com" -Environment "production"This creates:
- A
.dlpacdirectory for state, plans, and logs - A
configsdirectory for your YAML policy files - An example policy file
- A
.gitignorefile
Create or edit YAML files in the configs directory to define your DLP policies. You can:
- Edit the example policy
- Create new policy files
- Import existing policies from your tenant
Before applying changes, validate your configurations:
Test-DLPaCConfiguration -Path "./dlp-workspace/configs"This checks:
- YAML syntax
- Schema compliance
- Logical consistency
Generate a plan to see what changes will be made:
Get-DLPaCPlan -ConfigPath "./dlp-workspace/configs" -DetailedThe plan shows:
- Policies to be created
- Policies to be updated
- Policies to be deleted
- Rules to be created, updated, or deleted
Apply the changes to your Microsoft 365 tenant:
Invoke-DLPaCApplyThis:
- Connects to your Microsoft 365 tenant
- Makes the changes outlined in the plan
- Updates the state file
If you have existing policies in your tenant, you can import them:
Import-DLPaCExisting -OutputPath "./dlp-workspace/configs"This:
- Retrieves policies from your tenant
- Generates YAML files
- Updates the state file
When you need to remove policies:
Invoke-DLPaCDestroy -ConfigPath "./dlp-workspace/configs/policy-to-remove.yaml"This:
- Removes the specified policies from your tenant
- Updates the state file
DLPaC uses YAML files to define DLP policies. Here's the basic structure:
policies:
- name: "Policy Name"
mode: "Enable" # Enable, Test, or Disable
priority: 1
description: "Policy description"
# Policy scope
scope:
exchange: true|false
sharepoint: true|false
onedrive: true|false
teams: true|false
devices: true|false
# Policy rules
rules:
- name: "Rule Name"
conditions:
- type: "ConditionType"
# Condition-specific properties
actions:
- type: "ActionType"
# Action-specific propertiespolicies:
- name: "Financial Data Protection"
mode: "Enable"
priority: 1
description: "Protects financial data from unauthorized sharing"
scope:
exchange: true
sharepoint: true
onedrive: true
teams: true
devices: false
rules:
- name: "Credit Card Rule"
conditions:
- type: "ContentContainsPattern"
pattern: "CreditCardNumber"
minCount: 1
actions:
- type: "BlockAccess"
notifyUser: true
notifyAdmin: truepolicies:
- name: "PII Protection Policy"
mode: "Enable"
priority: 2
description: "Protects personally identifiable information from unauthorized sharing"
scope:
exchange: true
sharepoint: true
onedrive: true
teams: true
devices: true
rules:
- name: "SSN Protection Rule"
conditions:
- type: "SensitiveInfoType"
infoType: "U.S. Social Security Number (SSN)"
minCount: 1
actions:
- type: "BlockAccess"
notifyUser: true
notifyAdmin: trueRetrieves available classifiers for DLP policies.
Get-DLPaCClassifiersCreates a new DLPaC workspace.
Initialize-DLPaCWorkspace -Path <string> [-Force]Validates DLP policy configuration files against the schema.
Test-DLPaCConfiguration -Path <string> [-Detailed]Generates a plan of changes to be applied to DLP policies.
Get-DLPaCPlan [-ConfigPath <string>] [-OutputPath <string>] [-Detailed] [-NoConnect]Applies the changes specified in the plan.
Invoke-DLPaCApply [-PlanPath <string>] [-AutoApprove]Removes DLP policies defined in the configuration.
Invoke-DLPaCDestroy [-ConfigPath <string>] [-AutoApprove]Imports existing DLP policies from the Microsoft 365 tenant.
Import-DLPaCExisting [-OutputPath <string>] [-PolicyName <string>] [-Force]DLPaC maintains a state file in the .dlpac/state directory of your workspace. This file tracks the current state of your DLP policies and is used to determine what changes need to be made when you apply a new configuration.
The state file is automatically updated when you apply changes, but you should not edit it manually.
Contributions are welcome! Please feel free to submit a Pull Request. Refer to DLPaC-Architecture.md for an overview of the project's design.
If you encounter schema validation errors when running Test-DLPaCConfiguration, check the following:
-
YAML Syntax: Ensure your YAML file has proper syntax. Common issues include:
- Incorrect indentation
- Missing or extra spaces
- Unquoted strings that contain special characters
-
Required Fields: Make sure all required fields are present:
- Each policy must have
name,mode, andrules - Each rule must have
name,conditions, andactions - Each condition must have
typeand type-specific required fields:ContentContainsPatternrequirespatternSensitiveInfoTyperequiresinfoTypeRecipientDomainrequiresoperatorandvalueAccessScoperequiresvalue
- Each action must have
typeand type-specific required fields:EncryptrequiresencryptionMethod
- Each policy must have
-
Field Values: Ensure field values match the expected types and constraints:
modemust be one of: "Enable", "Test", "Disable"prioritymust be a non-negative integer- Boolean values must be
trueorfalse(not strings)
-
Module Version: Ensure you're using the latest version of the powershell-yaml module:
Install-Module -Name powershell-yaml -Force
-
Verbose Output: Run the validation with verbose output for more details:
Test-DLPaCConfiguration -Path "path/to/config.yaml" -Verbose
For more detailed schema information, refer to the policy-schema.json file.
Use the provided scripts for debugging YAML and schema issues:
Test-SchemaValidation.ps1Test-YamlValidation.ps1
Run these scripts to validate and troubleshoot your configurations.
For long workflows, you can avoid repeated authentication prompts by manually managing a single Exchange Online session.
- Start session once:
Connect-DLPaC- Run your DLPaC workflow:
Initialize-DLPaCWorkspace -Path "./dlp-workspace" -TenantName "contoso.onmicrosoft.com" -Environment "production"
Get-DLPaCPlan -Path "./dlp-workspace/configs" -Detailed
Invoke-DLPaCApply -AutoApprove
# ... or cleanup:
Invoke-DLPaCDestroy -AutoApprove- End session:
Disconnect-DLPaCNotes:
- Standalone cmdlets still auto-connect, and will auto-disconnect unless a manual session is active.
- Connect/Disconnect are idempotent; calling them multiple times is safe.
Pre-deployment detection of unsupported action/condition/scope combinations. Runs automatically during planning via PowerShell.Get-DLPaCPlan() and during configuration validation via PowerShell.Test-DLPaCConfiguration(). Findings with severity "error" abort; "warn" logs and proceeds.
- Initialize workspace (scaffolds overrides file):
[PowerShell]
Initialize-DLPaCWorkspace -Path "./dlp-workspace"-
Edit overrides:
-
Run validation and plan (offline-friendly):
[PowerShell]
# Validate configs (schema + compatibility); fails on "error"
Test-DLPaCConfiguration -Path "./dlp-workspace/configs" -Detailed
# Plan without connecting; aborts on "error", persists "warn"
Get-DLPaCPlan -ConfigPath "./dlp-workspace/configs" -NoConnect -Detailed- Abort-on-error: Planning and config validation stop on "error" findings.
- Findings on plan: Saved under PowerShell.DLPaCPlan.CompatibilityFindings in the generated plan saved to
.dlpac/plans.
- Baseline rules (module defaults): DLPaC/Rules/compatibility-rules.yaml
- Demo config with an incompatible Encrypt on SPO/OneDrive: Test/configs/incompatible-encrypt-spo-od.yaml
Minimal override examples:
[yaml]
# Disable a default rule by id (case-insensitive)
- id: "encrypt-spo-od-unsupported"
enabled: false
# Downgrade severity to warn
- id: "encrypt-spo-od-unsupported"
severity: "warn"See the detailed design for schema, precedence, and integrations: docs/DLPaC-Enhanced-Schema-Design.md