Azure AD B2C: Custom policies – the structure

Hello again to the Azure AD B2C post series. I’m glad you’re still here!

Introduction

This posts content covers mainly the general structure of build-in
policies (and the custom ones, at the point of exporting) as seen in documentation and as in actual exported policies. It is making an introduction to what can be found in policies structure and will serve as a point of reference later in the series.

The documentation

First I need to admit the the docs got infinitely better recently. It’s really a comprehensive source of information at the moment.
The downside of this is it took me away a lot of ideas for blog posts which now wouldn’t make any sense as you can just get what you need from the documentation 🙂

Still, there are some things one could want to straighten out.

Let’s take a look at policy file types.
On one hand it seems there are three file types (Base, Extension, Relying Party) which together form an inheritance model in which Extension inherits from Base adding to or overriding it’s content and RP inherits from Extension (adding or overriding too).
On the other hand though you can find the information that this parent-child model of inheritance is not limited to these explicitly mentioned types but has no limit on number of levels.

Inheritance model
https://docs.microsoft.com/en-us/azure/active-directory-b2c/trustframeworkpolicy


I understand the reference to the BASE-EXT-RP pattern as a description of how the build-in policies work. There is some (more-less) constant part of policies – that is the BASE, then there is an intermediate EXT part where some shared but configurable content can be placed and then there is the RP policy which is actually defining the precise functionality of the policy and a specific visual branding. However, knowing how it is organized for build-in policies doesn’t have very much value and for the custom ones you can do it different way. The only thing you want to know is that while you make changes in the Azure Portal, the EXT and RP policies are being changed and the BASE remains the same.

What’s more, when you take a look at the file we exported in the first post of the series, you can quickly notice that it’s structure rather adds to the general confusion regarding structure and levels.

The exported policies file

First, there’s a single file. But let’s not be picky, this is the convenience of downloading a single file. Let’s take a look inside then.

According to the documentation the inheritance is made by referencing policies within the BasePolicy element. OK then, reverse engineering!

It starts quite well. Apparently there are five policies (TrustFrameworkPolicy elements) instead of three.

A quick investigation shows that there is only one policy without a BasePolicy element. That would be the “oldest” generation, the BASE policy, right? Well, not really or not entirely. It depends on how strictly do you want to understand the three-level concept described in documentation and found in different samples, like this one:
https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/tree/master/LocalAccounts

If you consider the example mentioned as a valid representation of BASE, EXT, RP policies then after looking in the exported file you’re faced with a choice of  either:
– accepting that the BASE (or any other, but it makes most sense for BASE) file is a set of several policies covering more then the samples (just look at the size of the file vs overall size of files from samples)
OR
– acknowledging that there are actually more layers out there

I think both have something to them but tend to shift towards the latter one myself. Let’s take another look at the exported file. When we gather policy names (PolicyId attribute) and references in BasePolicy elements we get something like this:

Right…
B2C_1_MyPolicy looks OK, it is the name we gave to our build-in policy and that should be “the leaf” of the model, a Relying Party policy.
Then, the EXT should follow. And it does, it’s just named “base-v1”. Not a really good pick of a name when you also should have BASE and it’s not this one, isn’t it? Still, it’s only a name.
But the confusion continues. The other three, if you follow my idea on how to understand it, should form a BASE together. Let’s assume for a while they do and peek in every one of these five to get a brief idea on their content.

[RP] B2C_1_Mypolicy

First, notice that the TenantId is your tenant. That is a kind of confirmation that this is what you configured, it’s specific for you and you own it.

The RP policy usually overrides/extends some settings but its most important task is done by RelyingParty element and it is choosing a UserJourney, the flow of user (UI-wise), data and the feature it represents (sign-in, password reset, etc.)

It also defines output claims (not all of them, but some, the ones you configured in policy Application Claims in the Portal) which will appear in the token passed to a redirect location when the user journey is completed.

[EXT] base-v1

The content of the extension policy can vary much from case to case but the most essential part from all the overrides it includes is pointing to proper AAD Applications, which represent AAD B2C by overriding part of AAD-Common TechnicalProfile. At least that’s the most important part in the exported one we’re looking at now. And why is it like that? Because the BASE remains unchanged for everyone (let’s not think how private previews work for a while), so the reference to applications has to be changed in the part you own.

[BASE] B2CTrustFrameworkV2

What you can quicly notice is the TenantId here is cpimcore.onmicrosoft.com. It indicates we moved to a territory we don’t own, at least in build in policies. From here on the most intriguing things happen. After this poing you can also find most of the dragons I mentioned in post No 1 😉

But what is most peculiar with this policy is it’s role – it seems it prevents policies other than basic (build-in) ones to inherit from it (and it’s predecessors). We’ll investigate it more while trying to import back the exported build-in policies as custom ones.

[BASE] B2CTrustFrameworkGlobalContent

This one is also in the cpimcore.onmicrosoft.com, but what is more interesting it’s the actual name being different then the one child specifies –  B2CTRUSTFRAMEWORKGLOBALCONTENT-PROD-AM3-001-000.

What these suffixes mean and how that works? We can intuitively guess that PROD indicates a type of environment but what about the other ones? I’m not 100% sure about the exact meaning of all of them but we ca have some light shed to it by looking into the source code of the policy page. Try this yourself, run your policy (a build-in one) and when the page opens look into its source. I got this:

So, we have the datacenter here, in my case AM3 would probably be Amsterdam, West Europe region. I’m curious about the Slice value. Is it somehow related to the service rollouts (take a look at a slide below, from the last Ignite)?

Preparing for the unexpected: Anatomy of an Azure outage – BRK3075

So, keeping in mind different name in the child policy and the parent one, we can see that not only the policies inherit from each other but there’s also some kind of routing going on between them. Part of it visible in policy configuration:

Last but not least, the policy content. This one is huge but rather boring 😉 It contains all content definitions (more on this later in the series) and text localizations for lots (nearly 40, as far as I remember) locales.

[BASE] B2CTrustFrameworkBaseV2

It follows the naming and routing pattern the above does so I won’t repeat myself and get to the point – this is the most interesting policy, the actual BASE which does stuff.

Here you can find general configuraiton of identity providers, technical profiles responsible for actions of gathering data from the user or external parties, reading and writing in AAD, session management, definitions of user journeys. In short – everything, the ultimate dragon lair – lots of treasures but grabbing them for own use may prove tricky (and painful).

This is the policy which holds all the features regarding policies in AAD B2C. If there is something new coming to policies – this particular policy will get updated. We will refer to it later in the series when talking about a strategy on how to keep our custom policies in touch with the latest features the service provides in build-in ones.

What’s next?

This post turned out to be longer than I expected so no luck with re-importing this time, but… The next one will be exactly about that. And it will also continue to make structure digressions supported with some experiments.

One thought on “Azure AD B2C: Custom policies – the structure”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.