Testing out conditional access for workload identities

At Ignite, Microsoft made the conditional access for workload identities feature available in public preview. Currently, this feature is quite limited in scope, but let’s see what it can do.

Let’s start by discussing the term “workload identity”. Previously Azure AD have had “App registration”, with the option of being scoped to a single tenant or multi tenants. Enterprise Applications points to an app registration; it is essentially an instance of and app registration. Service principals are essentially the same as Enterprise Applications.

This means that a service provider that wants to provide an Azure AD sign-in feature for their web portal, can add a single app registration, and handle only one set of keys/certificates, while other tenants that wants to sign into the app will simply get an Enterprise Application in their tenant (while the app registration remains only in the service provider tenant).

With the federated workload identity feature, Azure AD is getting another way for an Enterprise Application or Service Principal to authenticate – through, well you guessed it, federation (OpenID Connect). This means that things like GitHub Actions can authenticate to Azure AD without any secret management, which is super handy.

To make sure that all scenarios for “workloads” are convered in a single term, and to avoid confusion, Microsoft is now using “workload identities” as the term.

Let’s start by creation an app with a secret, like this:

Now, let’s add user.read.all and group.read.all for Graph and test it out:

The following PowerShell tests that we can get our access token properly, and query Graph, plus getting an access token to access an Azure KeyVault:

$clientid = "7ef864ad-4c95-444f-913e-c0a6e210608e"
$secret = "Bn.7Q~Gf4kBDFbV-tmebgAqik6-oNqs9O8Bm."
$tenantid = "fc576798-25a5-43d9-ad76-5e6930229575"

$token = $null 
$token = Invoke-RestMethod "https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body "client_id=$clientid&scope=https://graph.microsoft.com/.default&grant_type=client_credentials&client_secret=$secret" -Method POST
if($token.access_token) {
    $result = Invoke-RestMethod "https://graph.microsoft.com/v1.0/users" -Headers @{Authorization = "Bearer $($token.access_token)"}
    "Found $(($result.value | Measure-Object).Count) users"
} else {
    Write-Error "No access token found"
}

$keyvaulttoken = $null
$keyvaulttoken = Invoke-RestMethod "https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body "client_id=$clientid&scope=https://vault.azure.net/.default&grant_type=client_credentials&client_secret=$secret" -Method POST

Ok, now let’s try limiting access using conditional access.

No conditions set, and “Block” for action:

I now expect my script to fail, which it does with the following error:

Good, everything works as expected. Now we create “Home”, as a trusted location in Azure AD:

And then we configure the location condition for the CA rule to include any location, except trusted locations:

I now expect my script to start working again:

And indeed it does. Now this is where I want Microsoft to flip conditional access around, to block by default, or at least have the option to do it. Then, if we could scope on cloud apps too, we could say “Service principal X can access application Y”, only from certain locations, nothing else. If they could also add Azure service tags to conditional access policies, and Azure data centers are potential named locations, we could finally limit service principals properly. Baby steps… 🙂

2 thoughts on “Testing out conditional access for workload identities

  1. Please continue blogging.. I like all the screenshots and the basic explanation, awesome.. This will really help the community especially if there are new features in Azure.. Great Job

Leave a comment