0
# Service Principal Credentials
1
2
Authenticate applications and services using Azure Active Directory service principals. Service principals are non-interactive identities that represent applications, enabling secure authentication without user interaction. These credentials support client secrets, X.509 certificates, and custom client assertions.
3
4
## Capabilities
5
6
### ClientSecretCredential
7
8
Authenticates a service principal using a client secret. This is the most common form of service principal authentication, suitable for applications that can securely store secrets.
9
10
```python { .api }
11
class ClientSecretCredential:
12
def __init__(
13
self,
14
tenant_id: str,
15
client_id: str,
16
client_secret: str,
17
*,
18
authority: Optional[str] = None,
19
cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
20
disable_instance_discovery: bool = False,
21
additionally_allowed_tenants: List[str] = None,
22
**kwargs
23
):
24
"""
25
Create a ClientSecretCredential for service principal authentication.
26
27
Args:
28
tenant_id: ID of the service principal's tenant (directory ID)
29
client_id: The service principal's client ID (application ID)
30
client_secret: One of the service principal's client secrets
31
authority: Authority of a Microsoft Entra endpoint. Default: login.microsoftonline.com
32
cache_persistence_options: Configuration for persistent token caching
33
disable_instance_discovery: Disable instance discovery and authority validation
34
additionally_allowed_tenants: Additional allowed tenants beyond the configured tenant
35
"""
36
37
def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
38
"""
39
Request an access token for the specified scopes.
40
41
Args:
42
*scopes: Desired scopes for the access token
43
claims: Additional claims required in the token
44
tenant_id: Optional tenant ID override
45
46
Returns:
47
AccessToken: The access token with expiration information
48
49
Raises:
50
ClientAuthenticationError: Authentication failed due to invalid credentials
51
"""
52
53
def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
54
"""
55
Request access token with additional information.
56
57
Args:
58
*scopes: Desired scopes for the access token
59
options: Additional options for token acquisition
60
61
Returns:
62
dict: Token information including access token and metadata
63
"""
64
```
65
66
**Usage Example:**
67
68
```python
69
from azure.identity import ClientSecretCredential
70
from azure.keyvault.secrets import SecretClient
71
72
# Create service principal credential
73
credential = ClientSecretCredential(
74
tenant_id="your-tenant-id",
75
client_id="your-client-id",
76
client_secret="your-client-secret"
77
)
78
79
# Use with Azure SDK client
80
secret_client = SecretClient(
81
vault_url="https://vault.vault.azure.net/",
82
credential=credential
83
)
84
85
# Multi-tenant configuration
86
multi_tenant_credential = ClientSecretCredential(
87
tenant_id="primary-tenant-id",
88
client_id="your-client-id",
89
client_secret="your-client-secret",
90
additionally_allowed_tenants=["tenant-2", "tenant-3"]
91
)
92
```
93
94
### CertificateCredential
95
96
Authenticates a service principal using an X.509 certificate. More secure than client secrets as certificates can be stored in secure hardware and have expiration dates.
97
98
```python { .api }
99
class CertificateCredential:
100
def __init__(
101
self,
102
tenant_id: str,
103
client_id: str,
104
certificate_path: Optional[str] = None,
105
*,
106
authority: Optional[str] = None,
107
certificate_data: Optional[bytes] = None,
108
password: Optional[Union[str, bytes]] = None,
109
send_certificate_chain: bool = False,
110
cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
111
disable_instance_discovery: bool = False,
112
additionally_allowed_tenants: List[str] = None,
113
**kwargs
114
):
115
"""
116
Create a CertificateCredential for certificate-based service principal authentication.
117
118
Args:
119
tenant_id: ID of the service principal's tenant
120
client_id: The service principal's client ID
121
certificate_path: Path to a certificate file in PEM or PKCS12 format
122
authority: Authority of a Microsoft Entra endpoint
123
certificate_data: The bytes of a certificate in PEM or PKCS12 format (alternative to certificate_path)
124
password: The certificate's password (for PKCS12 certificates)
125
send_certificate_chain: Send the complete public certificate chain in x5c header
126
cache_persistence_options: Configuration for persistent token caching
127
disable_instance_discovery: Disable instance discovery and authority validation
128
additionally_allowed_tenants: Additional allowed tenants beyond the configured tenant
129
"""
130
131
def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
132
"""
133
Request an access token for the specified scopes using certificate authentication.
134
135
Args:
136
*scopes: Desired scopes for the access token
137
claims: Additional claims required in the token
138
tenant_id: Optional tenant ID override
139
140
Returns:
141
AccessToken: The access token with expiration information
142
143
Raises:
144
ClientAuthenticationError: Authentication failed due to invalid certificate
145
ValueError: Certificate path and data both provided or neither provided
146
"""
147
148
def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
149
"""
150
Request access token with additional information.
151
152
Args:
153
*scopes: Desired scopes for the access token
154
options: Additional options for token acquisition
155
156
Returns:
157
dict: Token information including access token and metadata
158
"""
159
```
160
161
**Usage Example:**
162
163
```python
164
from azure.identity import CertificateCredential
165
166
# Certificate from file path
167
credential = CertificateCredential(
168
tenant_id="your-tenant-id",
169
client_id="your-client-id",
170
certificate_path="/path/to/certificate.pem"
171
)
172
173
# Certificate with password (PKCS12)
174
p12_credential = CertificateCredential(
175
tenant_id="your-tenant-id",
176
client_id="your-client-id",
177
certificate_path="/path/to/certificate.p12",
178
password="certificate-password"
179
)
180
181
# Certificate from bytes (loaded from secure storage)
182
with open("/path/to/certificate.pem", "rb") as cert_file:
183
cert_data = cert_file.read()
184
185
data_credential = CertificateCredential(
186
tenant_id="your-tenant-id",
187
client_id="your-client-id",
188
certificate_data=cert_data
189
)
190
191
# Include full certificate chain for validation
192
chain_credential = CertificateCredential(
193
tenant_id="your-tenant-id",
194
client_id="your-client-id",
195
certificate_path="/path/to/certificate.pem",
196
send_certificate_chain=True
197
)
198
```
199
200
### ClientAssertionCredential
201
202
Authenticates a service principal using a signed client assertion (JWT). Provides the most flexibility for custom authentication scenarios and integration with hardware security modules (HSMs) or custom signing mechanisms.
203
204
```python { .api }
205
class ClientAssertionCredential:
206
def __init__(
207
self,
208
tenant_id: str,
209
client_id: str,
210
func: Callable[[], str],
211
*,
212
authority: Optional[str] = None,
213
cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
214
disable_instance_discovery: bool = False,
215
additionally_allowed_tenants: List[str] = None,
216
**kwargs
217
):
218
"""
219
Create a ClientAssertionCredential for custom assertion-based authentication.
220
221
Args:
222
tenant_id: ID of the application's Microsoft Entra tenant
223
client_id: The application's client ID
224
func: A callable that returns a client assertion (signed JWT)
225
authority: Authority of a Microsoft Entra endpoint
226
cache_persistence_options: Configuration for persistent token caching
227
disable_instance_discovery: Disable instance discovery and authority validation
228
additionally_allowed_tenants: Additional allowed tenants beyond the configured tenant
229
230
Note:
231
The func callable must return a valid JWT client assertion each time it's called.
232
The assertion must be signed with the application's registered certificate or key.
233
"""
234
235
def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
236
"""
237
Request an access token using the client assertion.
238
239
Args:
240
*scopes: Desired scopes for the access token
241
claims: Additional claims required in the token
242
tenant_id: Optional tenant ID override
243
244
Returns:
245
AccessToken: The access token with expiration information
246
247
Raises:
248
ClientAuthenticationError: Authentication failed due to invalid assertion
249
"""
250
251
def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
252
"""
253
Request access token with additional information.
254
255
Args:
256
*scopes: Desired scopes for the access token
257
options: Additional options for token acquisition
258
259
Returns:
260
dict: Token information including access token and metadata
261
"""
262
```
263
264
**Usage Example:**
265
266
```python
267
from azure.identity import ClientAssertionCredential
268
import jwt
269
import time
270
271
def create_client_assertion():
272
"""Create a signed JWT client assertion."""
273
now = int(time.time())
274
payload = {
275
'aud': f'https://login.microsoftonline.com/{tenant_id}/v2.0',
276
'exp': now + 600, # 10 minutes
277
'iss': client_id,
278
'jti': str(uuid.uuid4()), # unique identifier
279
'nbf': now,
280
'sub': client_id
281
}
282
283
# Sign with your private key
284
return jwt.encode(payload, private_key, algorithm='RS256')
285
286
# Create credential with custom assertion function
287
credential = ClientAssertionCredential(
288
tenant_id="your-tenant-id",
289
client_id="your-client-id",
290
func=create_client_assertion
291
)
292
293
# Use with Azure SDK
294
from azure.storage.blob import BlobServiceClient
295
296
blob_client = BlobServiceClient(
297
account_url="https://account.blob.core.windows.net",
298
credential=credential
299
)
300
```
301
302
### OnBehalfOfCredential
303
304
Implements the OAuth 2.0 On-Behalf-Of flow for middle-tier services that need to access downstream APIs on behalf of a user. Commonly used in multi-tier application architectures.
305
306
```python { .api }
307
class OnBehalfOfCredential:
308
def __init__(
309
self,
310
tenant_id: str,
311
client_id: str,
312
*,
313
client_secret: Optional[str] = None,
314
user_assertion: Optional[str] = None,
315
client_assertion: Optional[str] = None,
316
client_assertion_func: Optional[Callable[[], str]] = None,
317
authority: Optional[str] = None,
318
cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
319
disable_instance_discovery: bool = False,
320
additionally_allowed_tenants: List[str] = None,
321
**kwargs
322
):
323
"""
324
Create an OnBehalfOfCredential for on-behalf-of authentication flow.
325
326
Args:
327
tenant_id: ID of the application's Microsoft Entra tenant
328
client_id: The application's client ID
329
client_secret: One of the application's client secrets (mutually exclusive with client_assertion)
330
user_assertion: The access token the application will use to authenticate on behalf of the user
331
client_assertion: Signed client assertion (mutually exclusive with client_secret)
332
client_assertion_func: Function that returns a client assertion
333
authority: Authority of a Microsoft Entra endpoint
334
cache_persistence_options: Configuration for persistent token caching
335
disable_instance_discovery: Disable instance discovery and authority validation
336
additionally_allowed_tenants: Additional allowed tenants beyond the configured tenant
337
338
Note:
339
Either client_secret or client_assertion (or client_assertion_func) must be provided.
340
The user_assertion is typically obtained from the incoming request's Authorization header.
341
"""
342
343
def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
344
"""
345
Request an access token on behalf of a user.
346
347
Args:
348
*scopes: Desired scopes for the access token
349
claims: Additional claims required in the token
350
tenant_id: Optional tenant ID override
351
352
Returns:
353
AccessToken: The access token with expiration information
354
355
Raises:
356
ClientAuthenticationError: Authentication failed
357
"""
358
359
def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
360
"""
361
Request access token with additional information.
362
363
Args:
364
*scopes: Desired scopes for the access token
365
options: Additional options for token acquisition
366
367
Returns:
368
dict: Token information including access token and metadata
369
"""
370
```
371
372
**Usage Example:**
373
374
```python
375
from azure.identity import OnBehalfOfCredential
376
from flask import Flask, request
377
378
app = Flask(__name__)
379
380
@app.route('/api/data')
381
def get_data():
382
# Extract user token from Authorization header
383
auth_header = request.headers.get('Authorization')
384
user_token = auth_header.replace('Bearer ', '') if auth_header else None
385
386
# Create OBO credential
387
credential = OnBehalfOfCredential(
388
tenant_id="your-tenant-id",
389
client_id="your-client-id",
390
client_secret="your-client-secret",
391
user_assertion=user_token
392
)
393
394
# Use credential to access downstream API on behalf of user
395
from azure.storage.blob import BlobServiceClient
396
397
blob_client = BlobServiceClient(
398
account_url="https://account.blob.core.windows.net",
399
credential=credential
400
)
401
402
# Access user's data
403
containers = blob_client.list_containers()
404
return [c.name for c in containers]
405
```
406
407
### AuthorizationCodeCredential
408
409
Authenticates by redeeming an authorization code previously obtained from Microsoft Entra ID. Used in OAuth 2.0 authorization code flow scenarios, typically in web applications.
410
411
```python { .api }
412
class AuthorizationCodeCredential:
413
def __init__(
414
self,
415
tenant_id: str,
416
client_id: str,
417
authorization_code: str,
418
redirect_uri: str,
419
*,
420
client_secret: Optional[str] = None,
421
authority: Optional[str] = None,
422
cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
423
disable_instance_discovery: bool = False,
424
additionally_allowed_tenants: List[str] = None,
425
**kwargs
426
):
427
"""
428
Create an AuthorizationCodeCredential for authorization code flow.
429
430
Args:
431
tenant_id: ID of the application's Microsoft Entra tenant
432
client_id: The application's client ID
433
authorization_code: The authorization code from the user's log-in
434
redirect_uri: The application's redirect URI (must match registered URI)
435
client_secret: One of the application's client secrets (required for confidential clients)
436
authority: Authority of a Microsoft Entra endpoint
437
cache_persistence_options: Configuration for persistent token caching
438
disable_instance_discovery: Disable instance discovery and authority validation
439
additionally_allowed_tenants: Additional allowed tenants beyond the configured tenant
440
"""
441
442
def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
443
"""
444
Redeem the authorization code for an access token.
445
446
Args:
447
*scopes: Desired scopes for the access token
448
claims: Additional claims required in the token
449
tenant_id: Optional tenant ID override
450
451
Returns:
452
AccessToken: The access token with expiration information
453
454
Raises:
455
ClientAuthenticationError: Invalid authorization code or credentials
456
"""
457
458
def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
459
"""
460
Request access token with additional information.
461
462
Args:
463
*scopes: Desired scopes for the access token
464
options: Additional options for token acquisition
465
466
Returns:
467
dict: Token information including access token and metadata
468
"""
469
```
470
471
**Usage Example:**
472
473
```python
474
from azure.identity import AuthorizationCodeCredential
475
from flask import Flask, request, redirect, session
476
477
app = Flask(__name__)
478
479
@app.route('/login')
480
def login():
481
# Redirect to Microsoft Entra ID for authorization
482
auth_url = (
483
f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize"
484
f"?client_id={client_id}"
485
f"&response_type=code"
486
f"&redirect_uri={redirect_uri}"
487
f"&scope=https://graph.microsoft.com/.default"
488
)
489
return redirect(auth_url)
490
491
@app.route('/callback')
492
def callback():
493
# Extract authorization code from callback
494
code = request.args.get('code')
495
496
# Create credential with authorization code
497
credential = AuthorizationCodeCredential(
498
tenant_id="your-tenant-id",
499
client_id="your-client-id",
500
authorization_code=code,
501
redirect_uri="http://localhost:5000/callback",
502
client_secret="your-client-secret"
503
)
504
505
# Store credential in session for subsequent requests
506
session['credential'] = credential
507
return "Authentication successful!"
508
```
509
510
## Common Configuration
511
512
All service principal credentials support these common configuration options:
513
514
```python { .api }
515
# Multi-tenant configuration
516
additionally_allowed_tenants: List[str] = None
517
518
# Authority customization
519
authority: str = "https://login.microsoftonline.com" # Public cloud (default)
520
# authority: str = "https://login.chinacloudapi.cn" # Azure China
521
# authority: str = "https://login.microsoftonline.us" # Azure Government
522
523
# Token caching
524
cache_persistence_options: Optional[TokenCachePersistenceOptions] = None
525
526
# Instance discovery (for custom domains)
527
disable_instance_discovery: bool = False
528
529
# Logging and debugging
530
enable_support_logging: bool = False
531
```