We currently have 18 roles and seems to be taking a while to redirect back to PSU. When testing, it take about 20 - 30 seconds to redirect back, but other team members have reporting taking longer. Not sure if the roles would play into that, but giving you an idea.
I’d recommend attempting to cache the extended claims. It’s probably so slow because it needs to make 18x web requests and you could probably reduce that to 1 by cache.
New-PSURole -Name "Administrator" -Description "Administrators can manage settings of UA, create and edit any entity within UA and view all the entities within UA." -Policy {
param(
$User
)
if ($User.Claims.type -eq '_claim_names') {
# Check cache for claims before executing web request
$CacheKey = $User.Identity.Name + "Claims"
$GroupObjectId = Get-PSUCache -Key $CacheKey
if ($$GroupObjectId -ne $null)
{
$GroupObjectId -eq '<objectid>'
return
}
Try {
$AppSettings = Get-Content -Path "$env:UAPath\appsettings.json" |ConvertFrom-Json
$ClientId = $AppSettings.Authentication.OIDC.ClientID
$ClientSecret = $AppSettings.Authentication.OIDC.ClientSecret
$TenantId = ($User.Claims |Where-Object type -eq 'http://schemas.microsoft.com/identity/claims/tenantid').value
$UserId = ($User.Claims |Where-Object type -eq 'http://schemas.microsoft.com/identity/claims/objectidentifier').value
$Params = @{
Uri = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
Body = @{
'client_id' = $ClientId
'client_secret' = $ClientSecret
'scope' = 'https://graph.microsoft.com/.default'
'grant_type' = 'client_credentials'
}
Method = 'Post'
ContentType = 'application/x-www-form-urlencoded'
ErrorAction = 'Stop'
}
$Token = Invoke-RestMethod @Params |Select-Object -ExpandProperty access_token
$Params = @{
Uri = "https://graph.microsoft.com/v1.0/$TenantId/users/$UserId/getMemberObjects"
Headers = @{
Authorization = "Bearer $Token"
}
Method = 'Post'
ContentType = 'application/json'
Body = (@{
securityEnabledOnly = $false
} |ConvertTo-Json)
}
$GroupObjectId = (Invoke-RestMethod @Params).value
# Expire shortly afterwards so that on the next login we grab their claims again in case they change
Set-PSUCache -Key $CacheKey -Value $GroupObjectId -AbsoluteExpirationFromNow ([TimeSpan]::FromSeconds(30))
$GroupObjectId -eq '<objectid>'
}
Catch {
throw $_
}
}
else {
$User.HasClaim('groups', '<objectid>')
}
}
I’ve made a change to how this will work in 2.8.3. Rather than running the role scripts concurrently (which is what is happening now), they will run in parallel. This should really help the situation even without caching.
Thanks for the suggestion! However, if a user doesn’t get the overage claim (my user for example) it should just go to the else statements to get the group object id and shouldn’t need to get any cache correct?
Ah, interesting. Do you have a test box you can test a nightly build on? I can add some additional profiling\logging to help narrow down what’s happening as well as include the concurrent evaluation.
Running a nightly build of 2.8 now. I added some more profiling and what I see is the Microsoft Secret Store module is extremely slow. Most of the time executing role evaluations is due to Secret Store access. I’m going to have to update our documentation and open an issue on the Secret Store repo to see if we can figure out what’s going on here. It adds almost a 300ms delay per access to the store. It seems to get worse with more frequent access.
I did make some changes to some threading\synchronization stuff we were doing to guard against multi-access to the secret cmdlets so it should be slightly faster but any use of this module is going to cause performance issues.
I added a bunch of secrets to my environment and you can see that invoking the actual policy takes under 50ms, looking up secrets takes seconds.
Gotcha. I’ll be able to test on Friday. But we do have about 10 secrets. I could try and switch back to using Import-Clixml instead of the secrets module as well.
Couldn’t sleep. Reduced login speed from 2000ms to 80ms in my environment by changing how policies are processed to avoid creating multiple runspaces and importing secrets only during environment startup and not during policy processing.
I’ve downloaded the latest nightly build on v2.8.3 (1861748841) and simulated what we have in production (minus all of the scheduled jobs since our dev is not licensed). Just to give you an idea of our setup:
28 scheduled jobs
~500 jobs run a day
10 dashboards
12 secrets (Stored in Azure KeyVault)
1 secret (Stored locally that registers the keyvault)
18 total roles
Here are the results from logging in with our current policy scripts/overage claim script. If the latest nightly on 2.8.3 included how you processed policies, the login time was insanely fast.
When we tried to use KeyVault previously, the login time would be ~1 min or 2. Please let me know if there is anything else you would like me to test out.