Skip to content

Commit 07807d4

Browse files
authored
Merge pull request #97561 from msmbaldwin/akv-throt
Revised article
2 parents 754e0b6 + 1fd7fbb commit 07807d4

File tree

3 files changed

+121
-169
lines changed

3 files changed

+121
-169
lines changed

articles/key-vault/key-vault-ovw-throttling.md

Lines changed: 40 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ description: Key Vault throttling limits the number of concurrent calls to preve
44
services: key-vault
55
author: msmbaldwin
66
manager: rkarlin
7-
tags:
87

98
ms.service: key-vault
109
ms.topic: conceptual
11-
ms.date: 05/10/2018
10+
ms.date: 12/02/2019
1211
ms.author: mbaldwin
1312

1413
---
@@ -21,10 +20,34 @@ Throttling limits vary based on the scenario. For example, if you are performing
2120

2221
## How does Key Vault handle its limits?
2322

24-
Service limits in Key Vault are there to prevent misuse of resources and ensure quality of service for all of Key Vaults clients. When a service threshold is exceeded, Key Vault limits any further requests from that client for a period of time. When this happens, Key Vault returns HTTP status code 429 (Too many requests), and the requests fail. Also, failed requests that return a 429 count towards the throttle limits tracked by Key Vault.
23+
Service limits in Key Vault prevent misuse of resources and ensure quality of service for all of Key Vault's clients. When a service threshold is exceeded, Key Vault limits any further requests from that client for a period of time, returns HTTP status code 429 (Too many requests), and the request fails. Failed requests that return a 429 count towards the throttle limits tracked by Key Vault.
2524

26-
If you have a valid business case for higher throttle limits, please contact us.
25+
Key Vault was originally designed to be used to store and retrieve your secrets at deployment time. The world has evolved, and Key Vault is being used at run-time to store and retrieve secrets, and often apps and services want to use Key Vault like a database. Current limits do not support high throughput rates.
26+
27+
Key Vault was originally created with the limits specified in [Azure Key Vault service limits](key-vault-service-limits.md). To maximize your Key Vault through put rates, here are some recommended guidelines/best practices for maximizing your throughput:
28+
1. Ensure you have throttling in place. Client must honor exponential back-off policies for 429's and ensure you are doing retries as per the guidance below.
29+
1. Divide your Key Vault traffic amongst multiple vaults and different regions. Use a separate vault for each security/availability domain. If you have five apps, each in two regions, then we recommend 10 vaults each containing the secrets unique to app and region. A subscription-wide limit for all transaction types is five times the individual key vault limit. For example, HSM-other transactions per subscription are limited to 5,000 transactions in 10 seconds per subscription. Consider caching the secret within your service or app to also reduce the RPS directly to key vault and/or handle burst based traffic. You can also divide your traffic amongst different regions to minimize latency and use a different subscription/vault. Do not send more than the subscription limit to the Key Vault service in a single Azure region.
30+
1. Cache the secrets you retrieve from Azure Key Vault in memory, and reuse from memory whenever possible. Re-read from Azure Key Vault only when the cached copy stops working (e.g. because it got rotated at the source).
31+
1. Key Vault is designed for your own services secrets. If you are storing your customers' secrets (especially for high-throughput key storage scenarios), consider putting the keys in a database or storage account with encryption, and storing just the master key in Azure Key Vault.
32+
1. Encrypt, wrap, and verify public-key operations can be performed with no access to Key Vault, which not only reduces risk of throttling, but also improves reliability (as long as you properly cache the public key material).
33+
1. If you use Key Vault to store credentials for a service, check if that service supports AAD Authentication to authenticate directly. This reduces the load on Key Vault, improves reliability and simplifies your code since Key Vault can now use the AAD token. Many services have moved to using AAD Auth. See the current list at [Services that support managed identities for Azure resources](../active-directory/managed-identities-azure-resources/services-support-managed-identities.md#azure-services-that-support-managed-identities-for-azure-resources).
34+
1. Consider staggering your load/deployment over a longer period of time to stay under the current RPS limits.
35+
1. If your app comprises multiple nodes that need to read the same secret(s), then consider using a fan out pattern, where one entity reads the secret from Key Vault, and fans out to all nodes. Cache the retrieved secrets only in memory.
36+
If you find that the above still does not meet your needs, please fill out the below table and contact us to determine what additional capacity can be added (example put below for illustrative purposes only).
37+
38+
| Vault name | Vault Region | Object type (Secret, Key, or Cert) | Operation(s)* | Key Type | Key Length or Curve | HSM key?| Steady state RPS needed | Peak RPS needed |
39+
|--|--|--|--|--|--|--|--|--|
40+
| https://mykeyvault.vault.azure.net/ | | Key | Sign | EC | P-256 | No | 200 | 1000 |
2741

42+
\* For a full list of possible values, see [Azure Key Vault operations](/rest/api/keyvault/key-operations).
43+
44+
If additional capacity is approved, please note the following as result of the capacity increases:
45+
1. Data consistency model changes. Once a vault is allow listed with additional throughput capacity, the Key Vault service data consistency guarantee changes (necessary to meet higher volume RPS since the underlying Azure Storage service cannot keep up). In a nutshell:
46+
1. **Without allow listing**: The Key Vault service will reflect the results of a write operation (eg. SecretSet, CreateKey) immediately in subsequent calls (eg. SecretGet, KeySign).
47+
1. **With allow listing**: The Key Vault service will reflect the results of a write operation (eg. SecretSet, CreateKey) within 60 seconds in subsequent calls (eg. SecretGet, KeySign).
48+
1. Client code must honor back-off policy for 429 retries. The client code calling the Key Vault service must not immediately retry Key Vault requests when it receives a 429 response code. The Azure Key Vault throttling guidance published here recommends applying exponential backoff when receiving a 429 Http response code.
49+
50+
If you have a valid business case for higher throttle limits, please contact us.
2851

2952
## How to throttle your app in response to service limits
3053

@@ -38,97 +61,24 @@ When you implement your app's error handling, use the HTTP error code 429 to det
3861

3962
Code that implements exponential backoff is shown below.
4063
```
41-
public sealed class RetryWithExponentialBackoff
64+
SecretClientOptions options = new SecretClientOptions()
4265
{
43-
private readonly int maxRetries, delayMilliseconds, maxDelayMilliseconds;
44-
45-
public RetryWithExponentialBackoff(int maxRetries = 50,
46-
int delayMilliseconds = 200,
47-
int maxDelayMilliseconds = 2000)
48-
{
49-
this.maxRetries = maxRetries;
50-
this.delayMilliseconds = delayMilliseconds;
51-
this.maxDelayMilliseconds = maxDelayMilliseconds;
52-
}
53-
54-
public async Task RunAsync(Func<Task> func)
66+
Retry =
5567
{
56-
ExponentialBackoff backoff = new ExponentialBackoff(this.maxRetries,
57-
this.delayMilliseconds,
58-
this.maxDelayMilliseconds);
59-
retry:
60-
try
61-
{
62-
await func();
63-
}
64-
catch (Exception ex) when (ex is TimeoutException ||
65-
ex is System.Net.Http.HttpRequestException)
66-
{
67-
Debug.WriteLine("Exception raised is: " +
68-
ex.GetType().ToString() +
69-
" –Message: " + ex.Message +
70-
" -- Inner Message: " +
71-
ex.InnerException.Message);
72-
await backoff.Delay();
73-
goto retry;
74-
}
75-
}
76-
}
77-
78-
public struct ExponentialBackoff
79-
{
80-
private readonly int m_maxRetries, m_delayMilliseconds, m_maxDelayMilliseconds;
81-
private int m_retries, m_pow;
82-
83-
public ExponentialBackoff(int maxRetries, int delayMilliseconds,
84-
int maxDelayMilliseconds)
85-
{
86-
m_maxRetries = maxRetries;
87-
m_delayMilliseconds = delayMilliseconds;
88-
m_maxDelayMilliseconds = maxDelayMilliseconds;
89-
m_retries = 0;
90-
m_pow = 1;
91-
}
92-
93-
public Task Delay()
94-
{
95-
if (m_retries == m_maxRetries)
96-
{
97-
throw new TimeoutException("Max retry attempts exceeded.");
98-
}
99-
++m_retries;
100-
if (m_retries < 31)
101-
{
102-
m_pow = m_pow << 1; // m_pow = Pow(2, m_retries - 1)
103-
}
104-
int delay = Math.Min(m_delayMilliseconds * (m_pow - 1) / 2,
105-
m_maxDelayMilliseconds);
106-
return Task.Delay(delay);
107-
}
108-
}
68+
Delay= TimeSpan.FromSeconds(2),
69+
MaxDelay = TimeSpan.FromSeconds(16),
70+
MaxRetries = 5,
71+
Mode = RetryMode.Exponential
72+
}
73+
};
74+
var client = new SecretClient(new Uri(https://keyVaultName.vault.azure.net"), new DefaultAzureCredential(),options);
75+
76+
//Retrieve Secret
77+
secret = client.GetSecret(secretName);
10978
```
11079

11180

112-
Using this code in a client C\# application is straightforward. The following example shows how, using the HttpClient class.
113-
114-
```csharp
115-
public async Task<Cart> GetCartItems(int page)
116-
{
117-
_apiClient = new HttpClient();
118-
//
119-
// Using HttpClient with Retry and Exponential Backoff
120-
//
121-
var retry = new RetryWithExponentialBackoff();
122-
await retry.RunAsync(async () =>
123-
{
124-
// work with HttpClient call
125-
dataString = await _apiClient.GetStringAsync(catalogUrl);
126-
});
127-
return JsonConvert.DeserializeObject<Cart>(dataString);
128-
}
129-
```
130-
131-
Remember that this code is suitable only as a proof of concept.
81+
Using this code in a client C# application is straightforward.
13282

13383
### Recommended client-side throttling method
13484

articles/virtual-machines/extensions/key-vault-linux.md

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ title: Azure Key Vault VM Extension for Linux
33
description: Deploy an agent performing automatic refresh of Key Vault certificates on virtual machines using a virtual machine extension.
44
services: virtual-machines-linux
55
author: msmbaldwin
6+
tags: keyvault
67

78
ms.service: virtual-machines-linux
89
ms.topic: article
9-
ms.date: 09/23/2018
10+
ms.date: 12/02/2019
1011
ms.author: mbaldwin
1112

1213
---
@@ -36,20 +37,20 @@ The following JSON shows the schema for the Key Vault VM extension. The extensio
3637
"[concat('Microsoft.Compute/virtualMachines/', <vmName>)]"
3738
],
3839
"properties": {
39-
"publisher": "Microsoft.Azure.KeyVault.Edp",
40-
"type": "KeyVaultForLinux",
41-
"typeHandlerVersion": "1.0",
42-
"autoUpgradeMinorVersion": true,
43-
"settings": {
44-
"secretsManagementSettings": {
45-
"pollingIntervalInS": <polling interval in seconds>,
46-
"certificateStoreName": <certificate store name, e.g.: "MY">,
47-
"linkOnRenewal": <Not available on Linux e.g.: false>,
48-
"certificateStoreLocation": <certificate store location, currently it works locally only e.g.: "LocalMachine">,
49-
"requireInitialSync": <initial synchronization of certificates e..g: true>,
50-
"observedCertificates": <list of KeyVault URIs representing monitored certificates, e.g.: "https://myvault.vault.azure.net/secrets/mycertificate"
51-
}
52-
}
40+
"publisher": "Microsoft.Azure.KeyVault",
41+
"type": "KeyVaultForLinux",
42+
"typeHandlerVersion": "1.0",
43+
"autoUpgradeMinorVersion": true,
44+
"settings": {
45+
"secretsManagementSettings": {
46+
"pollingIntervalInS": <polling interval in seconds, e.g. "3600">,
47+
"certificateStoreName": <certificate store name, e.g.: "MY">,
48+
"linkOnRenewal": <Not available on Linux e.g.: false>,
49+
"certificateStoreLocation": <certificate store location, currently it works locally only e.g.: "LocalMachine">,
50+
"requireInitialSync": <initial synchronization of certificates e..g: true>,
51+
"observedCertificates": <list of KeyVault URIs representing monitored certificates, e.g.: "https://myvault.vault.azure.net/secrets/mycertificate"
52+
}
53+
}
5354
}
5455
}
5556
```
@@ -65,7 +66,7 @@ The following JSON shows the schema for the Key Vault VM extension. The extensio
6566
| Name | Value / Example | Data Type |
6667
| ---- | ---- | ---- |
6768
| apiVersion | 2019-07-01 | date |
68-
| publisher | Microsoft.Azure.KeyVault.Edp | string |
69+
| publisher | Microsoft.Azure.KeyVault | string |
6970
| type | KeyVaultForLinux | string |
7071
| typeHandlerVersion | 1.0 | int |
7172
| pollingIntervalInS | 3600 | string |
@@ -92,17 +93,17 @@ The JSON configuration for a virtual machine extension must be nested inside the
9293
"[concat('Microsoft.Compute/virtualMachines/', <vmName>)]"
9394
],
9495
"properties": {
95-
"publisher": "Microsoft.Azure.KeyVault.Edp",
96-
"type": "KeyVaultForLinux",
97-
"typeHandlerVersion": "1.0",
98-
"autoUpgradeMinorVersion": true,
99-
"settings": {
100-
"pollingIntervalInS": <polling interval in seconds>,
101-
"certificateStoreName": <certificate store name, e.g.: "MY">,
102-
"certificateStoreLocation": <certificate store location, currently it works locally only e.g.: "LocalMachine">,
103-
"observedCertificates": <list of KeyVault URIs representing monitored certificates, e.g.: "https://myvault.vault.azure.net/secrets/mycertificate"
104-
}
105-
}
96+
"publisher": "Microsoft.Azure.KeyVault",
97+
"type": "KeyVaultForLinux",
98+
"typeHandlerVersion": "1.0",
99+
"autoUpgradeMinorVersion": true,
100+
"settings": {
101+
"pollingIntervalInS": <polling interval in seconds, e.g. "3600">,
102+
"certificateStoreName": <certificate store name, e.g.: "MY">,
103+
"certificateStoreLocation": <certificate store location, currently it works locally only e.g.: "LocalMachine">,
104+
"observedCertificates": <list of KeyVault URIs representing monitored certificates, e.g.: "https://myvault.vault.azure.net/secrets/mycertificate"
105+
}
106+
}
106107
}
107108
}
108109
```
@@ -117,12 +118,12 @@ The Azure PowerShell can be used to deploy the Key Vault VM extension to an exis
117118
```powershell
118119
# Build settings
119120
$settings = '{"secretsManagementSettings":
120-
{ "pollingIntervalInS": "' + <pollingInterval> +
121-
'", "certificateStoreName": "' + <certStoreName> +
122-
'", "certificateStoreLocation": "' + <certStoreLoc> +
123-
'", "observedCertificates": ["' + <observedCerts> + '"] } }'
121+
{ "pollingIntervalInS": "' + <pollingInterval> +
122+
'", "certificateStoreName": "' + <certStoreName> +
123+
'", "certificateStoreLocation": "' + <certStoreLoc> +
124+
'", "observedCertificates": ["' + <observedCerts> + '"] } }'
124125
$extName = "KeyVaultForLinux"
125-
$extPublisher = "Microsoft.Azure.KeyVault.Edp"
126+
$extPublisher = "Microsoft.Azure.KeyVault"
126127
$extType = "KeyVaultForLinux"
127128
128129
@@ -137,12 +138,12 @@ The Azure PowerShell can be used to deploy the Key Vault VM extension to an exis
137138
138139
# Build settings
139140
$settings = '{"secretsManagementSettings":
140-
{ "pollingIntervalInS": "' + <pollingInterval> +
141-
'", "certificateStoreName": "' + <certStoreName> +
142-
'", "certificateStoreLocation": "' + <certStoreLoc> +
143-
'", "observedCertificates": ["' + <observedCerts> + '"] } }'
141+
{ "pollingIntervalInS": "' + <pollingInterval> +
142+
'", "certificateStoreName": "' + <certStoreName> +
143+
'", "certificateStoreLocation": "' + <certStoreLoc> +
144+
'", "observedCertificates": ["' + <observedCerts> + '"] } }'
144145
$extName = "KeyVaultForLinux"
145-
$extPublisher = "Microsoft.Azure.KeyVault.Edp"
146+
$extPublisher = "Microsoft.Azure.KeyVault"
146147
$extType = "KeyVaultForLinux"
147148
148149
# Add Extension to VMSS
@@ -182,8 +183,8 @@ The Azure CLI can be used to deploy the Key Vault VM extension to an existing vi
182183
183184
Please be aware of the following restrictions/requirements:
184185
- Key Vault restrictions:
185-
- It must exist at the time of the deployment
186-
- Key Vault Access Policy is set for VM/VMSS Identity using MSI
186+
- It must exist at the time of the deployment
187+
- Key Vault Access Policy is set for VM/VMSS Identity using MSI
187188
188189
189190
## Troubleshoot and support
@@ -204,4 +205,4 @@ Get-AzVMExtension -VMName <vmName> -ResourceGroupname <resource group name>
204205

205206
### Support
206207

207-
If you need more help at any point in this article, you can contact the Azure experts on the [MSDN Azure and Stack Overflow forums](https://azure.microsoft.com/support/forums/). Alternatively, you can file an Azure support incident. Go to the [Azure support site](https://azure.microsoft.com/support/options/) and select Get support. For information about using Azure Support, read the [Microsoft Azure support FAQ](https://azure.microsoft.com/support/faq/).
208+
If you need more help at any point in this article, you can contact the Azure experts on the [MSDN Azure and Stack Overflow forums](https://azure.microsoft.com/support/forums/). Alternatively, you can file an Azure support incident. Go to the [Azure support site](https://azure.microsoft.com/support/options/) and select Get support. For information about using Azure Support, read the [Microsoft Azure support FAQ](https://azure.microsoft.com/support/faq/).

0 commit comments

Comments
 (0)