Skip to content

Rotate Admin Accounts

Overview

This guide configures JIT credential rotation for dedicated AD admin accounts — accounts like jdoe-a that exist alongside a user’s standard account for privileged access.

At checkout, Britive rotates the password and delivers the new credential to the requesting user. At checkin, the password is rotated again without sharing the new value — leaving the account with an unknown password until the next checkout. This eliminates standing credential risk without deleting the account.

Two password generation modes are available:

  • Random — 12-character alphanumeric + symbol string (standard compliance)
  • Passphrase — pronounceable multi-word passphrase (easier to type in RDP sessions or on a phone)

Before You Begin

  • The Britive Access Broker is running (see Getting Started)
  • The broker gMSA has the following delegations on the managed accounts OU:
    • Create user objects
    • Reset Password
    • Write userAccountControl (enable/disable)
  • RSAT Active Directory module installed on the broker host

Checkout Routine — Random Password

Full script: Active Directory/permissions/rotate-a-account/rotate-a-account-checkout.ps1

At checkout, this script creates the -a account if it does not yet exist, generates a random password, enables the account, and returns the credentials to the user.

Environment variable: user (UPN of the requesting user)

Derive admin account name and generate password:

$Email    = $env:user
$Username = ($Email -split "@")[0] + "-a"

$chars    = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-+="
$password = -join ((1..12) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
$SecurePassword = ConvertTo-SecureString $password -AsPlainText -Force

Create or rotate the account:

$User = Get-ADUser -Filter { SamAccountName -eq $Username } -ErrorAction SilentlyContinue

if (-not $User) {
    New-ADUser -Name $Username -SamAccountName $Username -UserPrincipalName $Email `
               -AccountPassword $SecurePassword -Enabled $true
} else {
    Set-ADAccountPassword -Identity $Username -NewPassword $SecurePassword -Reset
    Enable-ADAccount -Identity $Username
}

Write-Output "username: $Username"
Write-Output "password: $password"

Checkout Routine — Passphrase Password

Full script: Active Directory/permissions/rotate-a-account/rotate-a-account-checkout-passphrase.ps1

Generates a memorable, pronounceable passphrase — useful when the credential must be typed manually (e.g., RDP without clipboard, mobile devices).

Generate pronounceable passphrase:

function New-PronounceableWord {
    param([int]$syllables = 2)
    $consonants = "bdfghjklmnprstvwz"
    $vowels     = "aeiou"
    $word = ""
    for ($s = 0; $s -lt $syllables; $s++) {
        $word += $consonants[(Get-Random -Maximum $consonants.Length)]
        $word += $vowels[(Get-Random -Maximum $vowels.Length)]
    }
    $word += $consonants[(Get-Random -Maximum $consonants.Length)]
    return $word
}

$password = ""
while ($password.Length -lt 18) {
    $word = New-PronounceableWord -syllables (Get-Random -Minimum 2 -Maximum 4)
    $password += $word.Substring(0,1).ToUpper() + $word.Substring(1)
}
$password += (Get-Random -Minimum 10 -Maximum 100).ToString()

Checkin Routine

Full script: Active Directory/permissions/rotate-a-account/rotate-a-account-checkin.ps1

At checkin, the password is rotated to a new random value that is not returned to the user — the account is left with an unknown password, eliminating standing access.

$Username = ($env:user -split "@")[0] + "-a"

$User = Get-ADUser -Filter { SamAccountName -eq $Username } -ErrorAction SilentlyContinue

if ($User) {
    $password = -join ((1..12) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
    $SecurePassword = ConvertTo-SecureString $password -AsPlainText -Force

    # Rotate password — do NOT output the new value
    Set-ADAccountPassword -Identity $Username -NewPassword $SecurePassword -Reset
    Write-Output "Account '$Username' password rotated on checkin. Credential is no longer valid."
}

Configure in Britive

Create a response template

Go to Resource Manager → Response Templates → New Template. Add fields that surface username and password from the checkout output.

Create a permission

Go to Resource Manager → Resource Type Permissions → New Permission. Set Language to PowerShell.

Paste the checkout routine (random or passphrase — choose one) into the Checkout field. Paste checkin.ps1 into the Checkin field.

Declare variables:

VariableSystem definedNotes
userYesInjected automatically

Under Response Templates, attach the template you created.

Create a profile

Go to Resource Manager → Profiles → New Profile. Set an expiration (e.g. 4h). Under Associations, select the resource label(s) covering your AD domain resources. Under Permissions, add the permission above.

Add a policy

Under Policies, assign members (users or tags) and configure approval conditions.

The checkin routine intentionally does not output the new password. This is by design — the -a account is left with an unknown credential between sessions. Do not modify the checkin routine to return the password.


Verify

Check out the profile

In the Britive console, check out the profile. The username and password should appear in the checkout response.

Test access

Log in to a domain resource using the -a account and the delivered password — access should work.

Check in

Check in (or allow the session to expire).

Confirm revocation

Attempt to log in with the previously delivered password — it should fail.

Get-ADUser -Identity "jdoe-a" -Properties Enabled, PasswordLastSet |
    Select-Object SamAccountName, Enabled, PasswordLastSet

Troubleshoot

SymptomCauseFix
Account not created on first checkoutgMSA missing Create user delegationDelegate CC;user on the accounts OU
Access denied on Set-ADAccountPasswordgMSA missing Reset Password rightDelegate CA;Reset Password;user on the accounts OU
Credentials not shown after checkoutshow_orig_creds = false and no response templateSet show_orig_creds = true or add a response template that exposes username and password
Old password still works after checkinCheckin routine did not runCheck broker logs — look for script execution errors
Last updated on