Assigning Rights in a Sensitivity Label for External Communications with PowerShell

Rights Management and Protection

Sensitivity Labels are built using Microsoft Information Protection (MIP) and are available to Office 365 users with E3 or above licenses. When a label protects a file or message with encryption, the ability to decrypt the item to reveal its content is governed by the rights assigned to the recipient as defined in the label settings. When you edit a label, you can assign rights such as the ability to edit or print a file to individual users and groups, everyone in your organization, all authenticated users, or people belonging to specific domains. Normally, a label will assign different sets of rights to different sets of people. It’s very flexible. The golden rule is that if the label assigned to an item doesn’t grant you the rights to open an item, you can’t.

Many sensitivity labels are used internally to protect information which should stay within an organization and there’s no need to assign rights to external recipients. But if you create labels to protect sensitive information for sharing with customers and partners, the question invariably comes up about how to maintain the rights assigned in labels created for this purpose. You can certainly edit the labels through the Information Protection section of the Microsoft 365 compliance center, but that can get boring when you need to assign rights to many different organizations.

Using PowerShell to Populate Rights Assignments

Fortunately, you can update label settings by using the Set-Label PowerShell cmdlet, part of the Exchange Online management module. To use Set-Label, you must connect to the compliance endpoint using the Connect-IPPSession cmdlet. In this example, we run Get-Credential to store the credentials to connect to Exchange Online in a variable and then use the credentials with Connect-IPPSession.

$O365Cred = Get-Credential
Connect-IPPSSession -Credential $O365Cred

To assign rights, we run Set-Label and pass the rights in the EncryptionRightsDefinitions parameter. The documentation tells us that rights are passed in a comma-separated list for a domain or email address. For example, this command assigns rights in a label called Partner-Accessible Content to open, edit, and print documents to any account in the Yandex.com domain:

Set-Label -Identity "Partner-Accessible Content" -EncryptionRightsDefinitions "quest.com:VIEW,VIEWRIGHTSDATA,DOCEDIT,PRINT”

It’s critical to understand that when you use Set-Label to update rights definitions for a label, you overwrite the existing definitions. It’s therefore important to include any definitions you want to keep in the set of definitions written back into the label. If you don’t, people depending on rights granted in the label will lose their access.

Dealing with Hundreds of Rights Definitions

The problem is that you might have tens or hundreds of different partners. Tying in a command from scratch to assign rights to large numbers of domains is likely to be both difficult and error-prone. The easiest approach is to use Excel or Notepad to create a list of partner domains, read in the list, and build the parameter in a variable before using it with Set-Label.

This code reads in partner details from a CSV file and populates the $Rights variable with the value we need to pass to Set-Label:

$InputFile = "c:\temp\InputPartnerDomains.csv"
$Permissions = ":VIEW,VIEWRIGHTSDATA,DOCEDIT,PRINT;"
# Read in list of partners to assign rights to
[array]$Partners = Import-Csv -Path $InputFile
$Rights = $Null
# Build the set of rights
For ($i = 0; $i -lt $Partners.Count; $i++)
    {
    $Rights = $Rights + $Partners[$i].Domains + $Permissions
    }
$Rights = $Rights.SubString(0, $Rights.Length -1)

With the variable populated, we can run Set-Label:

Set-Label -Identity "Partner-Accessible Content" -EncryptionRightsDefinitions $Rights

I built a list of 100 domains for testing. The length of the resulting parameter was 4,585 characters. I don’t know what the upper limit is.

Checking Assigned Rights

To check the rights defined in the label, we can extract the definitions using the Get-Label cmdlet where they are stored in the LabelActions property. Some extra processing is necessary to extract and format the rights assigned to each domain.

$Data = ConvertFrom-Json (Get-Label -Identity "Partner-Accessible Content").LabelActions[0]
$Rights = $Data.Settings | ? {$_.Value -like "*Identity*"} | Select -ExpandProperty Value
$Rights | ConvertFrom-Json | Format-List Identity, Rights

Identity : aa.com
Rights   : VIEW,VIEWRIGHTSDATA,DOCEDIT,PRINT

Identity : aerlingus.com
Rights   : VIEW,VIEWRIGHTSDATA,DOCEDIT,PRINT

Identity : aib.com
Rights   : VIEW,VIEWRIGHTSDATA,DOCEDIT,PRINT

Identity : airfrance.com
Rights   : VIEW,VIEWRIGHTSDATA,DOCEDIT,PRINT

You can also check the assigned rights through the Microsoft 365 compliance center (Figure 1).

Image 1 Expand
Sensitivity Label Lots of Partner domains
Figure 1: Viewing rights assigned in a sensitivity label (image credit: Tony Redmond)

Audit Records

Actions taken (through PowerShell or the Compliance center) to update sensitivity labels and the policies used to publish labels to users are captured as events in the Office 365 audit log. You can use search the audit log for Set-Label and Set-LabelPolicy operations to discover who makes changes to labels or policies. At least, that’s the theory. The reality is that some of the events logged for Set-Label don’t include a resolvable reference to a label while the events logged for Set-LabelPolicy don’t have anything I could tie back to a policy name.

In any case, this code creates a report of events logged for these operations over the last 90 days. You must run the Connect-ExchangeOnline cmdlet to connect to Exchange Online to search the audit log.

$TenantLabels = @{}
$Labels = Get-Label
$Labels.ForEach( {
       $TenantLabels.Add([String]$_.ImmutableId, $_.DisplayName) } )

$StartDate = (Get-Date).AddDays(-90) ; $EndDate = Get-Date
$Records = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -ResultSize 5000 -Operations Set-Label, Set-LabelPolicy
If ($Records) { # Process each audit record to find out what's been done
  CLS
  Write-Host "Analyzing" $Records.Count "audit records"
  $Report = [System.Collections.Generic.List[Object]]::new() # Create output file 
  ForEach ($Rec in $Records) {
     $AuditData = ConvertFrom-Json $Rec.Auditdata
     $TimeStamp   = Get-Date($AuditData.CreationTime) -format g
     Switch ($AuditData.Operation) {
        "Set-Label" {
           $Label = $TenantLabels.Item($AuditData.ObjectId) }
        "Set-LabelPolicy" {
           $Label = "Label Policy" }
    } #End Switch
    $ReportLine = [PSCustomObject] @{
           TimeStamp   = $TimeStamp
           User        = $AuditData.UserId
           Label       = $Label
           Parameters  = $Auditdata.Parameters
           Operation   = $Auditdata.Operation }        
    $Report.Add($ReportLine) 
 } #End ForEach
} #End if

The $Report output can be piped through Out-GridView (Figure 2) or exported to a CSV file. For example:

$Report | Select Timestamp, User, Label | Out-GridView
Image 2 Expand
Sensitivity Label Audit records
Figure 2: Viewing audit data for label and label policy updates (image credit: Tony Redmond)

Not Too Hard

Manipulating sensitivity labels with PowerShell, especially rights assignments might seem complicated but it’s reasonably straightforward. Like anything else, some preparation and testing will lead to good results. Hopefully, Microsoft will fix the deficiencies in the audit records to complete the picture. Time will tell.