Search code examples
c#azuremicrosoft-information-protectionmip-sdk

Error applying specific sensitivity label using Microsoft Information Protection SDK in C# (AdhocProtectionRequiredException)


I'm using the Microsoft Information Protection (MIP) SDK in C# to apply sensitivity labels to files. When I apply certain labels, the code works without any issues. However, when I try to apply a specific label, I encounter an error, and the label is not applied.

Here's the code snippet where the error occurs:

public static void ChangeFileLabel(string filePath, string labelId)
{

    using (var fileEngine = GetFileEngine())
    {
        using (var fileHandler = Task.Run(async () => await fileEngine.CreateFileHandlerAsync(filePath, filePath, true)).Result)
        {
            LabelingOptions labelingOptions = new LabelingOptions()
            {
                AssignmentMethod = AssignmentMethod.Standard,
                IsDowngradeJustified = true,
                JustificationMessage = "test"
            };

            fileHandler.SetLabel(label, labelingOptions, new ProtectionSettings());

            using (var memoryStream = new MemoryStream())
            {
                Task.Run(async () => await fileHandler.CommitAsync(memoryStream)).GetAwaiter().GetResult();
                memoryStream.Position = 0;
                using (var outputFileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
                {
                    memoryStream.CopyTo(outputFileStream);
                }
            }
        }
    }
}

I'm getting the following compilation errors:

Microsoft.InformationProtection.Exceptions.AdhocProtectionRequiredException: 'Label requires ad-hoc protection, but protection has not yet been set. Call FileHandler::SetProtection with ad-hoc protection settings before calling FileHandler::SetLabel.'

Additional Information:

  • The label IDs are from labels created under different admin accounts in the Microsoft Defender portal.
  • Both labels are sensitivity labels, but perhaps there's a difference in their configuration.
  • I'm using application authentication.

How can I modify my code to handle this problem? Any guidance would be greatly appreciated. Thank you!


Solution

  • It seems like the label that you're trying to set is an label with user-defined permissions. There are two types of permissions that can be related to a sensitivity label.

    1. Template-based permissions: where the permissions (rights) are set by an administrator in the Office Security and Compliance center.
    2. User-defined permissions: where the permissions (rights) are set at the time of applying the label to a file.

    Source: https://learn.microsoft.com/en-us/information-protection/develop/concept-user-defined-permissions

    To apply an sensitivity label with user-defined permissions, you have to call the FileHandler::SetProtection(...) method.

    List<UserRight> userRights = [
       new UserRights(
           users: [/* list of email addresses */], 
           rights: [/* list of policy encodings*/])
    ];
    var protectionDescriptor = new ProtectionDescriptor(userRights);
    var protectionSettings = new ProtectionSettings(/* your config */);
    fileHandler.SetProtection(protectionDescriptor, protectionSettings);
    

    The policy encodings / usage rights can be found here: https://learn.microsoft.com/en-us/azure/information-protection/configure-usage-rights#usage-rights-and-descriptions

    If you want to be able to apply both types of labels, you can put the fileHandler.SetLabel(...) call in a try catch, like how it's done here in documentation:

    try
    {
        // Attempt to set the label. If it's a UDP label, this will throw. 
        handler.SetLabel(engine.GetLabelById(options.LabelId), labelingOptions, new ProtectionSettings());
    }
    
    catch (Microsoft.InformationProtection.Exceptions.AdhocProtectionRequiredException)
    {
        // Assumes you've create a function that returns the List<UserRights> as previously detailed. 
        List<UserRights> userRightsList = GetUserRights();
    
        // Create a ProtectionDescriptor using the set of UserRights.
        ProtectionDescriptor protectionDescriptor = new ProtectionDescriptor(userRightsList);
        
        // Apply protection to the file using the new ProtectionDescriptor. 
        handler.SetProtection(protectionDescriptor, new ProtectionSettings());
    
        // Set the label. This will now succeed as protection has been defined. 
        handler.SetLabel(engine.GetLabelById(options.LabelId), labelingOptions, new ProtectionSettings());
    }
    
    // Commit the change. 
    var result = Task.Run(async () => await handler.CommitAsync("myFileOutput.xlsx")).Result;
    

    Source: https://learn.microsoft.com/en-us/information-protection/develop/concept-user-defined-permissions#when-to-apply-protection-to-files