0
# System-Assigned Identity Access
1
2
System-assigned managed identities are automatically created and managed by Azure services. Unlike user-assigned identities, system-assigned identities have a lifecycle tied to the Azure resource that creates them and cannot be shared across multiple resources. This capability provides read-only access to system-assigned identity information.
3
4
## Capabilities
5
6
### Retrieve System-Assigned Identity
7
8
Retrieves the system-assigned managed identity for a specific Azure resource by its scope (resource ID). This operation is read-only as system-assigned identities are managed by the Azure service itself.
9
10
```python { .api }
11
def get_by_scope(
12
scope: str,
13
**kwargs
14
) -> SystemAssignedIdentity:
15
"""
16
Get the system-assigned identity for a resource.
17
18
Parameters:
19
- scope (str): The resource scope (full Azure resource ID)
20
- **kwargs: Additional request options
21
22
Returns:
23
SystemAssignedIdentity: The system-assigned identity resource
24
25
Raises:
26
ResourceNotFoundError: If resource has no system-assigned identity
27
HttpResponseError: For other API errors
28
"""
29
```
30
31
**Usage Examples:**
32
33
```python
34
from azure.mgmt.msi import ManagedServiceIdentityClient
35
from azure.identity import DefaultAzureCredential
36
from azure.core.exceptions import ResourceNotFoundError
37
38
client = ManagedServiceIdentityClient(
39
credential=DefaultAzureCredential(),
40
subscription_id="your-subscription-id"
41
)
42
43
# Get system-assigned identity for a Virtual Machine
44
vm_scope = (
45
"subscriptions/12345678-1234-1234-1234-123456789012/"
46
"resourceGroups/myResourceGroup/"
47
"providers/Microsoft.Compute/virtualMachines/myVM"
48
)
49
50
try:
51
vm_identity = client.system_assigned_identities.get_by_scope(scope=vm_scope)
52
53
print(f"VM Identity found:")
54
print(f" Name: {vm_identity.name}")
55
print(f" Client ID: {vm_identity.client_id}")
56
print(f" Principal ID: {vm_identity.principal_id}")
57
print(f" Tenant ID: {vm_identity.tenant_id}")
58
print(f" Location: {vm_identity.location}")
59
60
except ResourceNotFoundError:
61
print("VM does not have a system-assigned identity enabled")
62
63
# Get system-assigned identity for an App Service
64
app_service_scope = (
65
"subscriptions/12345678-1234-1234-1234-123456789012/"
66
"resourceGroups/myResourceGroup/"
67
"providers/Microsoft.Web/sites/myAppService"
68
)
69
70
try:
71
app_identity = client.system_assigned_identities.get_by_scope(scope=app_service_scope)
72
73
print(f"App Service Identity:")
74
print(f" Client ID: {app_identity.client_id}")
75
print(f" Principal ID: {app_identity.principal_id}")
76
77
except ResourceNotFoundError:
78
print("App Service does not have a system-assigned identity")
79
80
# Get system-assigned identity for Azure Functions
81
function_scope = (
82
"subscriptions/12345678-1234-1234-1234-123456789012/"
83
"resourceGroups/myResourceGroup/"
84
"providers/Microsoft.Web/sites/myFunctionApp"
85
)
86
87
function_identity = client.system_assigned_identities.get_by_scope(scope=function_scope)
88
```
89
90
## Advanced Usage Patterns
91
92
### Bulk System Identity Discovery
93
94
```python
95
def discover_system_identities(resource_scopes: list):
96
"""
97
Discover system-assigned identities across multiple resources.
98
99
Args:
100
resource_scopes: List of Azure resource IDs to check
101
102
Returns:
103
dict: Mapping of resource names to identity information
104
"""
105
identities = {}
106
107
for scope in resource_scopes:
108
# Extract resource name from scope for easier identification
109
resource_name = scope.split('/')[-1]
110
111
try:
112
identity = client.system_assigned_identities.get_by_scope(scope=scope)
113
114
identities[resource_name] = {
115
"has_identity": True,
116
"client_id": identity.client_id,
117
"principal_id": identity.principal_id,
118
"tenant_id": identity.tenant_id,
119
"location": identity.location,
120
"scope": scope
121
}
122
123
except ResourceNotFoundError:
124
identities[resource_name] = {
125
"has_identity": False,
126
"scope": scope
127
}
128
except Exception as e:
129
identities[resource_name] = {
130
"has_identity": False,
131
"error": str(e),
132
"scope": scope
133
}
134
135
return identities
136
137
# Example: Check multiple VMs for system-assigned identities
138
vm_scopes = [
139
"subscriptions/sub-id/resourceGroups/rg1/providers/Microsoft.Compute/virtualMachines/vm1",
140
"subscriptions/sub-id/resourceGroups/rg1/providers/Microsoft.Compute/virtualMachines/vm2",
141
"subscriptions/sub-id/resourceGroups/rg2/providers/Microsoft.Compute/virtualMachines/vm3"
142
]
143
144
identity_report = discover_system_identities(vm_scopes)
145
146
print("System Identity Discovery Report:")
147
for resource, info in identity_report.items():
148
if info["has_identity"]:
149
print(f"✓ {resource}: {info['client_id']}")
150
else:
151
print(f"✗ {resource}: No system identity")
152
```
153
154
### Identity Information Export
155
156
```python
157
def export_system_identity_info(scope: str, export_format: str = "dict"):
158
"""
159
Export system-assigned identity information in various formats.
160
161
Args:
162
scope: Azure resource scope
163
export_format: Output format ('dict', 'json', 'env')
164
165
Returns:
166
Formatted identity information
167
"""
168
try:
169
identity = client.system_assigned_identities.get_by_scope(scope=scope)
170
171
identity_info = {
172
"resource_id": identity.id,
173
"name": identity.name,
174
"type": identity.type,
175
"client_id": identity.client_id,
176
"principal_id": identity.principal_id,
177
"tenant_id": identity.tenant_id,
178
"location": identity.location
179
}
180
181
if export_format == "json":
182
import json
183
return json.dumps(identity_info, indent=2)
184
185
elif export_format == "env":
186
resource_name = scope.split('/')[-1].upper().replace('-', '_')
187
return f"""
188
# System-assigned identity for {scope.split('/')[-1]}
189
{resource_name}_CLIENT_ID={identity.client_id}
190
{resource_name}_PRINCIPAL_ID={identity.principal_id}
191
{resource_name}_TENANT_ID={identity.tenant_id}
192
""".strip()
193
194
else: # dict format
195
return identity_info
196
197
except ResourceNotFoundError:
198
return None
199
200
# Export VM identity as environment variables
201
vm_scope = "subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/myvm"
202
env_vars = export_system_identity_info(vm_scope, "env")
203
if env_vars:
204
print(env_vars)
205
```
206
207
### Resource Type-Specific Helpers
208
209
```python
210
def get_vm_system_identity(subscription_id: str, resource_group: str, vm_name: str):
211
"""Get system-assigned identity for a Virtual Machine."""
212
scope = f"subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Compute/virtualMachines/{vm_name}"
213
return client.system_assigned_identities.get_by_scope(scope=scope)
214
215
def get_app_service_system_identity(subscription_id: str, resource_group: str, app_name: str):
216
"""Get system-assigned identity for an App Service."""
217
scope = f"subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Web/sites/{app_name}"
218
return client.system_assigned_identities.get_by_scope(scope=scope)
219
220
def get_function_app_system_identity(subscription_id: str, resource_group: str, function_name: str):
221
"""Get system-assigned identity for Azure Functions."""
222
scope = f"subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Web/sites/{function_name}"
223
return client.system_assigned_identities.get_by_scope(scope=scope)
224
225
def get_storage_account_system_identity(subscription_id: str, resource_group: str, storage_name: str):
226
"""Get system-assigned identity for a Storage Account."""
227
scope = f"subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Storage/storageAccounts/{storage_name}"
228
return client.system_assigned_identities.get_by_scope(scope=scope)
229
230
# Usage examples
231
subscription_id = "12345678-1234-1234-1234-123456789012"
232
233
# Get VM identity
234
vm_identity = get_vm_system_identity(subscription_id, "myResourceGroup", "myVM")
235
print(f"VM Identity Client ID: {vm_identity.client_id}")
236
237
# Get App Service identity
238
app_identity = get_app_service_system_identity(subscription_id, "myResourceGroup", "myApp")
239
print(f"App Identity Principal ID: {app_identity.principal_id}")
240
```
241
242
### Integration with Azure RBAC
243
244
```python
245
def create_system_identity_rbac_assignment(
246
scope: str,
247
role_definition_id: str,
248
target_scope: str
249
):
250
"""
251
Helper to prepare RBAC assignment for system-assigned identity.
252
Note: This prepares the data - actual RBAC assignment requires azure-mgmt-authorization.
253
"""
254
try:
255
identity = client.system_assigned_identities.get_by_scope(scope=scope)
256
257
# Prepare RBAC assignment parameters
258
rbac_assignment = {
259
"principal_id": identity.principal_id,
260
"principal_type": "ServicePrincipal",
261
"role_definition_id": role_definition_id,
262
"scope": target_scope,
263
"description": f"System identity access for {scope.split('/')[-1]}"
264
}
265
266
return rbac_assignment
267
268
except ResourceNotFoundError:
269
raise ValueError(f"Resource at scope {scope} does not have system-assigned identity")
270
271
# Example: Prepare RBAC assignment for VM to access Key Vault
272
vm_scope = "subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/myvm"
273
key_vault_scope = "subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.KeyVault/vaults/myvault"
274
reader_role = "subscriptions/sub-id/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6"
275
276
rbac_params = create_system_identity_rbac_assignment(
277
scope=vm_scope,
278
role_definition_id=reader_role,
279
target_scope=key_vault_scope
280
)
281
282
print(f"RBAC assignment prepared for principal: {rbac_params['principal_id']}")
283
```
284
285
## Common Resource Scope Patterns
286
287
System-assigned identities are available for various Azure resource types. Here are common scope patterns:
288
289
### Virtual Machines
290
```
291
subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Compute/virtualMachines/{vm-name}
292
```
293
294
### App Services
295
```
296
subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Web/sites/{app-name}
297
```
298
299
### Azure Functions
300
```
301
subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Web/sites/{function-name}
302
```
303
304
### Storage Accounts
305
```
306
subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Storage/storageAccounts/{storage-name}
307
```
308
309
### Key Vault
310
```
311
subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.KeyVault/vaults/{vault-name}
312
```
313
314
### Container Instances
315
```
316
subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.ContainerInstance/containerGroups/{container-name}
317
```
318
319
## Types
320
321
```python { .api }
322
class SystemAssignedIdentity:
323
"""System-assigned managed identity resource (extends ProxyResource)."""
324
# Read-only properties (all properties are read-only for system-assigned identities)
325
id: str # Full Azure resource ID
326
name: str # Resource name (matches the parent resource)
327
type: str # Resource type (Microsoft.ManagedIdentity/systemAssignedIdentities)
328
system_data: SystemData # ARM metadata (creation/modification info)
329
location: str # Azure region (matches parent resource location)
330
tags: Dict[str, str] # Resource tags (matches parent resource tags)
331
tenant_id: str # Azure tenant ID where identity is created
332
principal_id: str # Service principal object ID in Azure AD
333
client_id: str # Application (client) ID for the identity
334
client_secret_url: str # ManagedServiceIdentity DataPlane URL for token requests
335
```
336
337
## Error Handling
338
339
```python
340
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError
341
342
def safe_get_system_identity(scope: str):
343
"""Safely retrieve system-assigned identity with error handling."""
344
try:
345
return client.system_assigned_identities.get_by_scope(scope=scope)
346
347
except ResourceNotFoundError:
348
print(f"No system-assigned identity found for resource: {scope}")
349
return None
350
351
except HttpResponseError as e:
352
if e.status_code == 403:
353
print(f"Access denied - insufficient permissions to read identity for: {scope}")
354
elif e.status_code == 404:
355
print(f"Resource not found: {scope}")
356
else:
357
print(f"HTTP error {e.status_code}: {e.message}")
358
return None
359
360
except Exception as e:
361
print(f"Unexpected error: {e}")
362
return None
363
```