Skip to content

Commit 99ccfd6

Browse files
Merge pull request KelvinTegelaar#1634 from kris6673/jit-admin-reason
Feat: Add reason for JIT admin and improve logging
2 parents d38fb1c + d5e060a commit 99ccfd6

File tree

4 files changed

+47
-27
lines changed

4 files changed

+47
-27
lines changed

Config/schemaDefinitions.json

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
[
2-
{
3-
"id": "cippUser",
4-
"description": "CIPP User Schema",
5-
"targetTypes": ["User"],
6-
"properties": [
7-
{ "name": "jitAdminEnabled", "type": "Boolean" },
8-
{ "name": "jitAdminExpiration", "type": "DateTime" },
9-
{ "name": "mailboxType", "type": "String" },
10-
{ "name": "archiveEnabled", "type": "Boolean" },
11-
{ "name": "autoExpandingArchiveEnabled", "type": "Boolean" },
12-
{ "name": "perUserMfaState", "type": "String" }
13-
],
14-
"status": "Available"
15-
}
2+
{
3+
"id": "cippUser",
4+
"description": "CIPP User Schema",
5+
"targetTypes": ["User"],
6+
"properties": [
7+
{ "name": "jitAdminEnabled", "type": "Boolean" },
8+
{ "name": "jitAdminExpiration", "type": "DateTime" },
9+
{ "name": "jitAdminReason", "type": "String" },
10+
{ "name": "mailboxType", "type": "String" },
11+
{ "name": "archiveEnabled", "type": "Boolean" },
12+
{ "name": "autoExpandingArchiveEnabled", "type": "Boolean" },
13+
{ "name": "perUserMfaState", "type": "String" }
14+
],
15+
"status": "Available"
16+
}
1617
]

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecJITAdmin.ps1

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ function Invoke-ExecJITAdmin {
66
Entrypoint
77
.ROLE
88
Identity.Role.ReadWrite
9+
10+
.DESCRIPTION
11+
Just-in-time admin management API endpoint. This function can list JIT admins, create users, add roles, remove roles, delete, or disable a user.
912
#>
1013
[CmdletBinding()]
1114
param($Request, $TriggerMetadata)
@@ -16,6 +19,7 @@ function Invoke-ExecJITAdmin {
1619
Write-LogMessage -Headers $User -API $APIName -message 'Accessed this API' -Sev 'Debug'
1720

1821
if ($Request.Query.Action -eq 'List') {
22+
# TODO: The list functionality should be moved to a separate function. ListJITAdmin or similar.
1923
$Schema = Get-CIPPSchemaExtensions | Where-Object { $_.id -match '_cippUser' } | Select-Object -First 1
2024
if ($Request.Query.TenantFilter -ne 'AllTenants') {
2125
# Single tenant logic
@@ -48,6 +52,7 @@ function Invoke-ExecJITAdmin {
4852
accountEnabled = $_.accountEnabled
4953
jitAdminEnabled = $_.($Schema.id).jitAdminEnabled
5054
jitAdminExpiration = $_.($Schema.id).jitAdminExpiration
55+
jitAdminReason = $_.($Schema.id).jitAdminReason
5156
memberOf = $MemberOf
5257
}
5358
}
@@ -115,6 +120,7 @@ function Invoke-ExecJITAdmin {
115120
accountEnabled = $UserObject.accountEnabled
116121
jitAdminEnabled = $UserObject.jitAdminEnabled
117122
jitAdminExpiration = $UserObject.jitAdminExpiration
123+
jitAdminReason = $UserObject.jitAdminReason
118124
memberOf = $UserObject.memberOf
119125
}
120126
)
@@ -130,29 +136,29 @@ function Invoke-ExecJITAdmin {
130136
if ($Request.Body.existingUser.value -match '^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$') {
131137
$Username = (New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$($Request.Body.existingUser.value)" -tenantid $TenantFilter).userPrincipalName
132138
}
133-
Write-LogMessage -Headers $User -API $APIName -message "Executing JIT Admin for $Username" -tenant $TenantFilter -Sev 'Info'
134139

135140
$Start = ([System.DateTimeOffset]::FromUnixTimeSeconds($Request.Body.StartDate)).DateTime.ToLocalTime()
136141
$Expiration = ([System.DateTimeOffset]::FromUnixTimeSeconds($Request.Body.EndDate)).DateTime.ToLocalTime()
137142
$Results = [System.Collections.Generic.List[string]]::new()
138143

139-
if ($Request.Body.useraction -eq 'Create') {
140-
Write-LogMessage -Headers $User -API $APIName -tenant $TenantFilter -message "Creating JIT Admin user $($Request.Body.Username)" -Sev 'Info'
141-
Write-Information "Creating JIT Admin user $($Request.Body.username)"
144+
if ($Request.Body.userAction -eq 'create') {
142145
$Domain = $Request.Body.Domain.value ? $Request.Body.Domain.value : $Request.Body.Domain
146+
$Username = "$($Request.Body.Username)@$($Domain)"
147+
Write-Information "Creating JIT Admin user: $($Request.Body.username)"
143148

144149
$JITAdmin = @{
145150
User = @{
146151
'FirstName' = $Request.Body.FirstName
147152
'LastName' = $Request.Body.LastName
148-
'UserPrincipalName' = "$($Request.Body.Username)@$($Domain)"
153+
'UserPrincipalName' = $Username
149154
}
150155
Expiration = $Expiration
156+
Reason = $Request.Body.reason
151157
Action = 'Create'
152158
TenantFilter = $TenantFilter
153159
}
154160
$CreateResult = Set-CIPPUserJITAdmin @JITAdmin
155-
$Username = "$($Request.Body.Username)@$($Domain)"
161+
Write-LogMessage -Headers $User -API $APIName -tenant $TenantFilter -message "Created JIT Admin user: $Username. Reason: $($Request.Body.reason). Roles: $($Request.Body.adminRoles.label -join ', ')" -Sev 'Info' -LogData $JITAdmin
156162
$Results.Add("Created User: $Username")
157163
if (!$Request.Body.UseTAP) {
158164
$Results.Add("Password: $($CreateResult.password)")
@@ -212,6 +218,7 @@ function Invoke-ExecJITAdmin {
212218
}
213219
Roles = $Request.Body.AdminRoles.value
214220
Action = 'AddRoles'
221+
Reason = $Request.Body.Reason
215222
Expiration = $Expiration
216223
}
217224
if ($Start -gt (Get-Date)) {
@@ -231,13 +238,15 @@ function Invoke-ExecJITAdmin {
231238
}
232239
}
233240
Add-CIPPScheduledTask -Task $TaskBody -hidden $false
234-
if ($Request.Body.useraction -ne 'Create') {
235-
Set-CIPPUserJITAdminProperties -TenantFilter $TenantFilter -UserId $Request.Body.existingUser.value -Expiration $Expiration
241+
if ($Request.Body.userAction -ne 'create') {
242+
Set-CIPPUserJITAdminProperties -TenantFilter $TenantFilter -UserId $Request.Body.existingUser.value -Expiration $Expiration -Reason $Request.Body.Reason
236243
}
237244
$Results.Add("Scheduling JIT Admin enable task for $Username")
245+
Write-LogMessage -Headers $User -API $APIName -message "Scheduling JIT Admin for existing user: $Username. Reason: $($Request.Body.reason). Roles: $($Request.Body.adminRoles.label -join ', ') " -tenant $TenantFilter -Sev 'Info'
238246
} else {
239247
$Results.Add("Executing JIT Admin enable task for $Username")
240248
Set-CIPPUserJITAdmin @Parameters
249+
Write-LogMessage -Headers $User -API $APIName -message "Executing JIT Admin for existing user: $Username. Reason: $($Request.Body.reason). Roles: $($Request.Body.adminRoles.label -join ', ') " -tenant $TenantFilter -Sev 'Info'
241250
}
242251

243252
$DisableTaskBody = [pscustomobject]@{
@@ -253,6 +262,7 @@ function Invoke-ExecJITAdmin {
253262
'UserPrincipalName' = $Username
254263
}
255264
Roles = $Request.Body.AdminRoles.value
265+
Reason = $Request.Body.Reason
256266
Action = $Request.Body.ExpireAction.value
257267
}
258268
PostExecution = @{

Modules/CIPPCore/Public/Set-CIPPUserJITAdmin.ps1

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ function Set-CIPPUserJITAdmin {
2121
.PARAMETER Expiration
2222
DateTime for expiration
2323
24+
.PARAMETER Reason
25+
Reason for JIT admin assignment. Defaults to 'No reason provided' as due to backwards compatibility this is not a mandatory field.
26+
2427
.EXAMPLE
25-
Set-CIPPUserJITAdmin -TenantFilter 'contoso.onmicrosoft.com' -Headers@{UserPrincipalName = 'jit@contoso.onmicrosoft.com'} -Roles @('62e90394-69f5-4237-9190-012177145e10') -Action 'AddRoles' -Expiration (Get-Date).AddDays(1)
28+
Set-CIPPUserJITAdmin -TenantFilter 'contoso.onmicrosoft.com' -Headers@{UserPrincipalName = 'jit@contoso.onmicrosoft.com'} -Roles @('62e90394-69f5-4237-9190-012177145e10') -Action 'AddRoles' -Expiration (Get-Date).AddDays(1) -Reason 'Emergency access'
2629
2730
#>
2831
[CmdletBinding(SupportsShouldProcess = $true)]
@@ -39,7 +42,9 @@ function Set-CIPPUserJITAdmin {
3942
[ValidateSet('Create', 'AddRoles', 'RemoveRoles', 'DeleteUser', 'DisableUser')]
4043
[string]$Action,
4144

42-
[datetime]$Expiration
45+
[datetime]$Expiration,
46+
47+
[string]$Reason = 'No reason provided'
4348
)
4449

4550
if ($PSCmdlet.ShouldProcess("User: $($User.UserPrincipalName)", "Action: $Action")) {
@@ -67,6 +72,7 @@ function Set-CIPPUserJITAdmin {
6772
$Schema.id = @{
6873
jitAdminEnabled = $false
6974
jitAdminExpiration = $Expiration.ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
75+
jitAdminReason = $Reason
7076
}
7177
}
7278
$Json = ConvertTo-Json -Depth 5 -InputObject $Body
@@ -109,7 +115,7 @@ function Set-CIPPUserJITAdmin {
109115
} catch {}
110116
}
111117

112-
Set-CIPPUserJITAdminProperties -TenantFilter $TenantFilter -UserId $UserObj.id -Enabled -Expiration $Expiration | Out-Null
118+
Set-CIPPUserJITAdminProperties -TenantFilter $TenantFilter -UserId $UserObj.id -Enabled -Expiration $Expiration -Reason $Reason | Out-Null
113119
return "Added admin roles to user $($UserObj.displayName) ($($UserObj.userPrincipalName))"
114120
}
115121
'RemoveRoles' {

Modules/CIPPCore/Public/Set-CIPPUserJITAdminProperties.ps1

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
function Set-CIPPUserJITAdminProperties {
22
[CmdletBinding()]
3-
Param(
3+
param(
44
[string]$TenantFilter,
55
[string]$UserId,
66
[switch]$Enabled,
77
$Expiration,
8-
[switch]$Clear
8+
[switch]$Clear,
9+
[string]$Reason
910
)
1011
try {
1112
$Schema = Get-CIPPSchemaExtensions | Where-Object { $_.id -match '_cippUser' } | Select-Object -First 1
@@ -14,13 +15,15 @@ function Set-CIPPUserJITAdminProperties {
1415
"$($Schema.id)" = @{
1516
jitAdminEnabled = $null
1617
jitAdminExpiration = $null
18+
jitAdminReason = $null
1719
}
1820
}
1921
} else {
2022
$Body = [PSCustomObject]@{
2123
"$($Schema.id)" = @{
2224
jitAdminEnabled = $Enabled.IsPresent
2325
jitAdminExpiration = $Expiration.ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
26+
jitAdminReason = $Reason
2427
}
2528
}
2629
}

0 commit comments

Comments
 (0)