or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdcache-and-credentials.mdconnected-registries.mdindex.mdprivate-networking.mdregistry-management.mdreplication-management.mdwebhook-management.md

access-control.mddocs/

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

```