0
# Policy Management
1
2
Comprehensive policy system for implementing cross-cutting concerns including authentication, rate limiting, transformation, caching, and routing. Supports policies at global, product, API, and operation levels with reusable policy fragments and validation capabilities.
3
4
## Capabilities
5
6
### Global Policy Management
7
8
Service-level global policies that apply to all APIs and operations within the API Management instance.
9
10
```python { .api }
11
class PolicyOperations:
12
def get(self, resource_group_name: str, service_name: str, policy_id: str, format: Optional[str] = None, **kwargs) -> PolicyContract: ...
13
def create_or_update(self, resource_group_name: str, service_name: str, policy_id: str, parameters: PolicyContract, if_match: Optional[str] = None, **kwargs) -> PolicyContract: ...
14
def delete(self, resource_group_name: str, service_name: str, policy_id: str, if_match: str, **kwargs) -> None: ...
15
def list_by_service(self, resource_group_name: str, service_name: str, **kwargs) -> PolicyCollection: ...
16
def get_entity_tag(self, resource_group_name: str, service_name: str, policy_id: str, **kwargs) -> bool: ...
17
```
18
19
### Policy Fragment Management
20
21
Reusable policy fragments that can be referenced across multiple policies for better maintainability and consistency.
22
23
```python { .api }
24
class PolicyFragmentOperations:
25
def get(self, resource_group_name: str, service_name: str, policy_fragment_id: str, format: Optional[str] = None, **kwargs) -> PolicyFragmentContract: ...
26
def begin_create_or_update(self, resource_group_name: str, service_name: str, policy_fragment_id: str, parameters: PolicyFragmentContract, if_match: Optional[str] = None, **kwargs) -> LROPoller[PolicyFragmentContract]: ...
27
def begin_delete(self, resource_group_name: str, service_name: str, policy_fragment_id: str, if_match: str, **kwargs) -> LROPoller[None]: ...
28
def list_by_service(self, resource_group_name: str, service_name: str, filter: Optional[str] = None, top: Optional[int] = None, skip: Optional[int] = None, **kwargs) -> ItemPaged[PolicyFragmentContract]: ...
29
def get_entity_tag(self, resource_group_name: str, service_name: str, policy_fragment_id: str, **kwargs) -> bool: ...
30
def list_references(self, resource_group_name: str, service_name: str, policy_fragment_id: str, top: Optional[int] = None, skip: Optional[int] = None, **kwargs) -> ItemPaged[ResourceCollection]: ...
31
```
32
33
### Policy Description Operations
34
35
Management of policy descriptions and documentation for available policy types.
36
37
```python { .api }
38
class PolicyDescriptionOperations:
39
def list_by_service(self, resource_group_name: str, service_name: str, scope: Optional[str] = None, **kwargs) -> PolicyDescriptionCollection: ...
40
```
41
42
### Policy Restriction Management
43
44
Policy validation and restriction enforcement to ensure policy compliance and security.
45
46
```python { .api }
47
class PolicyRestrictionOperations:
48
def get(self, resource_group_name: str, service_name: str, policy_restriction_id: str, **kwargs) -> PolicyRestrictionContract: ...
49
def update(self, resource_group_name: str, service_name: str, policy_restriction_id: str, if_match: str, parameters: PolicyRestrictionContract, **kwargs) -> PolicyRestrictionContract: ...
50
def list_by_service(self, resource_group_name: str, service_name: str, **kwargs) -> PolicyRestrictionCollection: ...
51
def get_entity_tag(self, resource_group_name: str, service_name: str, policy_restriction_id: str, **kwargs) -> bool: ...
52
53
class PolicyRestrictionValidationsOperations:
54
def by_service_and_policy_id(self, resource_group_name: str, service_name: str, policy_restriction_id: str, parameters: PolicyRestrictionValidationParameters, **kwargs) -> PolicyRestrictionValidationResult: ...
55
```
56
57
### All Policies Operations
58
59
Comprehensive policy management across all scopes (global, product, API, operation).
60
61
```python { .api }
62
class AllPoliciesOperations:
63
def list_by_service(self, resource_group_name: str, service_name: str, **kwargs) -> AllPoliciesCollection: ...
64
```
65
66
### API-Level Policy Operations
67
68
Policy management specific to individual APIs, inherited by all operations within the API unless overridden.
69
70
```python { .api }
71
class ApiPolicyOperations:
72
def get(self, resource_group_name: str, service_name: str, api_id: str, policy_id: str, format: Optional[str] = None, **kwargs) -> PolicyContract: ...
73
def create_or_update(self, resource_group_name: str, service_name: str, api_id: str, policy_id: str, parameters: PolicyContract, if_match: Optional[str] = None, **kwargs) -> PolicyContract: ...
74
def delete(self, resource_group_name: str, service_name: str, api_id: str, policy_id: str, if_match: str, **kwargs) -> None: ...
75
def list_by_api(self, resource_group_name: str, service_name: str, api_id: str, **kwargs) -> PolicyCollection: ...
76
def get_entity_tag(self, resource_group_name: str, service_name: str, api_id: str, policy_id: str, **kwargs) -> bool: ...
77
```
78
79
### Operation-Level Policy Operations
80
81
Fine-grained policy management for individual API operations with the highest precedence in the policy hierarchy.
82
83
```python { .api }
84
class ApiOperationPolicyOperations:
85
def get(self, resource_group_name: str, service_name: str, api_id: str, operation_id: str, policy_id: str, format: Optional[str] = None, **kwargs) -> PolicyContract: ...
86
def create_or_update(self, resource_group_name: str, service_name: str, api_id: str, operation_id: str, policy_id: str, parameters: PolicyContract, if_match: Optional[str] = None, **kwargs) -> PolicyContract: ...
87
def delete(self, resource_group_name: str, service_name: str, api_id: str, operation_id: str, policy_id: str, if_match: str, **kwargs) -> None: ...
88
def list_by_operation(self, resource_group_name: str, service_name: str, api_id: str, operation_id: str, **kwargs) -> PolicyCollection: ...
89
def get_entity_tag(self, resource_group_name: str, service_name: str, api_id: str, operation_id: str, policy_id: str, **kwargs) -> bool: ...
90
```
91
92
### Product-Level Policy Operations
93
94
Policy management for products, applying to all APIs within the product scope.
95
96
```python { .api }
97
class ProductPolicyOperations:
98
def get(self, resource_group_name: str, service_name: str, product_id: str, policy_id: str, format: Optional[str] = None, **kwargs) -> PolicyContract: ...
99
def create_or_update(self, resource_group_name: str, service_name: str, product_id: str, policy_id: str, parameters: PolicyContract, if_match: Optional[str] = None, **kwargs) -> PolicyContract: ...
100
def delete(self, resource_group_name: str, service_name: str, product_id: str, policy_id: str, if_match: str, **kwargs) -> None: ...
101
def list_by_product(self, resource_group_name: str, service_name: str, product_id: str, **kwargs) -> PolicyCollection: ...
102
def get_entity_tag(self, resource_group_name: str, service_name: str, product_id: str, policy_id: str, **kwargs) -> bool: ...
103
```
104
105
## Usage Examples
106
107
### Creating a Rate Limiting Policy
108
109
```python
110
from azure.mgmt.apimanagement.models import PolicyContract
111
112
# Define rate limiting policy XML
113
rate_limit_policy = """
114
<policies>
115
<inbound>
116
<rate-limit calls="100" renewal-period="60" />
117
<quota calls="10000" renewal-period="604800" />
118
<base />
119
</inbound>
120
<backend>
121
<base />
122
</backend>
123
<outbound>
124
<base />
125
</outbound>
126
<on-error>
127
<base />
128
</on-error>
129
</policies>
130
"""
131
132
# Create policy contract
133
policy = PolicyContract(
134
value=rate_limit_policy,
135
format="xml"
136
)
137
138
# Apply policy at global level
139
global_policy = client.policy.create_or_update(
140
resource_group_name="my-rg",
141
service_name="my-apim",
142
policy_id="policy",
143
parameters=policy
144
)
145
146
print("Global rate limiting policy applied")
147
```
148
149
### Creating Authentication Policy
150
151
```python
152
# JWT validation policy
153
jwt_policy = """
154
<policies>
155
<inbound>
156
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized">
157
<openid-config url="https://login.microsoftonline.com/{tenant-id}/.well-known/openid_configuration" />
158
<required-claims>
159
<claim name="aud">
160
<value>{client-id}</value>
161
</claim>
162
</required-claims>
163
</validate-jwt>
164
<base />
165
</inbound>
166
<backend>
167
<base />
168
</backend>
169
<outbound>
170
<base />
171
</outbound>
172
<on-error>
173
<base />
174
</on-error>
175
</policies>
176
"""
177
178
# Apply to specific API
179
api_policy = PolicyContract(
180
value=jwt_policy,
181
format="xml"
182
)
183
184
api_auth_policy = client.api_policy.create_or_update(
185
resource_group_name="my-rg",
186
service_name="my-apim",
187
api_id="secure-api",
188
policy_id="policy",
189
parameters=api_policy
190
)
191
192
print("JWT authentication policy applied to API")
193
```
194
195
### Creating Reusable Policy Fragment
196
197
```python
198
from azure.mgmt.apimanagement.models import PolicyFragmentContract
199
200
# CORS policy fragment
201
cors_fragment = """
202
<fragment>
203
<cors allow-credentials="true">
204
<allowed-origins>
205
<origin>https://www.contoso.com</origin>
206
<origin>https://app.contoso.com</origin>
207
</allowed-origins>
208
<allowed-methods preflight-result-max-age="300">
209
<method>GET</method>
210
<method>POST</method>
211
<method>PUT</method>
212
<method>DELETE</method>
213
<method>OPTIONS</method>
214
</allowed-methods>
215
<allowed-headers>
216
<header>Content-Type</header>
217
<header>Authorization</header>
218
</allowed-headers>
219
</cors>
220
</fragment>
221
"""
222
223
# Create policy fragment
224
fragment = PolicyFragmentContract(
225
value=cors_fragment,
226
description="Standard CORS policy for Contoso applications",
227
format="xml"
228
)
229
230
cors_fragment = client.policy_fragment.begin_create_or_update(
231
resource_group_name="my-rg",
232
service_name="my-apim",
233
policy_fragment_id="cors-fragment",
234
parameters=fragment
235
).result()
236
237
print(f"Policy fragment created: {cors_fragment.name}")
238
```
239
240
### Using Policy Fragment in Policy
241
242
```python
243
# Policy that references the fragment
244
policy_with_fragment = """
245
<policies>
246
<inbound>
247
<include-fragment fragment-id="cors-fragment" />
248
<rate-limit calls="1000" renewal-period="60" />
249
<base />
250
</inbound>
251
<backend>
252
<base />
253
</backend>
254
<outbound>
255
<base />
256
</outbound>
257
<on-error>
258
<base />
259
</on-error>
260
</policies>
261
"""
262
263
# Apply policy using fragment
264
policy_with_fragment_contract = PolicyContract(
265
value=policy_with_fragment,
266
format="xml"
267
)
268
269
api_policy = client.api_policy.create_or_update(
270
resource_group_name="my-rg",
271
service_name="my-apim",
272
api_id="my-api",
273
policy_id="policy",
274
parameters=policy_with_fragment_contract
275
)
276
```
277
278
### Transformation Policy Example
279
280
```python
281
# Request/response transformation policy
282
transformation_policy = """
283
<policies>
284
<inbound>
285
<set-header name="X-Custom-Header" exists-action="override">
286
<value>@(context.Request.Headers.GetValueOrDefault("User-Agent",""))</value>
287
</set-header>
288
<rewrite-uri template="/v2/{path-param}" />
289
<set-query-parameter name="api-version" exists-action="override">
290
<value>2.0</value>
291
</set-query-parameter>
292
<json-to-xml apply="always" consider-accept-header="false" />
293
<base />
294
</inbound>
295
<backend>
296
<retry condition="@(context.Response.StatusCode >= 500)" count="3" interval="1" />
297
<base />
298
</backend>
299
<outbound>
300
<xml-to-json kind="direct" apply="always" consider-accept-header="false" />
301
<find-and-replace from="oldValue" to="newValue" />
302
<base />
303
</outbound>
304
<on-error>
305
<set-status code="500" reason="Internal Server Error" />
306
<set-body>@{
307
return new JObject(
308
new JProperty("error", new JObject(
309
new JProperty("code", "InternalError"),
310
new JProperty("message", context.LastError.Message)
311
))
312
).ToString();
313
}</set-body>
314
<base />
315
</on-error>
316
</policies>
317
"""
318
319
transformation_policy_contract = PolicyContract(
320
value=transformation_policy,
321
format="xml"
322
)
323
324
operation_policy = client.api_operation_policy.create_or_update(
325
resource_group_name="my-rg",
326
service_name="my-apim",
327
api_id="transformation-api",
328
operation_id="transform-operation",
329
policy_id="policy",
330
parameters=transformation_policy_contract
331
)
332
```
333
334
## Types
335
336
### Core Policy Types
337
338
```python { .api }
339
class PolicyContract:
340
id: Optional[str]
341
name: Optional[str]
342
type: Optional[str]
343
properties: Optional[PolicyContractProperties]
344
345
class PolicyContractProperties:
346
value: str
347
format: Optional[PolicyContentFormat]
348
349
class PolicyFragmentContract:
350
id: Optional[str]
351
name: Optional[str]
352
type: Optional[str]
353
properties: Optional[PolicyFragmentContractProperties]
354
355
class PolicyFragmentContractProperties:
356
value: str
357
description: Optional[str]
358
format: Optional[PolicyContentFormat]
359
360
class PolicyCollection:
361
value: Optional[List[PolicyContract]]
362
next_link: Optional[str]
363
364
class PolicyDescriptionContract:
365
id: Optional[str]
366
name: Optional[str]
367
type: Optional[str]
368
properties: Optional[PolicyDescriptionContractProperties]
369
370
class PolicyDescriptionContractProperties:
371
display_name: Optional[str]
372
description: Optional[str]
373
scope: Optional[PolicyScopeContract]
374
375
class PolicyRestrictionContract:
376
id: Optional[str]
377
name: Optional[str]
378
type: Optional[str]
379
properties: Optional[PolicyRestrictionContractProperties]
380
381
class PolicyRestrictionContractProperties:
382
scope: Optional[str]
383
selector: Optional[str]
384
value: Optional[str]
385
```
386
387
### Policy Enums
388
389
```python { .api }
390
class PolicyContentFormat:
391
XML = "xml"
392
XML_LINK = "xml-link"
393
RAWXML = "rawxml"
394
RAWXML_LINK = "rawxml-link"
395
396
class PolicyScopeContract:
397
TENANT = "Tenant"
398
PRODUCT = "Product"
399
API = "Api"
400
OPERATION = "Operation"
401
ALL = "All"
402
403
class PolicyExportFormat:
404
XML = "xml"
405
RAWXML = "rawxml"
406
```
407
408
## Common Policy Examples
409
410
### Authentication Policies
411
412
- **API Key**: `<check-header name="Ocp-Apim-Subscription-Key" failed-check-httpcode="401" />`
413
- **JWT Validation**: `<validate-jwt header-name="Authorization">`
414
- **OAuth 2.0**: `<validate-jwt header-name="Authorization" require-scheme="Bearer">`
415
- **Certificate**: `<authentication-certificate thumbprint="{thumbprint}" />`
416
417
### Rate Limiting Policies
418
419
- **Rate Limit**: `<rate-limit calls="100" renewal-period="60" />`
420
- **Quota**: `<quota calls="10000" renewal-period="604800" />`
421
- **Rate Limit by Key**: `<rate-limit-by-key calls="100" renewal-period="60" counter-key="@(context.Request.IpAddress)" />`
422
423
### Transformation Policies
424
425
- **Set Header**: `<set-header name="X-Custom-Header" exists-action="override">`
426
- **Rewrite URI**: `<rewrite-uri template="/v2/users/{id}" />`
427
- **JSON to XML**: `<json-to-xml apply="always" />`
428
- **Find and Replace**: `<find-and-replace from="oldtext" to="newtext" />`
429
430
### Backend Policies
431
432
- **Set Backend Service**: `<set-backend-service base-url="https://backend.contoso.com" />`
433
- **Retry**: `<retry condition="@(context.Response.StatusCode >= 500)" count="3" />`
434
- **Timeout**: `<forward-request timeout="60" />`
435
- **Load Balancer**: `<set-backend-service backend-id="load-balanced-backend" />`