or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdasync.mdazure-platform.mdcore-credentials.mddeveloper.mdindex.mdinteractive.mdservice-principal.md

advanced.mddocs/

0

# Advanced Features

1

2

Advanced authentication features including authentication records for session persistence, token caching configuration, exception handling, utility functions, and authority host constants for different Azure clouds.

3

4

## Capabilities

5

6

### AuthenticationRecord

7

8

Non-secret account information that enables silent authentication and account caching. Returned by interactive credentials' `authenticate()` method and can be serialized for persistent storage.

9

10

```python { .api }

11

class AuthenticationRecord:

12

def __init__(

13

self,

14

tenant_id: str,

15

client_id: str,

16

authority: str,

17

home_account_id: str,

18

username: str

19

):

20

"""

21

Create an AuthenticationRecord with account information.

22

23

Args:

24

tenant_id: ID of the tenant the account should authenticate in

25

client_id: Client ID of the application which performed the original authentication

26

authority: Authority host used to authenticate the account

27

home_account_id: Unique identifier of the account

28

username: User principal or service principal name of the account

29

30

Note:

31

AuthenticationRecords are typically created by calling authenticate() on

32

interactive credentials, not by direct instantiation.

33

"""

34

35

@property

36

def authority(self) -> str:

37

"""The authority host used to authenticate the account."""

38

39

@property

40

def client_id(self) -> str:

41

"""The client ID of the application which performed the original authentication."""

42

43

@property

44

def home_account_id(self) -> str:

45

"""A unique identifier of the account."""

46

47

@property

48

def tenant_id(self) -> str:

49

"""The tenant the account should authenticate in."""

50

51

@property

52

def username(self) -> str:

53

"""The user principal or service principal name of the account."""

54

55

@classmethod

56

def deserialize(cls, data: str) -> 'AuthenticationRecord':

57

"""

58

Deserialize an AuthenticationRecord from JSON string.

59

60

Args:

61

data: JSON string containing serialized AuthenticationRecord

62

63

Returns:

64

AuthenticationRecord: Deserialized authentication record

65

66

Raises:

67

ValueError: Invalid JSON data or missing required fields

68

"""

69

70

def serialize(self) -> str:

71

"""

72

Serialize the AuthenticationRecord to JSON string.

73

74

Returns:

75

str: JSON representation of the authentication record

76

77

Note:

78

The serialized record contains only non-secret account information

79

and can be safely stored in configuration files or databases.

80

"""

81

```

82

83

**Usage Example:**

84

85

```python

86

from azure.identity import InteractiveBrowserCredential, AuthenticationRecord

87

import json

88

89

# Perform interactive authentication

90

credential = InteractiveBrowserCredential()

91

record = credential.authenticate(scopes=["https://graph.microsoft.com/.default"])

92

93

print(f"Authenticated user: {record.username}")

94

print(f"Tenant: {record.tenant_id}")

95

print(f"Authority: {record.authority}")

96

97

# Serialize for persistent storage

98

serialized = record.serialize()

99

with open("auth_record.json", "w") as f:

100

f.write(serialized)

101

102

# Later, deserialize and reuse

103

with open("auth_record.json", "r") as f:

104

serialized = f.read()

105

106

restored_record = AuthenticationRecord.deserialize(serialized)

107

108

# Create new credential with cached account info

109

cached_credential = InteractiveBrowserCredential(

110

authentication_record=restored_record,

111

disable_automatic_authentication=True # Only use cache, don't prompt

112

)

113

114

try:

115

token = cached_credential.get_token("https://graph.microsoft.com/.default")

116

print("Silent authentication successful")

117

except AuthenticationRequiredError:

118

print("Cache expired, interactive authentication required")

119

```

120

121

### TokenCachePersistenceOptions

122

123

Configuration options for persistent token caching across application sessions. Enables tokens to be cached securely on disk and shared between application instances.

124

125

```python { .api }

126

class TokenCachePersistenceOptions:

127

def __init__(

128

self,

129

*,

130

allow_unencrypted_storage: bool = False,

131

name: str = "msal.cache",

132

**kwargs

133

):

134

"""

135

Create TokenCachePersistenceOptions for configuring persistent token caching.

136

137

Args:

138

allow_unencrypted_storage: Whether to fall back to unencrypted storage when

139

encryption is not available (default: False for security)

140

name: Prefix name of the cache for isolation between applications (default: "msal.cache")

141

142

Security Note:

143

When allow_unencrypted_storage=False and encryption is not available,

144

the credential will not cache tokens persistently. This is the secure default.

145

"""

146

```

147

148

**Usage Example:**

149

150

```python

151

from azure.identity import (

152

ClientSecretCredential,

153

TokenCachePersistenceOptions,

154

InteractiveBrowserCredential

155

)

156

157

# Configure encrypted token caching

158

cache_options = TokenCachePersistenceOptions(

159

allow_unencrypted_storage=False, # Require encryption (secure default)

160

name="myapp.cache" # Isolate cache from other applications

161

)

162

163

# Use with service principal credential

164

sp_credential = ClientSecretCredential(

165

tenant_id="your-tenant-id",

166

client_id="your-client-id",

167

client_secret="your-client-secret",

168

cache_persistence_options=cache_options

169

)

170

171

# Use with interactive credential

172

interactive_credential = InteractiveBrowserCredential(

173

cache_persistence_options=cache_options

174

)

175

176

# Development environment with unencrypted fallback (less secure)

177

dev_cache_options = TokenCachePersistenceOptions(

178

allow_unencrypted_storage=True, # Allow unencrypted storage if needed

179

name="dev.cache"

180

)

181

182

dev_credential = InteractiveBrowserCredential(

183

cache_persistence_options=dev_cache_options

184

)

185

```

186

187

### Exception Handling

188

189

Comprehensive exception classes for handling authentication failures and providing appropriate fallback strategies.

190

191

```python { .api }

192

from azure.core.exceptions import ClientAuthenticationError

193

194

class CredentialUnavailableError(ClientAuthenticationError):

195

"""

196

The credential did not attempt to authenticate because required data or state is unavailable.

197

198

This exception indicates that the credential cannot authenticate in the current environment,

199

typically due to missing configuration, unavailable services, or platform limitations.

200

"""

201

202

class AuthenticationRequiredError(CredentialUnavailableError):

203

def __init__(

204

self,

205

scopes: Iterable[str],

206

message: Optional[str] = None,

207

claims: Optional[str] = None,

208

**kwargs

209

):

210

"""

211

Interactive authentication is required to acquire a token.

212

213

Args:

214

scopes: Scopes requested during failed authentication

215

message: Error message describing the authentication requirement

216

claims: Additional claims required in next authentication attempt

217

"""

218

219

@property

220

def scopes(self) -> Iterable[str]:

221

"""Scopes requested during failed authentication."""

222

223

@property

224

def claims(self) -> Optional[str]:

225

"""Additional claims required in next authentication."""

226

```

227

228

**Usage Example:**

229

230

```python

231

from azure.identity import (

232

DefaultAzureCredential,

233

InteractiveBrowserCredential,

234

CredentialUnavailableError,

235

AuthenticationRequiredError

236

)

237

from azure.core.exceptions import ClientAuthenticationError

238

239

def robust_authentication():

240

"""Implement robust authentication with proper exception handling."""

241

242

# Try DefaultAzureCredential first

243

try:

244

credential = DefaultAzureCredential()

245

token = credential.get_token("https://graph.microsoft.com/.default")

246

print("Automatic authentication successful")

247

return credential

248

249

except CredentialUnavailableError as e:

250

print(f"Default authentication unavailable: {e}")

251

252

# Fall back to interactive authentication

253

try:

254

interactive_credential = InteractiveBrowserCredential()

255

token = interactive_credential.get_token("https://graph.microsoft.com/.default")

256

print("Interactive authentication successful")

257

return interactive_credential

258

259

except AuthenticationRequiredError as e:

260

print(f"Interactive authentication required for scopes: {list(e.scopes)}")

261

if e.claims:

262

print(f"Additional claims needed: {e.claims}")

263

264

# Perform explicit authentication

265

record = interactive_credential.authenticate(*e.scopes, claims=e.claims)

266

print(f"Authentication completed for user: {record.username}")

267

return interactive_credential

268

269

except ClientAuthenticationError as e:

270

print(f"Authentication failed: {e}")

271

raise

272

273

except Exception as e:

274

print(f"Unexpected error: {e}")

275

raise

276

277

# Use robust authentication

278

try:

279

credential = robust_authentication()

280

# Use credential with Azure SDK clients

281

except Exception as e:

282

print(f"Could not establish authentication: {e}")

283

```

284

285

### Authority Hosts and Constants

286

287

Constants for Microsoft Entra ID authority hosts across different Azure clouds and regions.

288

289

```python { .api }

290

class AzureAuthorityHosts:

291

"""Constants for Microsoft Entra ID authority hosts in different Azure clouds."""

292

293

AZURE_CHINA: str = "https://login.chinacloudapi.cn"

294

"""Authority host for Azure China cloud."""

295

296

AZURE_GOVERNMENT: str = "https://login.microsoftonline.us"

297

"""Authority host for Azure Government cloud."""

298

299

AZURE_PUBLIC_CLOUD: str = "https://login.microsoftonline.com"

300

"""Authority host for Azure Public cloud (default)."""

301

302

AZURE_GERMANY: str = "https://login.microsoftonline.de"

303

"""Authority host for Azure Germany cloud (deprecated)."""

304

305

# Backward compatibility alias

306

KnownAuthorities = AzureAuthorityHosts

307

```

308

309

**Usage Example:**

310

311

```python

312

from azure.identity import ClientSecretCredential, AzureAuthorityHosts

313

314

# Azure Public Cloud (default)

315

public_credential = ClientSecretCredential(

316

tenant_id="your-tenant-id",

317

client_id="your-client-id",

318

client_secret="your-client-secret"

319

# authority defaults to AzureAuthorityHosts.AZURE_PUBLIC_CLOUD

320

)

321

322

# Azure Government Cloud

323

gov_credential = ClientSecretCredential(

324

tenant_id="your-gov-tenant-id",

325

client_id="your-gov-client-id",

326

client_secret="your-gov-client-secret",

327

authority=AzureAuthorityHosts.AZURE_GOVERNMENT

328

)

329

330

# Azure China Cloud

331

china_credential = ClientSecretCredential(

332

tenant_id="your-china-tenant-id",

333

client_id="your-china-client-id",

334

client_secret="your-china-client-secret",

335

authority=AzureAuthorityHosts.AZURE_CHINA

336

)

337

338

# Custom authority (for Azure AD B2C or custom domains)

339

custom_credential = ClientSecretCredential(

340

tenant_id="your-tenant-id",

341

client_id="your-client-id",

342

client_secret="your-client-secret",

343

authority="https://your-custom-authority.com"

344

)

345

```

346

347

### Utility Functions

348

349

Helper functions for working with credentials and tokens in different scenarios.

350

351

```python { .api }

352

from typing import Callable, Any, Coroutine

353

from azure.core.credentials import TokenCredential, AccessToken

354

355

def get_bearer_token_provider(credential: TokenCredential, *scopes: str) -> Callable[[], str]:

356

"""

357

Returns a callable that provides a bearer token string for HTTP Authorization headers.

358

359

Args:

360

credential: The credential used to authenticate requests

361

*scopes: The scopes required for the bearer token

362

363

Returns:

364

Callable that returns a bearer token string when invoked

365

366

Usage:

367

Use this function to create a token provider for HTTP clients that expect

368

a callable returning a bearer token string for Authorization headers.

369

"""

370

371

# Async version in azure.identity.aio

372

def get_bearer_token_provider(credential: AsyncTokenCredential, *scopes: str) -> Callable[[], Coroutine[Any, Any, str]]:

373

"""

374

Returns a callable that provides a bearer token string asynchronously.

375

376

Args:

377

credential: The async credential used to authenticate requests

378

*scopes: The scopes required for the bearer token

379

380

Returns:

381

Callable that returns a coroutine yielding a bearer token string

382

"""

383

```

384

385

**Usage Example:**

386

387

```python

388

from azure.identity import DefaultAzureCredential, get_bearer_token_provider

389

import requests

390

391

# Create credential

392

credential = DefaultAzureCredential()

393

394

# Create bearer token provider for Microsoft Graph

395

graph_token_provider = get_bearer_token_provider(

396

credential,

397

"https://graph.microsoft.com/.default"

398

)

399

400

# Use with HTTP requests

401

def make_graph_request(endpoint: str):

402

token = graph_token_provider()

403

headers = {"Authorization": f"Bearer {token}"}

404

response = requests.get(f"https://graph.microsoft.com/v1.0/{endpoint}", headers=headers)

405

return response.json()

406

407

# Make Microsoft Graph API calls

408

user_data = make_graph_request("me")

409

print(f"User: {user_data.get('displayName')}")

410

411

# Use with different scopes for different services

412

storage_token_provider = get_bearer_token_provider(

413

credential,

414

"https://storage.azure.com/.default"

415

)

416

417

management_token_provider = get_bearer_token_provider(

418

credential,

419

"https://management.azure.com/.default"

420

)

421

```

422

423

### Environment Variables Reference

424

425

Complete reference of environment variables used by azure-identity credentials.

426

427

```python { .api }

428

class EnvironmentVariables:

429

"""Environment variable names used by various credentials."""

430

431

# Core authentication variables

432

AZURE_CLIENT_ID: str = "AZURE_CLIENT_ID"

433

"""Application client ID for service principal authentication."""

434

435

AZURE_CLIENT_SECRET: str = "AZURE_CLIENT_SECRET"

436

"""Client secret for service principal authentication."""

437

438

AZURE_TENANT_ID: str = "AZURE_TENANT_ID"

439

"""Microsoft Entra tenant ID."""

440

441

# Certificate authentication variables

442

AZURE_CLIENT_CERTIFICATE_PATH: str = "AZURE_CLIENT_CERTIFICATE_PATH"

443

"""Path to certificate file for certificate-based authentication."""

444

445

AZURE_CLIENT_CERTIFICATE_PASSWORD: str = "AZURE_CLIENT_CERTIFICATE_PASSWORD"

446

"""Password for encrypted certificate files."""

447

448

# Username/password authentication variables

449

AZURE_USERNAME: str = "AZURE_USERNAME"

450

"""Username for user authentication."""

451

452

AZURE_PASSWORD: str = "AZURE_PASSWORD"

453

"""Password for user authentication."""

454

455

# Managed identity endpoint variables

456

IDENTITY_ENDPOINT: str = "IDENTITY_ENDPOINT"

457

"""Managed identity endpoint URL."""

458

459

IDENTITY_HEADER: str = "IDENTITY_HEADER"

460

"""Managed identity authentication header."""

461

462

MSI_ENDPOINT: str = "MSI_ENDPOINT"

463

"""Legacy managed identity endpoint URL."""

464

465

MSI_SECRET: str = "MSI_SECRET"

466

"""Legacy managed identity authentication secret."""

467

468

# Workload identity variables

469

AZURE_FEDERATED_TOKEN_FILE: str = "AZURE_FEDERATED_TOKEN_FILE"

470

"""Path to federated token file for workload identity."""

471

472

# Authority and region settings

473

AZURE_AUTHORITY_HOST: str = "AZURE_AUTHORITY_HOST"

474

"""Authority host override for authentication."""

475

476

AZURE_REGIONAL_AUTHORITY_NAME: str = "AZURE_REGIONAL_AUTHORITY_NAME"

477

"""Regional authority name for multi-region scenarios."""

478

```

479

480

**Environment Setup Example:**

481

482

```bash

483

# Service principal with client secret

484

export AZURE_TENANT_ID="your-tenant-id"

485

export AZURE_CLIENT_ID="your-client-id"

486

export AZURE_CLIENT_SECRET="your-client-secret"

487

488

# Service principal with certificate

489

export AZURE_TENANT_ID="your-tenant-id"

490

export AZURE_CLIENT_ID="your-client-id"

491

export AZURE_CLIENT_CERTIFICATE_PATH="/path/to/certificate.pem"

492

export AZURE_CLIENT_CERTIFICATE_PASSWORD="cert-password"

493

494

# User authentication

495

export AZURE_TENANT_ID="your-tenant-id"

496

export AZURE_CLIENT_ID="your-public-client-id"

497

export AZURE_USERNAME="user@example.com"

498

export AZURE_PASSWORD="user-password"

499

500

# Workload identity (typically set by Kubernetes)

501

export AZURE_TENANT_ID="your-tenant-id"

502

export AZURE_CLIENT_ID="your-workload-client-id"

503

export AZURE_FEDERATED_TOKEN_FILE="/var/run/secrets/azure/tokens/azure-identity-token"

504

505

# Authority override for different clouds

506

export AZURE_AUTHORITY_HOST="https://login.microsoftonline.us" # Azure Government

507

```

508

509

## Advanced Configuration Patterns

510

511

### Multi-Tenant Authentication

512

513

```python

514

from azure.identity import ClientSecretCredential

515

516

# Multi-tenant application configuration

517

multi_tenant_credential = ClientSecretCredential(

518

tenant_id="primary-tenant-id",

519

client_id="your-client-id",

520

client_secret="your-client-secret",

521

additionally_allowed_tenants=["tenant-2-id", "tenant-3-id", "*"] # "*" allows all tenants

522

)

523

524

# Request token for specific tenant

525

primary_token = multi_tenant_credential.get_token(

526

"https://graph.microsoft.com/.default"

527

)

528

529

secondary_token = multi_tenant_credential.get_token(

530

"https://graph.microsoft.com/.default",

531

tenant_id="tenant-2-id" # Override to specific tenant

532

)

533

```

534

535

### Credential Performance Optimization

536

537

```python

538

from azure.identity import DefaultAzureCredential, TokenCachePersistenceOptions

539

540

# Optimize DefaultAzureCredential for production

541

production_credential = DefaultAzureCredential(

542

# Exclude credentials not needed in production

543

exclude_cli_credential=True,

544

exclude_powershell_credential=True,

545

exclude_developer_cli_credential=True,

546

exclude_visual_studio_code_credential=True,

547

exclude_interactive_browser_credential=True,

548

549

# Configure specific identity for production

550

managed_identity_client_id="production-identity-client-id"

551

)

552

553

# Optimize for development with caching

554

cache_options = TokenCachePersistenceOptions(

555

allow_unencrypted_storage=True, # For development only

556

name="dev-app-cache"

557

)

558

559

dev_credential = DefaultAzureCredential(

560

exclude_managed_identity_credential=True, # Skip in local dev

561

cache_persistence_options=cache_options

562

)

563

```

564

565

### Custom Authority and Instance Discovery

566

567

```python

568

from azure.identity import ClientSecretCredential

569

570

# Custom authority with instance discovery disabled

571

custom_credential = ClientSecretCredential(

572

tenant_id="your-tenant-id",

573

client_id="your-client-id",

574

client_secret="your-client-secret",

575

authority="https://custom.authority.com",

576

disable_instance_discovery=True # Skip authority validation

577

)

578

579

# Azure AD B2C configuration

580

b2c_credential = ClientSecretCredential(

581

tenant_id="your-b2c-tenant.onmicrosoft.com",

582

client_id="your-b2c-client-id",

583

client_secret="your-b2c-client-secret",

584

authority="https://your-b2c-tenant.b2clogin.com",

585

disable_instance_discovery=True

586

)

587

```