Intro

Using service accounts is one way to manage environment beside Azure Service Principals. Having privileged account which password is not changed won’t pose a great threat (unless the password is 1234 😵) but it is attack vector.

Alright let’s assume that someone guessed password. If this account has e.g. Global Administrator role then you are immediately F🦆ed. Otherwise it’s not great but under control.

Such accounts MUST be secured using top-notch, cutting edge technology. With help comes Azure KeyVault 🔐 and Azure AD Privileged Identity Management 👮🏻‍♂️.

Prerequisites

Privilaged Service Account Management

PSAM1

On the flow chart above PSAM solution ends at the red line, behind it you implement your job that automation account was created for. In my example I’m checking Azure AD for Bitlocker Recovery Keys and then taking action depend on outcome of validation script.

Let’s break it down and dive in into step-by-step configuration.

Azure KeyVault

We can start with creating Azure KeyVault. It will store credentials for your Service Account. Go to Azure KeyVault and fill out creation form.

PSAM2

With KeyVault created you can then add entry for your service account.

PSAM3

PSAM4

Note: To implement KeyVault secrets rotation I’m inviting you to use your favorite search engine and use one of the available implementations online

Azure Automation

Next step is to create Azure Automation Account. Azure Automation allows you to create and run Runbooks that process provided code e.g. Powershell. Go to Azure Automation Account and fill out creation form.

PSAM5

For purposes of PSAM you will need to add 3 Powershell modules to your Azure Automation:

PSAM6

Key component of Azure Automation is AzureRunAsAccount

PSAM7

Adding this application to resources permissions you will be able to automate many aspects of Azure cloud. We need to be able to Read KeyVault secrets so lets do that. Go back to your KeyVault and proceed to Access Policies blade and click on Add Access Policy.

PSAM8

In next step select secrets permissions

PSAM9

Select your AzureRunAsAccount as principal

PSAM10

And do not forget to click Save!!

PSAM11

To get secret from KeyVault in Powershell runbook you just need to paste

$AzureRunAsConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'

Connect-AzAccount -CertificateThumbprint $AzureRunAsConnection.CertificateThumbprint -ApplicationId $AzureRunAsConnection.ApplicationId -Tenant $AzureRunAsConnection.TenantId -ServicePrincipal

$secret = Get-AzKeyVaultSecret -VaultName 'KV-PSAM' -Name 'sa-NameResambleItsJob'

$secret

#The same goes for connecting to AzureAD
#Connect-AzureAD -TenantID $AzureRunAsConnection.TenantId -ApplicationId  $AzureRunAsConnection.ApplicationId -CertificateThumbprint $AzureRunAsConnection.CertificateThumbprint 

And you should be able to see results like

PSAM12

Azure DevOps repository

Now that you’ve got automation to run your scripts, create repository for them 🧱. Go to Azure DevOps and create a new project if you don’t have one.

PSAM13

Initialize a new repo

PSAM14

Then create a new folder and file within

PSAM15

Go back to your Automation Account and procced to Source Control blade and click Add

PSAM16

PSAM17

Click authenticate to connect to DevOps

PSAM18

Fill out the rest of the form

PSAM19

Note: Remember to set Publish runbook to Yes. Otherwise you will have to publish after every sync manually.

PSAM20

This is how sync should look like

PSAM21

Azure AD Privileged Identity Management

Finally you can assign desired role to service account. Go to Privileged Identity Management | Azure AD roles and select a role.

Click Add assignments

PSAM22

Select your service account

PSAM23

Proceed with Assign

PSAM24

One last thing you will need from that blade is roleID. The fastest way is to copy it from address bar

PSAM25

Final

If you are reading this it means that you’ve gone through preparation steps of PSAM! 🥳 Now it’s time for the frosting of our cupcake 🧁.

To read secret and request role using PIM you need to run:

$AzureRunAsConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'

Connect-AzAccount -CertificateThumbprint $AzureRunAsConnection.CertificateThumbprint -ApplicationId $AzureRunAsConnection.ApplicationId -Tenant $AzureRunAsConnection.TenantId -ServicePrincipal

$secret = Get-AzKeyVaultSecret -VaultName 'KV-PSAM' -Name 'sa-NameResambleItsJob'

$Password = $secret.SecretValue
'Cooking service account credentials'
$saCredentials = New-Object System.Management.Automation.PSCredential -ArgumentList ('[email protected]', $Password)

'Disconnecting from Az'
Disconnect-AzAccount

Import-Module AzureADPreview

"Connecting to AzureAD"
Connect-AzureAD -Credential $saCredentials | out-null

'Creating PIM schedule'
$roles = Get-AzureADMSPrivilegedRoleDefinition -ProviderId aadRoles -ResourceId $AzureRunAsConnection.TenantId
$schedule = New-Object Microsoft.Open.MSGraph.Model.AzureADMSPrivilegedSchedule
$schedule.Type = "Once"
$schedule.StartDateTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
$schedule.endDateTime = (Get-Date).AddMinutes(30).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ")     

"Requesting permissions"
Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId 'aadRoles' -ResourceId $AzureRunAsConnection.TenantId -RoleDefinitionId '7698a772-787b-4ac8-901f-60d6b08affd2' -SubjectId '25fca288-42e8-4ef3-8546-4305d7ba197c' -Type 'UserAdd' -AssignmentState 'Active' -schedule $schedule -reason "Powershell test"

That’s nicely formatted output from Runbook

PSAM26

Summary

Having so heavily protected service account with those few tools gives you great advantage against attackers 👨‍💻. To make this solution better you can make Automation Account variables for roleID or configure PIM to send mail notification to desired distribution list with information that role has been assigned 📩

See you in next! 😉 🧠