0
# Access Control
1
2
Repository-level access control through scope maps and tokens, providing fine-grained permissions for registry access without using admin credentials. This system enables secure, principle-of-least-privilege access for applications, CI/CD systems, and users with customizable repository and action permissions.
3
4
## Capabilities
5
6
### Scope Map Management
7
8
Create and manage scope maps that define repository access permissions and allowed actions for token-based authentication.
9
10
```python { .api }
11
def begin_create(resource_group_name: str, registry_name: str, scope_map_name: str, scope_map_create_parameters: ScopeMap, **kwargs) -> LROPoller[ScopeMap]:
12
"""
13
Create a scope map for a container registry.
14
15
Parameters:
16
- resource_group_name: str - Name of the resource group
17
- registry_name: str - Name of the registry
18
- scope_map_name: str - Name of the scope map
19
- scope_map_create_parameters: ScopeMap - Scope map configuration
20
21
Returns:
22
LROPoller[ScopeMap] - Long-running operation poller for the scope map
23
"""
24
25
def begin_delete(resource_group_name: str, registry_name: str, scope_map_name: str, **kwargs) -> LROPoller[None]:
26
"""
27
Delete a scope map from a container registry.
28
29
Parameters:
30
- resource_group_name: str - Name of the resource group
31
- registry_name: str - Name of the registry
32
- scope_map_name: str - Name of the scope map to delete
33
34
Returns:
35
LROPoller[None] - Long-running operation poller
36
"""
37
38
def begin_update(resource_group_name: str, registry_name: str, scope_map_name: str, scope_map_update_parameters: ScopeMapUpdateParameters, **kwargs) -> LROPoller[ScopeMap]:
39
"""
40
Update a scope map for a container registry.
41
42
Parameters:
43
- resource_group_name: str - Name of the resource group
44
- registry_name: str - Name of the registry
45
- scope_map_name: str - Name of the scope map to update
46
- scope_map_update_parameters: ScopeMapUpdateParameters - Update parameters
47
48
Returns:
49
LROPoller[ScopeMap] - Long-running operation poller for the updated scope map
50
"""
51
52
def get(resource_group_name: str, registry_name: str, scope_map_name: str, **kwargs) -> ScopeMap:
53
"""
54
Get properties of a scope map.
55
56
Parameters:
57
- resource_group_name: str - Name of the resource group
58
- registry_name: str - Name of the registry
59
- scope_map_name: str - Name of the scope map
60
61
Returns:
62
ScopeMap - Scope map resource with complete configuration
63
"""
64
65
def list(resource_group_name: str, registry_name: str, **kwargs) -> ItemPaged[ScopeMap]:
66
"""
67
List all scope maps for a container registry.
68
69
Parameters:
70
- resource_group_name: str - Name of the resource group
71
- registry_name: str - Name of the registry
72
73
Returns:
74
ItemPaged[ScopeMap] - Paginated list of all scope maps for the registry
75
"""
76
```
77
78
### Token Management
79
80
Create and manage authentication tokens that use scope maps to define repository access permissions.
81
82
```python { .api }
83
def begin_create(resource_group_name: str, registry_name: str, token_name: str, token_create_parameters: Token, **kwargs) -> LROPoller[Token]:
84
"""
85
Create a token for a container registry.
86
87
Parameters:
88
- resource_group_name: str - Name of the resource group
89
- registry_name: str - Name of the registry
90
- token_name: str - Name of the token
91
- token_create_parameters: Token - Token configuration
92
93
Returns:
94
LROPoller[Token] - Long-running operation poller for the token
95
"""
96
97
def begin_delete(resource_group_name: str, registry_name: str, token_name: str, **kwargs) -> LROPoller[None]:
98
"""
99
Delete a token from a container registry.
100
101
Parameters:
102
- resource_group_name: str - Name of the resource group
103
- registry_name: str - Name of the registry
104
- token_name: str - Name of the token to delete
105
106
Returns:
107
LROPoller[None] - Long-running operation poller
108
"""
109
110
def begin_update(resource_group_name: str, registry_name: str, token_name: str, token_update_parameters: TokenUpdateParameters, **kwargs) -> LROPoller[Token]:
111
"""
112
Update a token for a container registry.
113
114
Parameters:
115
- resource_group_name: str - Name of the resource group
116
- registry_name: str - Name of the registry
117
- token_name: str - Name of the token to update
118
- token_update_parameters: TokenUpdateParameters - Update parameters
119
120
Returns:
121
LROPoller[Token] - Long-running operation poller for the updated token
122
"""
123
124
def get(resource_group_name: str, registry_name: str, token_name: str, **kwargs) -> Token:
125
"""
126
Get properties of a token.
127
128
Parameters:
129
- resource_group_name: str - Name of the resource group
130
- registry_name: str - Name of the registry
131
- token_name: str - Name of the token
132
133
Returns:
134
Token - Token resource with complete configuration
135
"""
136
137
def list(resource_group_name: str, registry_name: str, **kwargs) -> ItemPaged[Token]:
138
"""
139
List all tokens for a container registry.
140
141
Parameters:
142
- resource_group_name: str - Name of the resource group
143
- registry_name: str - Name of the registry
144
145
Returns:
146
ItemPaged[Token] - Paginated list of all tokens for the registry
147
"""
148
```
149
150
## Core Model Types
151
152
### ScopeMap
153
154
```python { .api }
155
class ScopeMap:
156
"""
157
An object that represents a scope map for a container registry.
158
159
Attributes:
160
- id: str - Resource ID
161
- name: str - Resource name
162
- type: str - Resource type
163
- description: str - Description of the scope map
164
- type_properties_type: str - Type of the scope map
165
- creation_date: datetime - Creation timestamp
166
- provisioning_state: ProvisioningState - Current provisioning state
167
- actions: List[str] - List of actions allowed by this scope map
168
"""
169
```
170
171
### ScopeMapUpdateParameters
172
173
```python { .api }
174
class ScopeMapUpdateParameters:
175
"""
176
Parameters for updating a scope map.
177
178
Attributes:
179
- description: str - Description of the scope map
180
- actions: List[str] - List of actions to update
181
"""
182
```
183
184
### Token
185
186
```python { .api }
187
class Token:
188
"""
189
An object that represents a token for a container registry.
190
191
Attributes:
192
- id: str - Resource ID
193
- name: str - Resource name
194
- type: str - Resource type
195
- creation_date: datetime - Creation timestamp
196
- provisioning_state: ProvisioningState - Current provisioning state
197
- scope_map_id: str - Resource ID of the scope map associated with the token
198
- credentials: TokenCredentialsProperties - Token credentials configuration
199
- status: TokenStatus - Token status (enabled/disabled)
200
"""
201
```
202
203
### TokenUpdateParameters
204
205
```python { .api }
206
class TokenUpdateParameters:
207
"""
208
Parameters for updating a token.
209
210
Attributes:
211
- scope_map_id: str - Resource ID of the scope map
212
- status: TokenStatus - Token status (enabled/disabled)
213
- credentials: TokenCredentialsProperties - Credentials configuration
214
"""
215
```
216
217
### TokenCredentialsProperties
218
219
```python { .api }
220
class TokenCredentialsProperties:
221
"""
222
Properties for token credentials.
223
224
Attributes:
225
- certificates: List[TokenCertificate] - List of certificates
226
- passwords: List[TokenPassword] - List of passwords
227
"""
228
```
229
230
### TokenPassword
231
232
```python { .api }
233
class TokenPassword:
234
"""
235
Password for a token.
236
237
Attributes:
238
- creation_time: datetime - Password creation time
239
- expiry: datetime - Password expiry time
240
- name: TokenPasswordName - Password name (password1/password2)
241
- value: str - Password value (only returned on creation)
242
"""
243
```
244
245
### TokenCertificate
246
247
```python { .api }
248
class TokenCertificate:
249
"""
250
Certificate for a token.
251
252
Attributes:
253
- name: TokenCertificateName - Certificate name (certificate1/certificate2)
254
- expiry: datetime - Certificate expiry time
255
- thumbprint: str - Certificate thumbprint
256
- encoded_pem_certificate: str - PEM-encoded certificate
257
"""
258
```
259
260
## Enums
261
262
### TokenStatus
263
264
```python { .api }
265
class TokenStatus(str, Enum):
266
"""Token status options."""
267
ENABLED = "enabled"
268
DISABLED = "disabled"
269
```
270
271
### TokenPasswordName
272
273
```python { .api }
274
class TokenPasswordName(str, Enum):
275
"""Token password names."""
276
PASSWORD1 = "password1"
277
PASSWORD2 = "password2"
278
```
279
280
### TokenCertificateName
281
282
```python { .api }
283
class TokenCertificateName(str, Enum):
284
"""Token certificate names."""
285
CERTIFICATE1 = "certificate1"
286
CERTIFICATE2 = "certificate2"
287
```
288
289
## Usage Examples
290
291
### Create Repository-Specific Access Control
292
293
```python
294
from azure.mgmt.containerregistry import ContainerRegistryManagementClient
295
from azure.mgmt.containerregistry.models import (
296
ScopeMap, Token, TokenStatus, TokenCredentialsProperties, TokenPassword
297
)
298
from azure.identity import DefaultAzureCredential
299
300
client = ContainerRegistryManagementClient(
301
DefaultAzureCredential(),
302
"subscription-id"
303
)
304
305
# Create scope map for frontend application access
306
frontend_scope_map = ScopeMap(
307
description="Access for frontend applications",
308
actions=[
309
"repositories/frontend/content/read",
310
"repositories/frontend/content/write",
311
"repositories/frontend/metadata/read"
312
]
313
)
314
315
frontend_scope = client.scope_maps.begin_create(
316
"my-resource-group",
317
"my-registry",
318
"frontend-access",
319
frontend_scope_map
320
).result()
321
322
# Create token for frontend applications
323
frontend_token = Token(
324
scope_map_id=frontend_scope.id,
325
status=TokenStatus.ENABLED,
326
credentials=TokenCredentialsProperties(
327
passwords=[
328
TokenPassword(name="password1"),
329
TokenPassword(name="password2")
330
]
331
)
332
)
333
334
frontend_auth_token = client.tokens.begin_create(
335
"my-resource-group",
336
"my-registry",
337
"frontend-token",
338
frontend_token
339
).result()
340
341
print(f"Created frontend token: {frontend_auth_token.name}")
342
print(f"Scope map: {frontend_auth_token.scope_map_id}")
343
```
344
345
### Create CI/CD Pipeline Access Control
346
347
```python
348
# Create scope map for CI/CD pipeline with broader permissions
349
cicd_scope_map = ScopeMap(
350
description="CI/CD pipeline access with push/pull permissions",
351
actions=[
352
"repositories/*/content/read", # Pull any repository
353
"repositories/*/content/write", # Push to any repository
354
"repositories/*/metadata/read", # Read metadata
355
"repositories/*/metadata/write" # Write metadata (for tags)
356
]
357
)
358
359
cicd_scope = client.scope_maps.begin_create(
360
"my-resource-group",
361
"my-registry",
362
"cicd-access",
363
cicd_scope_map
364
).result()
365
366
# Create token for CI/CD with long expiry
367
import datetime
368
from dateutil.relativedelta import relativedelta
369
370
expiry_date = datetime.datetime.utcnow() + relativedelta(years=1)
371
372
cicd_token = Token(
373
scope_map_id=cicd_scope.id,
374
status=TokenStatus.ENABLED,
375
credentials=TokenCredentialsProperties(
376
passwords=[
377
TokenPassword(
378
name="password1",
379
expiry=expiry_date
380
)
381
]
382
)
383
)
384
385
cicd_auth_token = client.tokens.begin_create(
386
"my-resource-group",
387
"my-registry",
388
"cicd-token",
389
cicd_token
390
).result()
391
392
print(f"Created CI/CD token: {cicd_auth_token.name}")
393
```
394
395
### Create Read-Only Access for Monitoring
396
397
```python
398
# Create scope map for monitoring/scanning tools (read-only)
399
monitoring_scope_map = ScopeMap(
400
description="Read-only access for monitoring and security scanning",
401
actions=[
402
"repositories/*/content/read",
403
"repositories/*/metadata/read"
404
]
405
)
406
407
monitoring_scope = client.scope_maps.begin_create(
408
"my-resource-group",
409
"my-registry",
410
"monitoring-access",
411
monitoring_scope_map
412
).result()
413
414
# Create token for monitoring tools
415
monitoring_token = Token(
416
scope_map_id=monitoring_scope.id,
417
status=TokenStatus.ENABLED,
418
credentials=TokenCredentialsProperties(
419
passwords=[TokenPassword(name="password1")]
420
)
421
)
422
423
monitoring_auth_token = client.tokens.begin_create(
424
"my-resource-group",
425
"my-registry",
426
"monitoring-token",
427
monitoring_token
428
).result()
429
430
print(f"Created monitoring token: {monitoring_auth_token.name}")
431
```
432
433
### Environment-Based Access Control
434
435
```python
436
# Create different scope maps for different environments
437
environments = {
438
"dev": [
439
"repositories/dev/*/content/read",
440
"repositories/dev/*/content/write",
441
"repositories/dev/*/metadata/read",
442
"repositories/dev/*/metadata/write"
443
],
444
"staging": [
445
"repositories/staging/*/content/read",
446
"repositories/staging/*/content/write",
447
"repositories/staging/*/metadata/read"
448
],
449
"prod": [
450
"repositories/prod/*/content/read" # Read-only for production
451
]
452
}
453
454
created_tokens = {}
455
456
for env_name, actions in environments.items():
457
# Create scope map
458
scope_map = ScopeMap(
459
description=f"Access control for {env_name} environment",
460
actions=actions
461
)
462
463
scope = client.scope_maps.begin_create(
464
"my-resource-group",
465
"my-registry",
466
f"{env_name}-access",
467
scope_map
468
).result()
469
470
# Create token
471
token = Token(
472
scope_map_id=scope.id,
473
status=TokenStatus.ENABLED,
474
credentials=TokenCredentialsProperties(
475
passwords=[TokenPassword(name="password1")]
476
)
477
)
478
479
auth_token = client.tokens.begin_create(
480
"my-resource-group",
481
"my-registry",
482
f"{env_name}-token",
483
token
484
).result()
485
486
created_tokens[env_name] = auth_token
487
print(f"Created {env_name} environment token")
488
489
print(f"Total environment tokens created: {len(created_tokens)}")
490
```
491
492
### Manage Token Lifecycle
493
494
```python
495
from azure.mgmt.containerregistry.models import TokenUpdateParameters
496
497
# List all tokens and check their status
498
tokens = client.tokens.list("my-resource-group", "my-registry")
499
500
print("Token Status Report:")
501
print("-" * 50)
502
for token in tokens:
503
print(f"Token: {token.name}")
504
print(f" Status: {token.status}")
505
print(f" Scope Map: {token.scope_map_id.split('/')[-1]}")
506
print(f" Created: {token.creation_date}")
507
print()
508
509
# Disable a token temporarily
510
update_params = TokenUpdateParameters(status=TokenStatus.DISABLED)
511
disabled_token = client.tokens.begin_update(
512
"my-resource-group",
513
"my-registry",
514
"frontend-token",
515
update_params
516
).result()
517
518
print(f"Disabled token: {disabled_token.name}")
519
520
# Re-enable the token later
521
enable_params = TokenUpdateParameters(status=TokenStatus.ENABLED)
522
enabled_token = client.tokens.begin_update(
523
"my-resource-group",
524
"my-registry",
525
"frontend-token",
526
enable_params
527
).result()
528
529
print(f"Re-enabled token: {enabled_token.name}")
530
```
531
532
### Update Scope Map Permissions
533
534
```python
535
from azure.mgmt.containerregistry.models import ScopeMapUpdateParameters
536
537
# Update scope map to add new permissions
538
current_scope = client.scope_maps.get(
539
"my-resource-group",
540
"my-registry",
541
"frontend-access"
542
)
543
544
# Add delete permissions to existing scope map
545
updated_actions = current_scope.actions + [
546
"repositories/frontend/content/delete"
547
]
548
549
update_params = ScopeMapUpdateParameters(
550
description="Frontend access with delete permissions",
551
actions=updated_actions
552
)
553
554
updated_scope = client.scope_maps.begin_update(
555
"my-resource-group",
556
"my-registry",
557
"frontend-access",
558
update_params
559
).result()
560
561
print(f"Updated scope map with {len(updated_scope.actions)} actions")
562
print("New actions:", updated_scope.actions)
563
```
564
565
### Clean Up Access Control Resources
566
567
```python
568
# Clean up tokens and scope maps
569
tokens_to_delete = ["old-token", "temp-token"]
570
scope_maps_to_delete = ["old-scope", "temp-scope"]
571
572
# Delete tokens first (they depend on scope maps)
573
for token_name in tokens_to_delete:
574
try:
575
client.tokens.begin_delete(
576
"my-resource-group",
577
"my-registry",
578
token_name
579
).result()
580
print(f"Deleted token: {token_name}")
581
except Exception as e:
582
print(f"Failed to delete token {token_name}: {e}")
583
584
# Then delete scope maps
585
for scope_name in scope_maps_to_delete:
586
try:
587
client.scope_maps.begin_delete(
588
"my-resource-group",
589
"my-registry",
590
scope_name
591
).result()
592
print(f"Deleted scope map: {scope_name}")
593
except Exception as e:
594
print(f"Failed to delete scope map {scope_name}: {e}")
595
```