-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfind_workload_identity.ps1
executable file
·162 lines (151 loc) · 6.12 KB
/
find_workload_identity.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Find a Service Principal or Managed Identity
.DESCRIPTION
Workload Identity is the umbrella term for both Service Principal and Managed Identity. This script will find a Service Principal or Managed Identity by various means.
Find an identity by (object/principal) id, service principal name, application/client id, application name, user assigned identity resource id, etc
.EXAMPLE
./find_workload_identity.ps1 12345678-1234-1234-abcd-1234567890ab
.EXAMPLE
./find_workload_identity.ps1 my-service-principal-name
.EXAMPLE
./find_workload_identity.ps1 /subscriptions/12345678-1234-1234-abcd-1234567890ab/resourcegroups/my-resource-group/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-user-assigned-identity
.EXAMPLE
./find_workload_identity.ps1 "https://identity.azure.net/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx="
.EXAMPLE
./find_workload_identity.ps1 "https://VisualStudio/SPN12345678-1234-1234-abcd-1234567890ab"
.EXAMPLE
./find_workload_identity.ps1 "sc://myorg/myproj/mysc"
#>
#Requires -Version 7
param (
[parameter(Mandatory=$true,HelpMessage="Application/Client/Object/Principal id/Resource id/Name/Service Principal Name/Federated subject identifier")]
[ValidateNotNullOrEmpty()]
[string]
$IdOrName,
[parameter(Mandatory=$false)]
[switch]
$ServicePrincipalOnly=$false,
[parameter(Mandatory=$false,HelpMessage="Azure Active Directory tenant id")]
[guid]
$TenantId=($env:ARM_TENANT_ID ?? $env:AZURE_TENANT_ID)
)
Write-Debug $MyInvocation.line
. (Join-Path $PSScriptRoot functions.ps1)
# Login to Azure CLI
Write-Verbose "Logging into Azure..."
Login-Az -Tenant ([ref]$TenantId)
# Parse input
switch -regex ($IdOrName) {
# Match GUID
"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$" {
Write-Verbose "'$IdOrName' is a GUID"
Find-ServicePrincipalByGUID -Id $IdOrName | Set-Variable sp
if (!$sp) {
Find-ApplicationByGUID -Id $IdOrName | Set-Variable app
if ($app) {
Find-ServicePrincipalByGUID -Id $app.appId | Set-Variable sp
} else {
Write-Warning "Could not find Application or Service Principal objects with Application or Object id '$IdOrName'"
exit
}
}
break
}
# Match User-assigned Identity Resource id
"/subscriptions/(.)+/resourcegroups/(.)+/providers/Microsoft.ManagedIdentity/userAssignedIdentities/(.)+" {
Write-Verbose "'$IdOrName' is a User-assigned Identity Resource id"
Find-ManagedIdentityByResourceId -Id $IdOrName | Set-Variable mi
if ($mi) {
Find-ServicePrincipalByGUID -Id $mi.principalId | Set-Variable sp
} else {
Write-Warning "Could not find Managed Identity with Resource id '$IdOrName'"
exit
}
break
}
# Match generic Resource id (System-assigned Identity)
"/subscriptions/(.)+/resourcegroups/(.)+/(.)+/(.)+" {
Write-Verbose "'$IdOrName' is a Resource id"
Find-ManagedIdentityByResourceId -Id $IdOrName | Set-Variable mi
if ($mi) {
Find-ServicePrincipalByGUID -Id $mi.principalId | Set-Variable sp
} else {
Write-Warning "Could not find System-assigned Identity with Resource id '$IdOrName'"
exit
}
break
}
# Match identity URL (servicePrincipalName)
"https://identity.azure.net/\w+" {
Write-Verbose "'$IdOrName' is a Service Principal Name"
Find-ServicePrincipalByName -Name $IdOrName | Set-Variable sp
if (!$sp) {
Write-Warning "Could not find Service Principal with Service Principal Name '$IdOrName'"
exit
}
break
}
# Match Azure Pipelines federation subject
"sc://[-\d\w]+/[-\d\w]+/[-_\d\w]+" {
Write-Verbose "'$IdOrName' is a Federation Subject"
Find-ApplicationsByFederation -StartsWith $IdOrName -Details -ExactMatch | Set-Variable apps
if (($apps | Measure-Object).Count -gt 1) {
Write-Warning "Found $($apps.Count) Applications with Federation Subject '$IdOrName', selecting oldest one"
}
$apps | Select-Object -First 1 | Set-Variable app
if ($app) {
Find-ServicePrincipalByGUID -Id $app.appId | Set-Variable sp
} else {
Write-Warning "Could not find Application with Federation Subject '$IdOrName'"
exit
}
break
}
# Match Name or URL
"^[\w\-\/\:\.]+" {
if (!$ServicePrincipalOnly) {
Find-ApplicationByName -Name $IdOrName | Set-Variable app
}
if ($app) {
Find-ServicePrincipalByGUID -Id $app.appId | Set-Variable sp
} else {
Find-ServicePrincipalByName -Name $IdOrName | Set-Variable sp
}
if (!$sp) {
Write-Warning "Could not find Service Principal with name '$IdOrName'"
exit
}
break
}
default {
Write-Output "$($PSStyle.Formatting.Error)'$IdOrName' is not a valid GUID, Name or Resource id, exiting$($PSStyle.Reset)" | Write-Warning
exit
}
}
## Retrieve app if it wasn't retrieved yet
if (!$ServicePrincipalOnly -and !$app -and $sp -and ($sp.servicePrincipalType -ieq "Application")) {
Find-ApplicationByGUID -Id $sp.appId | Set-Variable app
}
# Get Federated Credentials & owner(s)
if (!$ServicePrincipalOnly -and $sp) {
Get-FederatedCredentials -AppId $sp.appId -Type $sp.servicePrincipalType | Set-Variable fic
Get-ApplicationOwners -AppId $sp.appId | Set-Variable owners
}
if ($app) {
Write-Host "Found Application '$($app.displayName)' with appId '$($app.appId)'"
$app | Format-List
}
if ($sp) {
Write-Host "Found Service Principal '$($sp.displayName)' of type '$($sp.servicePrincipalType)' with appId '$($sp.appId)'"
$sp | Format-List
}
if ($fic) {
Write-Host "Federated Identity Credentials for appId '$($sp.appId)'"
$fic | Format-List
}
if ($owners) {
Write-Host "Owners of appId '$($sp.appId)'"
$owners | Format-List -Property displayName, userPrincipalName, mailNickname, mail, userType
}