Microsoft Information Protection SDK - File SDK profile concepts

The profile is the root class for all operations in the MIP SDK. Before using any File SDK functionality, create a FileProfile. The profile or other objects added to the profile perform all future operations.

Meet the following code prerequisites before you instantiate a profile:

  • MipContext: Create MipContext and store it in an object accessible to the mip::FileProfile object.
  • Consent delegate: ConsentDelegateImpl implements mip::ConsentDelegate.
  • Application registration: Register the application in Microsoft Entra ID and hard-code the client ID into the application or configuration files.
  • File profile observer: Implement a class that inherits mip::FileProfile::Observer.

Load a profile

After you define ProfileObserver and ConsentDelegateImpl, you can instantiate mip::FileProfile. Creating the mip::FileProfile object requires mip::MipContext and mip::FileProfile::Settings, which stores all settings information about the FileProfile.

FileProfile::Settings parameters

The FileProfile::Settings constructor accepts the following five parameters:

  • std::shared_ptr<MipContext>: The mip::MipContext object that was initialized to store application info, state path, etc.
  • mip::CacheStorageType: Defines how to store state: In memory, on disk, or on disk and encrypted.
  • std::shared_ptr<mip::ConsentDelegate>: A shared pointer of class mip::ConsentDelegate.
  • std::shared_ptr<mip::FileProfile::Observer> observer: A shared pointer to the profile Observer implementation (in PolicyProfile, ProtectionProfile, and FileProfile).

The following examples show how to create the profileSettings object by using local storage for state storage or in-memory only.

Store state in memory only

mip::ApplicationInfo appInfo {clientId, "APP NAME", "1.2.3" };

std::shared_ptr<mip::MipConfiguration> mipConfiguration = std::make_shared<mip::MipConfiguration>(mAppInfo,
			                                                                                      "mip_data",
                                                                                       			  mip::LogLevel::Trace,
                                                                                                  false);

std::shared_ptr<mip::MipContext> mMipContext = mip::MipContext::Create(mipConfiguration);

FileProfile::Settings profileSettings(
    mMipContext,                                  // mipContext object
    mip::CacheStorageType::InMemory,              // use in memory storage
    std::make_shared<ConsentDelegateImpl>(),      // new consent delegate
    std::make_shared<FileProfileObserverImpl>()); // new protection profile observer

Read/write profile settings from storage path on disk

The following code snippet instructs the FileProfile to store all app state data in ./mip_app_data.

mip::ApplicationInfo appInfo {clientId, "APP NAME", "1.2.3" };

std::shared_ptr<mip::MipConfiguration> mipConfiguration = std::make_shared<mip::MipConfiguration>(mAppInfo,
				                                                                                  "mip_data",
                                                                                        		  mip::LogLevel::Trace,
                                                                                                  false);

std::shared_ptr<mip::MipContext> mMipContext = mip::MipContext::Create(mipConfiguration);

FileProfile::Settings profileSettings(
    mMipContext,                                   // mipContext object
    mip::CacheStorageType::OnDisk,                 // use on disk storage    
    std::make_shared<ConsentDelegateImpl>(),       // new consent delegate
    std::make_shared<FileProfileObserverImpl>());  // new protection profile observer

Load the profile

After you use either previous approach, use the promise/future pattern to load the FileProfile.

auto profilePromise = std::make_shared<std::promise<std::shared_ptr<FileProfile>>>();
auto profileFuture = profilePromise->get_future();
FileProfile::LoadAsync(profileSettings, profilePromise);

If the application successfully loads a profile, ProfileObserver::OnLoadSuccess, the implementation of mip::FileProfile::Observer::OnLoadSuccess, is called. The SDK passes the resulting object or exception pointer, and the context, as parameters to the function. The context is a pointer to the std::promise created to handle the async operation. The function sets the value of the promise to the FileProfile object passed in for the first parameter. When the main function uses Future.get(), it can store the result in a new object.

//get the future value and store in profile. 
auto profile = profileFuture.get();

Putting it together

After you implement the observers and authentication delegate, you can fully load a profile. The following code snippet assumes all necessary headers are already included.

int main()
{
    const string userName = "MyTestUser@contoso.com";
    const string password = "P@ssw0rd!";
    const string clientId = "MyClientId";

    mip::ApplicationInfo appInfo {clientId, "APP NAME", "1.2.3" };

    std::shared_ptr<mip::MipConfiguration> mipConfiguration = std::make_shared<mip::MipConfiguration>(mAppInfo,
				                                                                                      "mip_data",
                                                                                        			  mip::LogLevel::Trace,
                                                                                                      false);

    std::shared_ptr<mip::MipContext> mMipContext = mip::MipContext::Create(mipConfiguration);

    FileProfile::Settings profileSettings(
        mMipContext,                                   // MipContext object
        mip::CacheStorageType::OnDisk,                 // use on disk storage        
        std::make_shared<ConsentDelegateImpl>(),       // new consent delegate
        std::make_shared<FileProfileObserverImpl>());  // new file profile observer

        auto profilePromise = std::make_shared<promise<shared_ptr<FileProfile>>>();
        auto profileFuture = profilePromise->get_future();
        FileProfile::LoadAsync(profileSettings, profilePromise);
        auto profile = profileFuture.get();
}

The code loads the profile and stores it in the object called profile.

Next steps

Now that the profile is added, the next step is to add an engine to the profile.