
In this post: why every licensed Microsoft 365 tenant should block credentials with Purview DLP, what a single leaked secret can lead to, a step-by-step build in the Purview portal, and a PowerShell script that deploys the same policy in one run.
Credentials end up in places they were never meant to be. A connection string pasted into a Teams chat to unblock a colleague. An API key in a config file uploaded to a project site. A service account password emailed to a contractor. Each copy outlives the conversation that created it - it is indexed, searchable, synced to devices and retained for years.
Secrets are different from most sensitive data. A leaked customer record exposes information; a leaked credential hands over access. Most secrets - storage keys, SAS tokens, client secrets, personal access tokens - are accepted on their own. There is no MFA prompt, no Conditional Access check and often no sign-in log to give the game away.
This policy belongs in every licensed tenant
There is no reason for any organisation whose Microsoft 365 subscription includes credential scanning sensitive information types not to have this policy configured and turned on. It costs nothing extra, takes minutes to deploy and protects every user in every Microsoft 365 workload. The risks in the table below make the case on their own.
Key risks of leaked credentials
| Credential leaked | What an attacker gets | Business impact | Severity |
|---|---|---|---|
| User login credentials and passwords | Direct sign-in as the user, and often to other services where the password is reused | Account takeover and further phishing from a trusted mailbox | ● Critical |
| Azure storage account key or SAS token | Read, write and delete access to the storage account data, with no MFA or Conditional Access check | Data theft, tampering, and deletion of data and backups held in storage | ● Critical |
| Azure SQL connection string | Direct access to the database | Bulk exfiltration of customer and business data | ● Critical |
| Client secret or API key | The ability to act as the application, with every permission it has been granted | Tenant-wide data access where the app holds broad Microsoft Graph permissions | ● Critical |
| X.509 private key or management certificate | The ability to impersonate a service or authenticate as an app | Persistent access that survives user password resets | ● Critical |
| GitHub personal access token | Source code, pipelines and the secrets stored in them | Supply chain compromise | ● High |
| Slack, Google and other third-party tokens | Access to partner and SaaS platforms | Exposure that spreads beyond Microsoft 365 | ● High |
| Any of the above | A foothold for privilege escalation and lateral movement | Ransomware, and GDPR notification to the Data Protection Commission within 72 hours where personal data is put at risk | ● Critical |
Scenario: a phished mailbox
Picture a common incident. A finance user falls for a phishing email, an attacker steals their session token and gets into their mailbox. The first thing many attackers do with mailbox access is search it - for terms such as password, AccountKey= or connection string.
Now picture what they find: an email from eight months ago in which a developer sent an Azure Storage connection string to unblock a data upload. That single line contains the storage account name and its access key.
- The key works on its own. No MFA, no Conditional Access, no sign-in risk policy stands between the attacker and the data.
- The blast radius is the whole storage account. Every container, file share, queue and table in it can be read, altered or deleted.
- It stays valid until someone rotates it. Resetting the phished user’s password and revoking their sessions does nothing to the key.
- It may go unnoticed. Key-based access does not appear in Entra ID sign-in logs, and storage diagnostic logging is often not enabled.
A mailbox compromise that should have been contained to one user becomes a data breach. With this policy enforced, that email is blocked at the moment it is sent, so the key never lands in the mailbox for an attacker to find.
Existing secrets are still there. DLP stops new credentials being shared. It does not remove the ones already sitting in mailboxes, sites and chats - use the Data Security Posture Agent or a content search to find them, then rotate every one.
Why DLP is the right control
Secret scanning in code repositories and threat detection in Defender both matter, but neither stops a person sharing a secret in email or Teams. A Purview DLP policy acts at the moment of sharing, across the Microsoft 365 workloads where most collaboration happens, and applies whether the leak is careless or deliberate.
Blocking is not revocation. If the policy fires, the credential has already been typed or pasted somewhere. Treat every alert as a prompt to rotate the secret, not just as a blocked message.
Credential protection in 2026
Microsoft’s credential scanning sensitive information types (SITs) have been in Purview since 2022 (MC402123, roadmap 88941), with All Credential Types as the bundled detection. What has changed in 2026 is how much further Microsoft is taking credential detection:
- Credential scanning in the Data Security Posture Agent (MC1259828). LLM-powered detection of exposed credentials, including Entra ID credentials, private keys and API tokens, across selected data locations, with risk scores and AI-generated insights. Public preview began in late March 2026; general availability is rolling out from early October to early November 2026.
- SIT testing in DLP (MC1235742, February 2026). Upload a file of up to 2.5 MB and test it against one SIT or all of them before building a policy - a quick way to confirm your credential samples are detected.
The two work together. The posture agent finds credentials already sitting in your data estate; the DLP policy in this post stops new ones being shared. Roadmap dates move and features roll out in waves, so confirm availability in your own tenant.
The All Credential Types SIT
All Credential Types is a bundled SIT. Rather than matching a single pattern, it fires when any of its underlying credential SITs matches, using checksums or keyword and pattern combinations. Detections include:
- Azure storage account access keys and shared access signatures
- Azure SQL connection strings and Azure Redis Cache connection string passwords
- Azure Service Bus, Event Grid, SignalR and Function keys
- Client secrets and API keys
- Amazon S3 client secret access keys
- GitHub personal access tokens, Google API keys and Slack access tokens
- HTTP authorisation headers
- X.509 certificate private keys
- User login credentials and general passwords (English keywords only)
Prerequisites
| Requirement | Detail |
|---|---|
| Licensing | Microsoft 365 E5, E5 Compliance or E5 Information Protection & Governance - required for credential scanning SITs |
| Purview role group | Compliance Administrator, Compliance Data Administrator, Information Protection Admin or Security Administrator - or a custom role group with DLP Compliance Management for least privilege |
| Alert recipients | Users, groups or mail contacts that already exist in the tenant. External addresses need a mail contact first |
| PowerShell (script only) | Windows PowerShell 5.1 or PowerShell 7, with ExchangeOnlineManagement 3.2.0 or later |
Policy design
| Setting | Value | Why |
|---|---|---|
| Policy name | Block Credentials and Secrets | Clear purpose in alerts and reports |
| Locations | Exchange, SharePoint, OneDrive, Teams | Where credentials are most often shared |
| Scope | All users (full directory) | Secrets leak from every team, not just IT |
| Condition | All Credential Types, Medium confidence, 1+ instances | Broad coverage with a sensible false-positive balance |
| Action | Block everyone | A secret shared internally is still a leaked secret |
| Alerts | High severity, every match, to the security team | Every match needs triage and likely rotation |
| Incident report content | Excludes original and matched content | Stops the alert email becoming a second leak |
| Mode | Turned on immediately | Enforced as soon as the policy syncs |
Step 1 - Open Data Loss Prevention
Sign in to the Microsoft Purview portal and go to Data Loss Prevention > Policies.
Step 2 - Start a custom policy
Select Create policy, then Enterprise applications & devices. Under Categories choose Custom, select Custom policy and then Next.
Step 3 - Name the policy
Name the policy Block Credentials and Secrets, add a description and select Next. On Assign admin units, leave Full directory and select Next.
Step 4 - Choose the locations
Make sure Exchange email, SharePoint sites, OneDrive accounts and Teams chat and channel messages are ticked. Untick Devices, Instances and On-premises repositories - the portal ticks these by default, and they need extra configuration this policy does not cover.
Step 5 - Add the credential condition
On Define policy settings, choose Create or customize advanced DLP rules and select Next. Select Create rule and name it Block credentials and secrets.
Under Conditions, choose Add condition > Content contains > Add > Sensitive info types, tick All Credential Types and select Add. Leave Medium confidence and an instance count of 1 to Any.
Step 6 - Block everyone
Under Actions, choose Add an action > Restrict access or encrypt the content in Microsoft 365 locations. The default is Block only people outside your organization - change it to Block everyone.
Step 7 - Configure alerts
Under Incident reports, set the severity to High, keep Send an alert to admins when a rule match occurs on, and use Add or remove users to add your security team. If you turn on email incident reports, leave out the matched and original content so the alert never carries the secret.
Step 8 - Turn the policy on
Select Save, then Next. On Policy mode, choose Turn the policy on immediately - the default is simulation mode. Select Next, review the summary and select Submit.
Allow up to an hour for the policy to sync to all four locations before testing.
Automating it with PowerShell
The companion script New-CredentialDlpPolicy.ps1 builds the same policy and rule in one run. It lists the required privileges and licensing before it starts, prompts for the tenant ID, admin UPN and alert recipients, and then:
- Confirms the tenant ID exists, and that you signed in to that tenant, before changing anything
- Checks your account holds DLP management permissions
- Creates the policy and rule idempotently, with
-WhatIfsupport and a confirmation before enforcing - Keeps the credential itself out of incident report emails
Preview the changes, then run it:
.\New-CredentialDlpPolicy.ps1 -WhatIf
.\New-CredentialDlpPolicy.ps1
What the script runs
New-DlpCompliancePolicy -Name 'Block Credentials and Secrets' `
-ExchangeLocation All -SharePointLocation All `
-OneDriveLocation All -TeamsLocation All -Mode Enable
New-DlpComplianceRule -Name 'Block credentials and secrets' `
-Policy 'Block Credentials and Secrets' `
-ContentContainsSensitiveInformation @{
Name = 'All Credential Types'; minCount = '1'; confidencelevel = 'Medium' } `
-BlockAccess $true -BlockAccessScope All `
-GenerateAlert 'secops@contoso.com' `
-GenerateIncidentReport 'secops@contoso.com' `
-IncidentReportContent Title, DocumentAuthor, Service, Severity, RulesMatched `
-ReportSeverityLevel High
Check the policy has synced:
Get-DlpCompliancePolicy -Identity 'Block Credentials and Secrets' |
Select-Object Name, Mode, DistributionStatus
Testing and tuning
- Use synthetic credentials only. A fake GitHub token or an Azure storage connection string with a made-up key is enough to trigger the rule. Never test with a live secret.
- Validate detection first. Use the Test option under Sensitive info types to confirm your samples match before you send them.
- Watch the signals. Check Data loss prevention > Alerts and Activity explorer after each test.
- Tune General Password if it is noisy. It relies on English password keywords and is the most likely source of false positives. Raise the confidence level or handle it in a separate rule.
- Rotate, then investigate. Every true positive means a secret has been exposed. Rotate it, then find out how it got there.
The script
The script is in the GitHub repository with its README. It contains no tenant-specific IDs.
| Script | Runs | Purpose |
|---|---|---|
| New-CredentialDlpPolicy | Once, by an administrator | Creates the Block Credentials and Secrets policy and rule, with tenant, permission and licensing checks |
Wrapping up
A leaked credential is not a data protection problem waiting to happen - it is access already handed over. If your licensing includes credential scanning SITs, this policy should be on. It takes minutes in the portal or one run of the script, it covers every user across Exchange, SharePoint, OneDrive and Teams, and it turns the next pasted connection string from a breach into a blocked message and an alert.
References
- All credentials sensitive information types - Microsoft Learn
- Learn about sensitive information types - Microsoft Learn
- Connect-IPPSSession - Microsoft Learn
- MC1259828 - Credential scanning in Data Security Posture Agent
- How to test a file against DLP sensitive information types - Office 365 for IT Pros
- Script on GitHub - New-CredentialDlpPolicy
Seán O’Farrell | cloud-secure.ai