Quickstart: Client application initialization - Policy SDK (C++)

This quickstart shows you how to implement the client initialization pattern used by the MIP C++ SDK Policy SDK at runtime.

Note

The steps outlined in this quickstart are required for any client application that uses the MIP Policy SDK. This quickstart should be completed after Set up and configure MIP SDK.

Prerequisites

If you haven't already, be sure to:

Create a Visual Studio solution and project

  1. Open Visual Studio 2022 or later, select the File menu, New, Project.

    • Select Console App under C++ templates.
    • Provide a Name and Location for the project.
  2. Add the NuGet package for the MIP Policy SDK to your project:

    • In the Solution Explorer, right-click the project node and select Manage NuGet packages....
    • Select Browse and enter "Microsoft.InformationProtection" in the search box.
    • Select the Microsoft.InformationProtection.Policy package and click Install.

Implement an observer class

Create a basic implementation for a Policy profile observer class by extending the SDK's mip::PolicyProfile::Observer class.

  1. Add a new class to your project named profile_observer.

  2. Replace the contents of profile_observer.h:

    #include <memory>
    #include "mip/upe/policy_profile.h"
    
    class PolicyProfileObserver final : public mip::PolicyProfile::Observer {
    public:
         PolicyProfileObserver() { }
         void OnLoadSuccess(const std::shared_ptr<mip::PolicyProfile>& profile, const std::shared_ptr<void>& context) override;
         void OnLoadFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override;
         void OnAddEngineSuccess(const std::shared_ptr<mip::PolicyEngine>& engine, const std::shared_ptr<void>& context) override;
         void OnAddEngineFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override;
    };
    
  3. Replace the contents of profile_observer.cpp:

    #include "profile_observer.h"
    #include <future>
    
    using std::promise;
    using std::shared_ptr;
    using std::exception_ptr;
    
    void PolicyProfileObserver::OnLoadSuccess(const shared_ptr<mip::PolicyProfile>& profile, const shared_ptr<void>& context) {
         auto loadPromise = static_cast<promise<shared_ptr<mip::PolicyProfile>>*>(context.get());
         loadPromise->set_value(profile);
    }
    
    void PolicyProfileObserver::OnLoadFailure(const exception_ptr& error, const shared_ptr<void>& context) {
         auto loadPromise = static_cast<promise<shared_ptr<mip::PolicyProfile>>*>(context.get());
         loadPromise->set_exception(error);
    }
    
    void PolicyProfileObserver::OnAddEngineSuccess(const shared_ptr<mip::PolicyEngine>& engine, const shared_ptr<void>& context) {
         auto addEnginePromise = static_cast<promise<shared_ptr<mip::PolicyEngine>>*>(context.get());
         addEnginePromise->set_value(engine);
    }
    
    void PolicyProfileObserver::OnAddEngineFailure(const exception_ptr& error, const shared_ptr<void>& context) {
         auto addEnginePromise = static_cast<promise<shared_ptr<mip::PolicyEngine>>*>(context.get());
         addEnginePromise->set_exception(error);
    }
    

Implement an authentication delegate and main function

  1. Add a new class to your project named auth_delegate. See Authentication concepts for details on implementing the mip::AuthDelegate interface.

  2. Update main() to create the MipContext, load a PolicyProfile, and add a PolicyEngine:

    #include "mip/mip_context.h"
    #include "mip/upe/policy_profile.h"
    #include "auth_delegate.h"
    #include "profile_observer.h"
    
    #include <iostream>
    #include <future>
    
    using std::cout;
    using std::endl;
    using std::make_shared;
    using std::shared_ptr;
    
    int main()
    {
        // Construct/initialize objects required by the application's profile object
        auto mipConfiguration = make_shared<mip::MipConfiguration>(
            "your_app_id",                          // Application ID from Microsoft Entra app registration
            "MIP SDK Policy Quickstart",            // Friendly name
            "1.0",                                  // Version
            true                                    // GUID for each machine
        );
    
        auto mipContext = mip::MipContext::Create(mipConfiguration);
    
        auto profileObserver = make_shared<PolicyProfileObserver>();
    
        auto authDelegateImpl = make_shared<sample::auth::AuthDelegateImpl>("your_app_id");
    
        mip::PolicyProfile::Settings profileSettings(mipContext,
            mip::CacheStorageType::OnDiskEncrypted,
            authDelegateImpl
        );
    
        // Load Policy Profile
        auto profilePromise = make_shared<std::promise<shared_ptr<mip::PolicyProfile>>>();
        auto profileFuture = profilePromise->get_future();
        mip::PolicyProfile::LoadAsync(profileSettings, profileObserver, profilePromise);
        auto profile = profileFuture.get();
    
        // Add a Policy Engine
        mip::PolicyEngine::Settings engineSettings(
            mip::Identity("user@contoso.com"),
            authDelegateImpl,
            "",
            "en-US",
            false
        );
    
        auto enginePromise = make_shared<std::promise<shared_ptr<mip::PolicyEngine>>>();
        auto engineFuture = enginePromise->get_future();
        profile->AddEngineAsync(engineSettings, profileObserver, enginePromise);
        auto engine = engineFuture.get();
    
        // Application using Policy engine is ready. 
        // Engine can be used to list labels, compute actions, etc.
    
        cout << "Policy engine loaded successfully." << endl;
    
        return 0;
    }
    
  3. Build and test. The application should initialize successfully and connect to the Policy service.

Next steps