Exploring Azure AD Privileged Identity Management (PIM) – Part 4 – Access Review and Azure RBAC

Exploring Azure AD Privileged Identity Management (PIM) – Part 4 – Access Review and Azure RBAC

Access Reviews

Welcome to my final post on Azure Active Directory Privileged Identity Management (AAD PIM).  Over this series of posts I’ve provided an overview of the service, guidance on how to set the service up, and a deep dive and look at the user and approver experience.  We’ll wrap up the series by looking at the Access Review feature, take an intermission to look at a new feature, and wrap up with reviewing the Azure RBAC integration.

We have a lot to cover, so let’s jump into it.

As a quick refresher, I’ll be using my Journey Of the Geek tenant.  Within the tenant I have some Office 365 E5 and EMS E5 licenses provisioned.  Our admin user will be initiating the access review and Homer Simpson will acting as a reviewer.

I first log into the Azure Portal as the admin user and open up the AAD PIM shortcut from my dashboard.  Once the application opens, I’m going to navigate to the Azure AD directory roles option.

4aadpim1

After selecting the option my main menu is refreshed to show the management options for the various AAD PIM features.  As a quick refresher, let’s look at the settings I’ve configured for Access Reviews in my tenant.  We navigate to those Settings by clicking the Settings option as seen below and selecting Access Reviews.

4aadpim2

As you can see from the settings in the screenshot below, my tenant is set to send mail notifications to reviewers when a review is started and to admins when it finishes.  It’s also configured for reminders to be sent out to reviewers who haven’t yet completed their review.  I’ve configured reviewers to provider a reason as to why continued access to a privileged role needs to be maintained.  This is a great little option to capture the business requirements behind the access.  Finally, my access reviews are configured to run a total of 30 days.

4aadpim3

Let’s navigate back to the Access Review blade under the management menu.

4aadpim4

On the Access Reviews blade we see a listing of the access reviews in progress.  You can see I setup an access review for users that are members of the Global Admins role.  On the top we have the menu options to start a new access review, filter what access reviews are displayed, change the way they are grouped, and go back to the Access Review settings I showed earlier.

4aadpim5

et’s spin up a new access review for users who are permanent or eligible members of the User Administrators Azure AD role.  We click the Add link and a new blade opens where we can configure a number of options.  We have the basic options of naming the access review, providing a description, and a start and end date.

I’ve selected the User Administrator role as the role being reviewed during this access review.  Notice the Scope option with the Everyone radio button.  Perhaps that’s a placeholder for functionality that will be introduced in the future to limit the users within a role that the access review will cover.  I’ve selected Homer Simpson to be the reviewer for the role.  The advanced settings have inherited the global settings for my tenant for access reviews I covered previously.  Once the information is filled in, I hit the start button to kick off the access review.

4aadpim6

It takes a few minutes for the access review to be created and then it’s displayed in the listing of access reviews with a status of active.

4aadpim7

If we navigate over to Homer Simpson’s Outlook inbox, we see he has received an email informing him an access review has been kicked off and he has been designated as a reviewer and must approve or reject other members’ continued eligibility for the role.

4aadpim8

If we delay acting on the access review for a day we receive another reminder email per our settings.  The email can be seen below.

4aadpim9

If the approvers do not respond to the access review, the review completes but records that none of the users have been reviewed.

4aadpim10.png

Let’s spin up another review and complete this one.

4aadpim11

Homer Simpson again receives the notice that an Access Review has been kicked off.  Clicking the Start Review button in the email opens up the Azure Portal and the AAD PIM blade.  Here Homer gets an overview of the access review including the user who created the review, the length of the review, the description of the review, and the users who are members (permanent or eligible) for the role.

The filter option allows us to filter on the listing of users based upon whether they still need to be reviewed or have been approved or denied.

4aadpim12

We first check off Bart Simpson and see that we are required to input a reason for Bart’s approval or denial.  I input a reason and choose the deny button.  Bart disappears from the menu.  If I use the filter option to show all three categories of users, Bart now reappears under the denied category.

4aadpim13

I check off both Homer and Marge and provide a reason for both users and hit the approve button. All users have been reviewed by Homer Simpson. After refreshing the page the review now shows 0 users remaining to be reviewed.

4aadpim14

Switching over to the browser for the admin user we see that the access review is still open.

4aadpim15

If we open the access review we can see that all users have been reviewed even though the review is still active.  We have the option to Reset the access review to force the approvers to perform the access review activities again or we can stop it.  We’re going to choose end the access review early now that all the reviews have been completed.

4aadpim16

Re-opening the access review, we now have the option to apply the results of it.  After clicking he Apply button the changes are applied and we’re notified via the Portal notification system.

4aadpim17

Navigating to the roles blade under the Manage section now shows only Homer and Marge as being eligible for the User Administrator role verifying that the changes made during the access review have taken effect.

The access review feature is a wonderful addition by Microsoft.  Back in the olden days of Windows Active Directory, managing the entire lifecycle of an identity and its entitlements often involved complex third-party identity management solutions in combination with request management system.  By including this feature out of the gates, Microsoft is showing a real maturity in its identity offerings.

A Brief Intermission

Before I get into what AAD PIM can do for Azure RBAC, I want to touch on a new feature that went into public preview while I was working on this post.  Notice in the Manage section the Roles blade now has a (Preview) notation after it.

4aadpim18

Navigating into the blade shows an entirely new interface with far more useful information.  We now have a complete list of the roles AAD PIM can manage including descriptions.  If we select a role we go a level deeper and can add users to the role as we would expect.

4aadpim19

We also have two new menu options for Description and Definition.  The Description blade opens up and gives us a link to the Microsoft documentation on the role as well as every permissions the role has (AWESOME!).  The Definition blade gives us a JSON view of the role information.  Perhaps we’ll be able to create custom AAD / O365 roles in the future and we’ll be able to use these JSON views as ARM templates?  Time will tell.

4aadpim20

The introduction of this new feature is a great demonstration of how quickly things change in the cloud.

AAD PIM and Azure RBAC

Most organizations consuming Microsoft cloud services don’t just consume Office 365.  These organizations want to yield the benefits of the infrastructure-as-a-Service (IaaS) and platform-as-a-Service (PaaS) services provide by Microsoft’s Azure offering.  Managing authorization in Azure is handled through Azure Role-Based Access Control (RBAC).  In short, Azure RBAC provides a method of authorizing a security principal (user, group, or service principal) to perform an action on a resource (VM, storage account, Azure SQL, etc) based upon membership in a role.  Out of the box Microsoft provides a few roles such as owner, reader, and contributor.  You can also create custom roles to fit your business needs.

 

Similar to Office 365 prior to AAD PIM, preventing standing access of security principals in Azure RBAC roles was left to custom scripts and third-party solutions.  Last year it was announcedthat AAD PIM capabilities were being extended to Azure RBAC.  The integration of AAD PIM and Azure RBAC become generally available in the commercial offering of Azure AD in May of 2018.

For this demonstration I’m going to switch over to my Geek In The Weeds tenant.  Recall that the tenant is a synchronized and federated tenant using Azure AD Connect and Active Directory Federation Services.  I’ve already activated AAD PIM for the tenant so I’ll be jumping right into its integration with Azure RBAC.

After logging into the portal as a user who has permanent membership in the Privileged Role Administrator role I’m faced with the standard admin view of AAD PIM.  In the Manage menu I’m going to select the Azure resources option.

4aadpim21

If this is your first time using AAD PIM with Azure RBAC you’ll need to go through the discovery stage.  This will discover Azure Resources that you have write permissions to and thus have the ability to manage privileged access to.  After discovery is complete you’ll see a screen similar to the below.  You can see that my user is a member of the owners role for the Visual Studio Enterprise Azure subscription and that there are 77 roles defined for the subscription with three security principals holding one or more roles.

4aadpim22

Selecting the subscription resource gives us a dashboard displaying key metrics about PIM activity within the subscription.

4aadpim23.png

One of the metrics that caught my eye was the single user in the User Access Administrator role.  Selecting that area of the dashboard opens a new blade which lists out the members of the role.  We can see the service principal for PIM has been added to the User Access Administrator role to grant the service permissions to administer the roles within the resource (in this case a subscription).

4aadpim24

Notice also that the PIM menu for managing Azure AD/Office 365 differs for the menu for managing Azure RBAC.  We see that the new Role options I outlined above haven’t been migrated to the Azure RBAC integration yet.  Additionally we see that the request approval workflow is still in public preview in Azure RBAC.  In the Azure RBAC menu we also get a Resource Audit log which details PIM activity within the resource.

4aadpim25

Notice also that the general Settings option isn’t present in the Azure RBAC menu.  Instead we have a Role Settings option.  Selecting this option opens a new blade that lists out the Roles associated with the Resource.  Selecting any of the resources opens a new blade where we have the options of configuring a large selection of options for the role for both assignment (making the user eligible or a permanent member) as well as activation.  If you recall the configurable options for the Azure AD / Office 365 roles, these are far more granular.  The additional flexibility makes sense because these roles are going to managing IaaS and PaaS resources which are much more catered to programmatic access by non-humans.  The non-human access tends to be much more predictable than human access, so enforcing controls such as temporary eligibility for a role makes a lot of sense.

4aadpim26

Let’s take a look at what the experience is adding a user to one of the RBAC roles.  The process is very similar to AAD PIM with Azure AD / Office 365 in that we select the Roles option from the Manage section.  For this demonstration I’m going to add a user to the Virtual Machine Contributor role.

Clicking the Add Member option allows me to assign Ash Williams as an eligible member of the role.  Notice the additional option called Set membership settings.  Here I can set a timespan that Ash is eligible for the role.  This option isn’t available in AAD PIM for Azure AD / Office 365 that I could see.

4aadpim27

After hitting the add button Ash is successfully added as a Direct member to the role.  Notice that I can also add groups as members of the Role.  This is another capability unit to the Azure RBAC integration.

4aadpim28

Let’s go through the user experience for activating a role.  For the sake of simplicity I’m going to cover differences in the user experience.  You can reference my third post if you’re curious of the full user experience.

At this point I’ve logged into a virtual machine as Ash Williams and have authenticated to the Azure Portal.  I’ve entered the Azure resources blade.  Here we see the user being informed that no Azure resources are protected by PIM.  In this instance hitting the Discover resources permission will not update this menu because Ash Williams isn’t a member of any role that would grant him write permissions on an Azure Resource.  Instead I’m going to click the Activate Role button.

4aadpim29

After clicking the Activate role button I’m shown the roles Ash Williams is eligible to activate.  Notice Ash has the ability to activate the role due to both his direct membership and his membership in the GIW AIP Users group.  I’d recommend leveraging groups for this access where possible so you don’t get in the situation where you grant a security principal longer access to the role than you wanted due to a direct role assignment situation.

4aadpim30

he activation experience and approval experience is the same from this point forward so I’m going stop here.

Summing It Up

I really enjoyed this blog series.  I hadn’t done a deep dive into AAD PIM since it was in public preview and much has changed since then.  I really like how Microsoft is finally exposing capabilities which have historically been more Azure AD / Office 365 centric to Microsoft Azure.  It’s an excellent marketing tool for companies who may already be using Office 365 but are using another cloud provider for IaaS and PaaS. The product team has also done great job integrating much needed features such as approval workflows, access reviews, and metrics.

I’m not going to have the time to do a post about the AAD PIM PowerShell module but I recommend you check it out if you have some bandwidth.  There are some great opportunities there to integrate PIM functionality with third party workflow management tools to automate the entire user experience behind a GUI you users are already familiar with.

That wraps up my series on Azure AD Privileged Identity Management.  I hope you enjoyed it as much as I did.

See you next post!

Exploring Azure AD Privileged Identity Management (PIM) – Part 3 – Deep Dive

Exploring Azure AD Privileged Identity Management (PIM) – Part 3 – Deep Dive

Welcome back fellow geeks to my third post on my series covering Azure AD Privileged Identity Management (AAD PIM).  In my first post I provided an overview of the service and in my second post I covered the initial setup and configuration of PIM.  In this post we’re going to take a look at role activation and approval as well as looking behind the scenes to see if we can figure out makes the magic of AAD PIM work.

The lab I’ll be using consists of a non-domain joined Microsoft Windows 10 Professional version 1803 virtual machine (VM) running on Hyper V on my home lab.  The VM has a local user configured that is a member of the Administrators group.  I’ll be using Microsoft Edge and Google Chrome as my browsers and running Telerik’s Fiddler to capture the web conversation.  The users in this scenario will be sourced from the Journey Of The Geek tenant and one will be licensed with Office 365 E5 and EMS E5 and the other will be licensed with just EMS E5.  The tenant is not synchronized from an on-premises Windows Active Directory.  The user Homer Simpsons has been made eligible for the Security Administrators role.

With the intro squared away, let’s get to it.

First thing I will do is navigate to the Azure Portal and authenticate as Homer Simpson.  As expected, since the user is not Azure MFA enforced, he is allowed to authenticate to the Azure Portal with just a password.  Once I’m into the Azure Portal I need to go into AAD PIM which I do from the shortcut I added to the user’s dashboard.

3pim1.png

Navigating to the My roles section of the menu I can see that the user is eligible to for the Security Administrator Azure Active Directory (AAD) role.

3pim2

Selecting the Activate link opens up a new section where the user will complete the necessary steps to activate the role.  As you can see from my screenshot below, the Security Administrator role is one of the roles Microsoft considers high risk and enforces step-up authentication via Azure MFA.  Selecting the Verify your identity before proceeding link opens up another section that informs the user he or she needs to verify the identity with an MFA challenge.  If the user isn’t already configured for MFA, they will be setup for it at this stage.

3pim3.png

Homer Simpson is already configured for MFA so after the successful response to the MFA challenge the screen refreshes and the Activation button can now be clicked.

3pim4.png

After clicking the Activation button I enter a new section where I can configure a custom start time, configuration an activation duration (up to the maximum configured for the Role), provide ticketing information, and provide an activation reason..  As you can see I’ve adjusted the max duration for an activation from the default of one hour to three hours and have configured a requirement to provide a ticket number.  This could be mapped back to your internal incident or change management system.

3pim5.png

After filling in the required information I click the Activate button, the screen refreshes back to the main request screen, and I’m informed that activation for this role requires approval.  In addition to modifying the activation and requiring a ticket number, I also configured the role to require approval.

3pim6.png

At this point I opened an instance of Google Chrome and authenticated to Azure AD as a user who is in the privileged role administrator role.  Opening up AAD PIM with this user and navigating to the My roles section and looking at the Active roles shows the user is a permanent member of the Security Administrators, Global Administrators, and Privileged Role Administrators roles.

3pim7.png

I then navigate over to the Approve requests section.  Here I can see the pending request from Homer Simpson requesting activation of the Security Administrator role.  I’m also provided with the user’s reason and start and end time.  I’d like to see Microsoft add a column for the user’s ticket number.  My approving user may want to reference the ticket for more detail on why the user is requesting the role

3pim8.png

At this point I select the pending request and click the Approve button.  A new section opens where I need to provide the approval reason after which I hit the Approve button.

3pim9.png

After approving the blue synchronization-like image is refreshed to a green check box indicating the approval has been process and the user’s role is now active.

3pim10

If I navigate to My audit history section I can see the approval of Homer’s request has been logged as well as the reasoning I provided for my approval.

3pim11.png

If I bounce back to the Microsoft Edge browser instance that Homer Simpsons is logged into and navigate to the My requests and I can see that my activation has been approved and it’s now active.

3pim12.png

At this point I have requested the role and the role has been approved by a member of the Privileged Role Administrators role.  Let’s try modifying an AIP Policy.  Navigating back to Homer Simpsons dashboard I select the Azure Information Protection icon and receive the notification below.

3pim13.png

What happened?  Navigating to Homer Simpsons mailbox shows the email confirming the role has been activated.

3pim14.png

What gives?  To figure out the answer to that question, I’m going to check on the Fiddler capture I started before logging in as Homer Simpson.

In this capture I can see my browser sending my bearer token to various AIP endpoints and receiving a 401 return code with an error indicating the user isn’t a member of the Global Administrators or Security Administrators roles.

3pim15.png

I’ll export the bearer token, base64 decode it and stick it into Notepad. Let’s refresh the web page and try accessing AIP again. As we can see AIP opens without issues this time.

3pim16.png

At this point I dumped the bearer token from the failure and the bearer token from a success and compared the two as seen below.  The IAT, NBF, and EXP are simply speak to times specific to the claim.  I can’t find any documentation on the aio or uti claims.  If anyone has information on those two, I’d love to see it.

3pim17.png

I thought it would be interesting at this point to deactivate my access and see if I could still access AIP.  To deactivate a role the user simply accesses AAD PIM, goes to My Roles and looks the Active Roles section as seen below.

3pim18.png

After deactivation I went back to the dashboard and was still able to access AIP.  After refreshing the browser I was unable to access AIP.  Since I didn’t see any obvious cookies or access tokens being created or deleted.  My guess at this point is applications that use Azure AD or Office 365 Roles have some type of method of receiving data from AAD PIM.  A plausible scenario would be an application receives a bearer token, queries Azure AD to see if the user is in one a member of the relevant roles for the application.  Perhaps for eligible roles there is an additional piece of information indicating the timespan the user has the role activated and that time is checked against the time the bearer token was issued.  That would explain my experience above because the bearer token my browser sent to AIP was obtained prior to activating my role.  I verified this by comparing the bearer token issued from the delegation point at first login to the one sent to AIP after I tried accessing it after activation.  Only after a refresh did I obtain a new bearer token from the delegation endpoint.

Well folks that’s it for this blog entry.  If you happen to know the secret sauce behind how AAD PIM works and why it requires a refresh I’d love to hear it!  See you next post.

The Evolution of AD RMS to Azure Information Protection – Part 7 – Deep Dive into cross Azure AD tenant consumption

The Evolution of AD RMS to Azure Information Protection – Part 7 – Deep Dive into cross Azure AD tenant consumption

Each time I think I’ve covered what I want to for Azure Information Protection (AIP), I think of another fun topic to explore.  In this post I’m going to look at how AIP can be used to share information with users that exist outside your tenant.  We’ll be looking at the scenario where an organization has a requirement to share protected content with another organization that has an Office 365 tenant.

Due to my requirements to test access from a second tenant, I’m going to supplement the lab I’ve been using.  I’m adding to the mix my second Azure AD tenant at journeyofthegeek.com.  Specific configuration items to note are as follows:

  • The tenant’s custom domain of journeyofthegeek.com is an Azure AD (AAD)-managed domain.
  • I’ve created two users for testing.  The first is named Homer Simpson (homer.simpson@journeyofthegeek.com) and the second is Bart Simpson (bart.simpson@journeyofthegeek.com).
  • Each user have been licensed with Office 365 E3 and Enterprise Mobility + Security E5 licenses.
  • Three mail-enabled security groups have been created.  The groups are named The Simpsons (thesimpsons@journeyofthegeek.com), JOG Accounting (jogaccounting@journeyofthegeek.com), and JOG IT (jogit@journeyofthegeek.com).
  • Homer Simpson is a member of The Simpsons and JOG Accounting while Bart Simpson is a member of The Simpsons and JOG IT.
  • Two additional AIP policies have been created in addition to the Global policy.  One policy is named JOG IT and one is named JOG Accounting.
  • The Global AIP policy has an additional label created named PII that enforces protection.  The label is configured to detect at least one occurrence of a US social security number.  The document is protection policy allows only members of the The Simpsons group to the role of viewer.
  • The JOG Accounting and JOG IT AIP policies have both been configured with an additional label of either JOG Accounting or JOG IT.  A sublabel for each label has also been created which enforces protection and restricts members of the relevant departmental group to the role of viewer.
  • I’ve repurposed the GIWCLIENT2 machine and have created two local users named Bart Simpson and Homer Simpson.

Once I had my tenant configuration up and running, I initialized Homer Simpson on GIWCLIENT2.  I already had the AIP Client installed on the machine, so upon first opening Microsoft Word, the same bootstrapping process I described in my previous post occurred for the MSIPC client and the AIP client.  Notice that the document has had the Confidential \ All Employees label applied to the document automatically as was configured in the Global AIP policy.  Notice also the Custom Permissions option which is presented to the user because I’ve enabled the appropriate setting in the relevant AIP policies.

7aip1.png

I’ll be restricting access to the document by allowing users in the geekintheweeds.com organization to hold the Viewer role.  The geekintheweeds.com domain is associated with my other Azure AD tenant that I have been using for the lab for this series of posts.  First thing I do is change the classification label from Confidential \ All Employees to General.  That label is a default label provided by Microsoft which has an RMS Template applied that restricts viewers to users within the tenant.

One interesting finding I discovered through my testing is that the user can go through the process of protecting with custom permissions using a label that has a pre-configured template and the AIP client won’t throw any errors, but the custom permissions won’t be applied.  This makes perfect sense from a security perspective, but it would be nice to inform the user with an error or warning.  I can see this creating unnecessary help desk calls with how it’s configured now.

When I attempt to change my classification label to General, I receive a prompt requiring me to justify the drop in classification.  This is yet another setting I’ve configured in my Global AIP policy.  This seems to be a standard feature in most data classification solutions from what I’ve observed in another major vendor.

7aip2.png

After successfully classifying the document with the General label protection is removed from the document. At this point I can apply my custom permissions as seen below.

7aip3.png

I repeated the process for another protected doc named jog_protected_for_Ash_Williams.docx with permissions restricted to ash.williams@geekintheweeds.com.  I packaged both files into an email and sent them to Ash Williams who is a user in the Geek In The Weeds tenant.  Keep in mind the users in the Geek In The Weeds tenant are synchronized from a Windows Active Directory domain and use federated authentication.

After opening Outlook the message email from Homer Simpson arrives in Ash William’s inbox.   At this point I copied the files to my desktop, closed Outlook, opened Microsoft Word and used the “Reset Settings” options of the AIP client, and signed out of my Office profile.

7aip4

At this point I started Fiddler and opened one of the Microsoft Word document. Microsoft Word pops-up a login prompt where I type in my username of ash.williams@geekintheweeds.com and I’m authenticated to Office 365 through the standard federated authentication flow. The document then pops open.

7aip5.png

Examining the Fiddler capture we see a lot of chatter. Let’s take a look at this in chunks, first addressing the initial calls to the AIP endpoint.

7aip6

If you have previous experience with the MSIPC client in the AD RMS world you’ll recall that it makes its calls in the following order:

  1. Searches HKLM registry hive
  2. Searches HKCU registry hive
  3. Web request to the RMS licensing pipeline for the RMS endpoint listed in the metadata attached to the protected document

In my previous deep dives into AD RMS we observed this behavior in action.  In the AIP world, it looks like the MSIPC client performs similarly.  The endpoint we see it first contacting is the Journey of the Geek which starts with 196d8e.

The client first sends an unauthenticated HTTP GET to the Server endpoint in the licensing pipeline. The response the server gives is a list of available SOAP functions which include GetLicensorCertificate and GetServerInfo as seen below.

7aip8.png

The client follows up the actions below:

  1. Now that the client knows the endpoint supports the GetServerInfo SOAP function, it sends an unauthenticated HTTP POST which includes the SOAP action of GetServerInfo.  The AIP endpoint returns a response which includes the capabilities of the AIP service and the relevant endpoints for certification and the like.
  2. It uses that information received from the previous request to send an unauthenticated HTTP POST which includes the SOAP action of ServiceDiscoveryForUser.  The service returns a 401.

At this point the client needs to obtain a bearer access token to proceed.  This process is actually pretty interesting and warrants a closer look.

7aip9

Let’s step through the conversation:

  1. We first see a connection opened to odc.officeapps.live.com and an unauthenticated HTTP GET to the /odc/emailhrd/getfederationprovider URI with query strings of geekintheweeds.com.  This is a home realm discovery process trying to the provider for the user’s email domain.

    My guess is this is MSAL In action and is allowing support for multiple IdPs like Azure AD, Microsoft Live, Google, and the like.  I’ll be testing this theory in a later post where I test consumption by a Google user.

    The server responds with a number of headers containing information about the token endpoints for Azure AD (since this is domain associated with an Azure AD tenant.)

    7aip10.png

  2. A connection is then opened to odc.officeapps.live.com and an unauthenticated HTTP GET to the /odc/emailhrd/getidp with the email address for my user ash.williams@geekintheweeds.com. The response is interesting in that I would have thought it would return the user’s tenant ID. Instead it returns a JSON response of OrgId.

    7aip11.png

    Since I’m a nosey geek, I decided to unlock the session for editing.  First I put in the email address associated with a Microsoft Live.  Instead of OrgId it returned MSA which indicates it detects it as being a Microsoft Live account.  I then plugged in a @gmail.com account to see if I would get back Google but instead I received back neither.  OrgId seems to indicate that it’s an account associated with an Azure AD tenant.  Maybe it would perform alternative steps depending on whether it’s MSA or Azure AD in future steps?  No clue.

  3. Next, a connection is made to oauth2 endpoint for the journeyofthegeek.com tenant. The machine makes an unathenticated requests an access token for the https://api.aadrm.com/ in order to impersonate Ash Williams. Now if you know your OAuth, you know the user needs to authenticate and approve the access before the access token can be issued. The response from the oauth2 endpoint is a redirect over to the AD FS server so the user can authenticate.

    7aip12.png

  4. After the user successfully authenticates, he is returned a security token and redirected back to login.microsoftonline.com where the assertion is posted and the user is successfully authenticated and is returned an authorization code.

    7aip13.png

  5. The machine then takes that authorization code and posts it to the oauth2 endpoint for my journeyofthegeek.com tenant. It receives back an Open ID Connect id token for ash.williams, a bearer access token, and a refresh token for the Azure RMS API.

    7aip14.png

    Decoding the bearer access token we come across some interesting information.  We can see the audience for the token is the Azure RMS API, the issuer of the token is the tenant id associated with journeyofthegeek.com (interesting right?), and the identity provider for the user is the tenant id for geekintheweeds.com.

    7aip15.png

  6. After the access token is obtained the machine closes out the session with login.microsoftonline.com and of course dumps a bunch of telemetry (can you see the trend here?).

    7aip16.png

  7. A connection is again made to odc.officeapps.live.com and the /odc/emailhrd/getfederationprovider URI with an unauthenticated request which includes a query string of geekintheweeds.com. The same process as before takes place.

Exhausted yet?  Well it’s about to get even more interesting if you’re an RMS nerd like myself.

7aip17.png

Let’s talk through the sessions above.

  1. A connection is opened to the geekintheweeds.com /wmcs/certification/server.asmx AIP endpoint with an unauthenticated HTTP POST and a SOAP action of GetServerInfo.  The endpoint responds as we’ve observed previously with information about the AIP instance including features and endpoints for the various pipelines.
  2. A connection is opened to the geekintheweeds.com /wmcs/oauth2/servicediscovery/servicediscovery.asmx AIP endpoint with an unauthenticated HTTP POST and a SOAP action of ServiceDiscoveryForUser.  We know from the bootstrapping process I covered in my last post, that this action requires authentication, so we see the service return a 401.
  3. A connection is opened to the geekintheweeds.com /wmcs/oauth2/certification/server.asmx AIP endpoint with an unauthenticated HTTP POST and SOAP action of GetLicensorCertificate.  The SLC and its chain is returned to the machine in the response.
  4. A connection is opened to the geekintheweeds.com /wmcs/oauth2/certification/certification.asmx AIP endpoint with an unauthenticated HTTP POST and SOAP action of Certify.  Again, we remember from my last post that this requires authentication, so the service again responds with a 401.

What we learned from the above is the bearer access token the client obtained earlier isn’t attended for the geekintheweeds.com AIP endpoint because we never see it used.  So how will the machine complete its bootstrap process?  Well let’s see.

  1. A connection is opened to the journeyofthegeek.com /wmcs/oauth2/servicediscovery/servicediscovery.asmx AIP endpoint with an unauthenticated HTTP POST and SOAP action of ServiceDiscoveryForUser.  The service returns a 401 after which the client makes the same connection and HTTP POST again, but this time including its bearer access token it retrieved earlier.  The service provides a response with the relevant pipelines for the journeyofthegeek.com AIP instance.
  2. A connection is opened to the journeyofthegeek.com /wmcs/oauth2/certification/server.asmx AIP endpoint with an authenticated (bearer access token) HTTP POST and SOAP action of GetLicensorCertificate.  The service returns the SLC and its chain.
  3. A connection is opened to the journeyofthegeek.com /wmcs/oauth2/certification/certification.asmx AIP endpoint with an authenticated (bearer access token) HTTP POST and SOAP action of Certify.  The service returns a RAC for the ash.williams@geekintheweeds.com along with relevant SLC and chain.  Wait what?  A RAC from the journeyofthegeek.com AIP instance for a user in geekintheweeds.com?   Well folks this is supported through RMS’s support for federation.  Since all Azure AD’s in a given offering (commercial, gov, etc) come pre-federated, this use case is supported.
  4. A connection is opened to the journeyofthegeek.com /wmcs/licensing/server.asmx AIP endpoint with an uauthenticated HTTP POST and SOAP action of GetServerInfo.  We’ve covered this enough to know what’s returned.
  5. A connection is opened to the journeyofthegeek.com /wmcs/licensing/publish.asmx AIP endpoint with an authenticated (bearer access token) HTTP POST and SOAP action of GetClientLicensorandUserCertificates.  The server returns the CLC and EUL to the user.

After this our protected document opens in Microsoft Word.

7aip18.png

Pretty neat right? Smart move by Microsoft to take advantage and build upon of the federated capabilities built into AD RMS. This is another example showing just how far ahead of their game the product team for AD RMS was. Heck, there are SaaS vendors that still don’t support SAML, let alone on-premises products from 10 years ago.

In the next few posts (can you tell I find RMS fascinating yet?) of this series I’ll explore how Microsoft has integrated AIP into OneDrive, SharePoint Online, and Exchange Online.

Have a great week!

The Evolution of AD RMS to Azure Information Protection – Part 6 – Deep Dive into Client Bootstrapping

The Evolution of AD RMS to Azure Information Protection – Part 6 – Deep Dive into Client Bootstrapping

Today I’m back with more Azure Information Protection (AIP) goodness.  Over the past five posts I’ve covered the use cases, concepts and migration paths.  Today I’m going to get really nerdy and take a look behind the curtains at how the MSIPC client shipped with Office 2016 interacts with AIP .  I’ll be examining the MSIPC client log and reviewing procmon and Fiddler captures.  If the thought of examining log files and SOAP calls excites you, this is a post for you.  Make sure to take a read through my previous posts to ensure you understand my lab infrastructure and configuration as well as key AIP concepts.

Baselining the Client

Like any good engineer, I wanted to baseline my machine to ensure the MSIPC client was functioning correctly.  Recall that my clients are migrating from an on-premises AD RMS implementation to AIP.  I haven’t completed my removal of AD RMS so the service connection point for on-premises AD RMS is still there and the migration scripts Microsoft provides are still in use.  Let’s take a look at the registry entries that are set via the Migrate-Client and Migrate-User script.  In my last post I covered the purpose of the two scripts.  For the purposes of this post, I’m going to keep it brief and only cover registry entries applicable to the MSIPC client shipped with Office 2016.

  1. Migrate-Client
    • Condition: Runs each computer startup only if it detects it has not run before or the version variable in the script has been changed.
    • Registry Entries Modified:
      • Deletes HKLM\Software\Microsoft\MSIPC\ServiceLocation keys
      • Deletes HKLM\Software\Wow6432Node\Microsoft\MSIPC\ServiceLocation key
      • Deletes HKLM\Software\Microsoft\MSIPC\ServiceLocation\LicensingRedirection key
      • Deletes HKLM\Software\Wow6432Node\Microsoft\MSIPC\ServiceLocation\LicensingRedirection key
      • Add Default value to HKLM\Software\Microsoft\MSIPC\ServiceLocation\EnterpriseCertification key with data value pointing to AIP endpoint for tenant
      • Add Default value to HKLM\Software\Wow6432Node\Microsoft\MSIPC\ServiceLocation\EnterpriseCertification key with data value pointing to AIP endpoint for tenant
      • Add a value for the FQDN and single label URLs to on-premises AD RMS licensing pipeline to HKLM\Software\Microsoft\MSIPC\ServiceLocation\LicensingRedirection key with data values pointing to AIP endpoints for tenant
      • Add a value for the FQDN and single label URLs to on-premises AD RMS licensing pipeline to HKLM\Software\Wow6432NodeMicrosoft\MSIPC\ServiceLocation\LicensingRedirection key with data values pointing to AIP endpoints for tenant
  2. Migrate-User
    • Condition: Runs each user logon only if it detects it has not run before or the version variable in the script has been changed.
    • Registry Entries Modified:
      • Deletes HKCU\Software\Microsoft\Office\16.0\Common\DRM key
      • Deletes HKCU\Software\Classes\Local Settings\Software\Microsoft\MSIPC key
      • Deletes HKCU\Software\Classes\Microsoft.IPViewerChildMenu\shell key
      • Add DefaultServerUrl value to HKCU\Software\Microsoft\Office\16.0\Common\DRM key and set its data value to the AIP endpoint for the tenant
    • Files Modified:
      • Deletes the contents of the %localappdata%\Microsoft\MSIPC folder

A quick review of my client settings validates that all the necessary registry entries are in place and I have no issues consuming and created protected content.

Resetting the Client

If you have administered AD RMS in the past, you will be very familiar with how to re-bootstrap an RMS client.  Microsoft has made that entire process easier by incorporating a “reset” function into the AIP client.  The function can be accessed in Microsoft Office by hitting the drop down arrow for the AIP icon on the toolbar and selecting the Help and Feedback option.

6AIP1.png

After clicking the Help and Feedback option, a new window pops up where you can select the Reset Settings option to which performs a series of changes to the registry, deletions of RMS licenses, and AIP metadata.  Lastly, I log out of the machine.

6AIP2.png

 

Bootstrapping the Client with Azure Information Protection

After logging back in I start up Fiddler, open Microsoft Word, and attempt to open a file that was protected with my AD RMS cluster. The file opens successfully.

One thing to note is if you’re using Windows 10 and Microsoft Edge like I was, you’ll need to take the extra steps outlined here to successfully capture due to the AppContainer Isolation feature added back in Windows 8. If you do not take those extra steps, you’ll get really odd behavior. Microsoft Edge will fail any calls to intranet endpoints (such as AD FS in my case) by saying it can’t contact the proxy. Trying with Internet Explorer will simply cause Fiddler to fail to make the calls and to throw a DNS error. Suffice to say, I spent about 20 minutes troubleshooting the issue before I remembered Fiddler’s dialog box that pops up every new install about AppContainer and Microsoft Edge.

The first thing we’re going to look at is the MSIPC log files which keep track of the client activity. I have to give an applause to whichever engineer over at Microsoft thought it would be helpful to include such a detailed log. If you’ve administered on-premises AD RMS in the past on previous versions of Microsoft Office, you’ll know the joys (pain?) of client side tracing with DebugView.

When we pop open the log we get some great detail as to the client behavior. We can see the client read a number of registry entries. The first thing we see is the client discover that is not initialized so it calls an API to bootstrap the user. Notice in the below that it has identified my user and it’s mentioning OAuth as a method for authentication to the endpoint.

6AIP3.png

Following this we have a few more registry queries to discover the version of the operating system. We then have our first HTTP session opened by the client. I’m pretty sure this session is the initial user authentication to Azure AD in order to obtain a bearer access token for the user to call further APIs

6AIP4.png

Bouncing over to Fiddler we can check out the authentication process. We can see the machine reach out to Azure AD (login.windows.net), perform home realm discovery which Azure AD determines that geekintheweeds.com is configured for federated authentication. The client makes the connection to the AD FS server where the user is seamlessly authenticated via Kerberos. The windowstransport endpoint is called which supports the WS-Trust 1.3 active profile.  In an WS-Trust active flow, the client initiates the request (hence it’s active) vs the passive flow where the service provider initiates the flow.  This is how Office applications support modern (aka federated) authentication.

6AIP5

After the assertion is obtained, it’s posted to the /common/oauth2/token endpoint at login.windows.net.  The assertion is posted within a request for an access token, refresh token, and id token request using the saml1_1-bearer token grant type for the Azure RMS endpoint.

6AIP6.png

The machine is returned an access token, refresh token, and id token.  We can see the token returned is a bearer token allowing client to impersonate my user moving forward.

6AIP7.png

Dumping the access token into the Fiddler TextWizard and decoding the Base64 gives us the details of the token.  Within the token we can see an arm (authenticated method reference) of wia indicating the user authenticated using Windows authentication.  A variety of information about the user is included in the token including UPN, first name, and last name.

6AIP8.png

I’m fairly certain the tokens are cached to a flat file based upon some of the data I did via procmon while the bootstrap process initiated.  You can see the calls to create the file and write to it below.

6AIP9

After the tokens are obtained and cached we see from the log file that the MSIPC client then discovers it doesn’t have machine certificates.  It goes through the process of creating the machine certificates.

6AIP10.png

We now see the MISPC client attempts to query for the SRV record Microsoft introduced with Office 2016 to help with migrations from AD RMS.  The client then attempts discovery of service by querying the RMS-specific registry keys in the HKLM hive and comes across the information we hardcoded into the machine via the migration scripts.  It uses this information to make a request to the non-authenticated endpoint of https://<tenant_specific>/_wmcs/certification/server.asmx.

6AIP11

Bouncing back to Fiddler and continuing the conversation we can see a few different connections are created.  We see one to api.informationprotection.azure.com, another to mobile.pipe.aria.microsoft.com, and yet another to the AIP endpoint for my tenant.

6AIP12.png

I expected the conversation between api.informationprotection.azure.com and the AIP endpoint for my tenant.  The connection to mobile.pipe.aria.microsoft.com interested me.  I’m not sure if it was randomly captured or if it was part of the consumption of protected content.  I found a few Reddit posts where people were theorizing it has something to do with how Microsoft consumes telemetry from Microsoft Office.  As you could probably guess, this piqued my interest to know what exactly Microsoft was collecting.

We can see from the Fiddler captures that an application on the client machine is posting data to https://mobile.pipe.aria.microsoft.com/Collector/3.0/.  Examination of the request header shows the user agent as AriaSDK Client and the sdk-version of ACT-Windows Desktop.  This looks to be the method in which the telemetry agent for Office collects its information.

6AIP13.png

If we decode the data within Fiddler and dump both sets of data to Notepad we get some insight into what’s being pulled. Most of the data is pretty generic in that there is information about the version of Word I’m using, the operating system version, information that my machine is a virtual machine, and some activity IDs which must relate to something MS holds on their end. The only data point I found interesting was that my tenant ID is included in it. Given tenant id isn’t exactly a secret, it’s still interesting it’s being collected. It must be fascinating to see this telemetry at scale. Interesting stuff either way.

6AIP14.png

Continuing the conversation, let’s examine the chatter with my tenant’s AIP endpoint since the discovery was requested by the MSIPC client.  We see a SOAP request of GetServerInfo posted to https://<tenant_specific>/_wmcs/certification/server.asmx.  The response we receive from the endpoint has all the information our RMS client will need to process the request.  My deep dive into AD RMS was before I got my feet with Fiddler so I’ve never examined the conversations with the SOAP endpoints within AD RMS.  Future blog post maybe?  Either way, I’ve highlighted the interesting informational points below.  We can see that the service is identifying itself as RMS Online, has a set of features that cater to modern authentication, runs in Cryptomode 2, and supports a variety of authentication methods.  I’m unfamiliar with the authentication types beyond X509 and OAuth 2.  Maybe carry overs from on-prem?  Something to explore in the future.  The data boxed in red are all the key endpoints the RMS client needs to know to interact with the service moving forward.  Take note the request at this endpoint doesn’t require any authentication.  That comes in later requests.

6AIP15.png

After the response is received the MSIPC writes a whole bunch of registry entries to the HKCU hive for the user to cache all the AIP endpoint information it discovered.  It then performs a service discovery against the authenticated endpoint using its bearer token it cached to the tokencache file.

6AIP16.png

Once the information is written to the registry, the client initiates a method called GetCertAndLicURLsWithNewSD.  It uses the information it discovered previously to query the protected endpoint https://<tenant_specific>/_wmcs/oauth2/servicediscovery/servicediscovery.asmx.  Initially it receives a 401 unauthorized back with instructions to authenticate uses a bearer token.

6AIP17.png

The client tries again this time providing the bearer token it obtained earlier and placed in the tokencache file.  The SOAP action of ServiceDiscoveryForUser is performed and the client requests the specific endpoints for certification, licensing, and the new tracking portal feature of AIP.

6AIP18.png

The SOAP response contains the relevant service endpoints and user for which the query applied to.

6AIP19.png

The MSIPC client then makes a call to /_wmcs/oauth2/certification/server.asmx with a SOAP request of GetLicensorCertificate.  I won’t break that one down response but it returns the SLC certificate chain in XrML format.  For my tenant this included both the new SLC I generated when I migrated to AIP as well as the SLC from my on-premises AD RMS cluster that I uploaded.

6AIP20.png

The MISPC log now shows a method called GetNewRACandCLC being called which is used to obtain a RAC and CLC. This is done by making a call to the certification pipeline.

6AIP21.png

The call to /_wmcs/oauth2/certification/certification.asmx does exactly as you would expect and calls the SOAP request of Certify. This included my user’s RAC, and both SLCs and certificates in that chain. The one interesting piece in the response was a Quota tag as seen below. I received back five certificates, so maybe there is a maximum that can be returned? If you have more than 4 on-premises AD RMS clusters you’re consolidating to AIP, you might be in trouble. 🙂

6AIP22.png

The MISPC log captures the successful certification and logs information about the RAC.

6AIP23.png

Next up the client attempts to obtain a CLC by calling continuing with the GetNewRACandCLC method. It first calls the /_wmcs/licensing/server.asmx pipeline and makes a GetServerInfo SOAP request which returns the same information we saw in the last request to server.asmx. This request isn’t authenticated and the information returned is written to the HKCU hive for the user.

6AIP24.png

The service successfully returns the users CLC.  The last step in the process is the MSIPC service requests the RMS templates associated with the user.  You can see the template that is associated custom AIP classification label I created.

6AIP25.png

Last but not least, the certificates are written to the %LOCALAPPDATA%\Microsoft\MSIPC directory.

6AIP26.png

Conclusion

Very cool stuff right? I find it interesting in that the MSIPC client performs pretty much the same way it performs with on-premises exempting some of the additional capabilities introduced such as the search for the SRV DNS records and the ability to leverage modern authentication via the bearer token. The improved log is a welcome addition and again, stellar job to whatever engineer at Microsoft thought it would be helpful to include all the detail that is included in that log.

If you’ve used AD RMS or plan to use AIP and haven’t peeked behind the curtains I highly recommend it. Seeing how all the pieces fit together and how a relatively simple web service and a creative use of certificates can provide such a robust and powerful security capability will make your appreciate the service AD RMS tried to be and how far ahead of its time it was.

I know I didn’t cover the calls to the AIP-classification specific web calls, but I’ll explore that in my next entry.  Hopefully you enjoyed nerding out on this post as much as I did. Have a great week and see you next post!