diff --git a/sdk/keyvault/assets.json b/sdk/keyvault/assets.json index 62172f59c..9377449c7 100644 --- a/sdk/keyvault/assets.json +++ b/sdk/keyvault/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "cpp", "TagPrefix": "cpp/keyvault", - "Tag": "cpp/keyvault_5a151033a9" + "Tag": "cpp/keyvault_ea82152bd3" } diff --git a/sdk/keyvault/azure-security-keyvault-administration/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-administration/CHANGELOG.md index b3898e3ab..000cc5071 100644 --- a/sdk/keyvault/azure-security-keyvault-administration/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-administration/CHANGELOG.md @@ -2,4 +2,4 @@ ## 4.0.0-beta.1 (Unreleased) -- initial preview +- initial preview of Settings API. diff --git a/sdk/keyvault/azure-security-keyvault-administration/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-administration/CMakeLists.txt index 1dded3cca..547758ab1 100644 --- a/sdk/keyvault/azure-security-keyvault-administration/CMakeLists.txt +++ b/sdk/keyvault/azure-security-keyvault-administration/CMakeLists.txt @@ -103,7 +103,7 @@ if (BUILD_PERFORMANCE_TESTS) #add_subdirectory(test/perf) endif() -if(BUILD_SAMPLES) +if(BUILD_SAMPLES_HSM) add_subdirectory(test/samples) endif() diff --git a/sdk/keyvault/azure-security-keyvault-administration/README.md b/sdk/keyvault/azure-security-keyvault-administration/README.md index b95659474..2a6294ce6 100644 --- a/sdk/keyvault/azure-security-keyvault-administration/README.md +++ b/sdk/keyvault/azure-security-keyvault-administration/README.md @@ -1,11 +1,138 @@ # Azure Security KeyVault Administration client library for C++ +Azure Key Vault Managed HSM is a fully-managed, highly-available, single-tenant, standards-compliant cloud service that enables you to safeguard +cryptographic keys for your cloud applications using FIPS 140-2 Level 3 validated HSMs. + Azure Security Keyvault Administration Package client library for C++ (`azure-security-keyvault-administration`) matches necessary patterns that the development team has established to create a unified SDK written in the C++ programming language. These libraries follow the Azure SDK Design Guidelines for C++. The library allows client libraries to expose common functionality in a consistent fashion. Once you learn how to use these APIs in one client library, you will know how to use them in other client libraries. [Source code][administration_client_src] | [API reference documentation][api_reference] | [Product documentation][keyvault_docs] +## Getting started + +### Install the package +Install the Azure Key Vault Administration Setting client library for C++ with vcpkg: + +```cmd +vcpkg install azure-security-keyvault-administration-cpp +``` + +### Prerequisites + +* An [Azure subscription][azure_sub]. +* An existing Azure Key Vault. If you need to create an Azure Key Vault, you can use the [Azure CLI][azure_cli]. +* Authorization to an existing Azure Key Vault using either [RBAC][rbac_guide] (recommended) or [access control][access_policy]. + +To create a Managed HSM resource, run the following CLI command: + +```PowerShell +az keyvault create --hsm-name --resource-group --administrators --location +``` + +To get `` you can run the following CLI command: + +```PowerShell +az ad user show --id --query id +``` + +#### Activate your managed HSM + +All data plane commands are disabled until the HSM is activated. You will not be able to create keys or assign roles. +Only the designated administrators that were assigned during the create command can activate the HSM. To activate the HSM you must download the security domain. + +To activate your HSM you need: + +* A minimum of 3 RSA key-pairs (maximum 10) +* Specify the minimum number of keys required to decrypt the security domain (quorum) + +To activate the HSM you send at least 3 (maximum 10) RSA public keys to the HSM. The HSM encrypts the security domain with these keys and sends it back. +Once this security domain is successfully downloaded, your HSM is ready to use. +You also need to specify quorum, which is the minimum number of private keys required to decrypt the security domain. + +The example below shows how to use openssl to generate 3 self-signed certificates. + +```PowerShell +openssl req -newkey rsa:2048 -nodes -keyout cert_0.key -x509 -days 365 -out cert_0.cer +openssl req -newkey rsa:2048 -nodes -keyout cert_1.key -x509 -days 365 -out cert_1.cer +openssl req -newkey rsa:2048 -nodes -keyout cert_2.key -x509 -days 365 -out cert_2.cer +``` + +Use the `az keyvault security-domain download` command to download the security domain and activate your managed HSM. +The example below uses 3 RSA key pairs (only public keys are needed for this command) and sets the quorum to 2. + +```PowerShell +az keyvault security-domain download --hsm-name --sd-wrapping-keys ./certs/cert_0.cer ./certs/cert_1.cer ./certs/cert_2.cer --sd-quorum 2 --security-domain-file ContosoMHSM-SD.json +``` + +#### Controlling access to your managed HSM + +The designated administrators assigned during creation are automatically added to the "Managed HSM Administrators" [built-in role][built_in_roles], +who are able to download a security domain and [manage roles for data plane access][access_control], among other limited permissions. + +To perform other actions on keys, you need to assign principals to other roles such as "Managed HSM Crypto User", which can perform non-destructive key operations: + +```PowerShell +az keyvault role assignment create --hsm-name --role "Managed HSM Crypto User" --scope / --assignee-object-id --assignee-principal-type +``` + +Please read [best practices][best_practices] for properly securing your managed HSM. + +## Key Concepts +### Thread safety +We guarantee that all client instance methods are thread-safe and independent of each other ([guideline](https://azure.github.io/azure-sdk/cpp_introduction.html#thread-safety)). This ensures that the recommendation of reusing client instances is always safe, even across threads. + +### Additional concepts + + +[Replaceable HTTP transport adapter](https://github.com/Azure/azure-sdk-for-cpp/blob/main/sdk/core/azure-core#http-transport-adapter) | +[Long-running operations](https://github.com/Azure/azure-sdk-for-cpp/blob/main/sdk/core/azure-core#long-running-operations) | + + +## Examples + +For detailed samples please review the code provided. + +#### GetSettings + +To get all the available settings present on the Keyvault instance we will first create a client : +```CPP + auto tenantId = std::getenv("AZURE_TENANT_ID"); + auto clientId = std::getenv("AZURE_CLIENT_ID"); + auto clientSecret = std::getenv("AZURE_CLIENT_SECRET"); + auto credential + = std::make_shared(tenantId, clientId, clientSecret); + + // create client + SettingsClient settingsClient(std::getenv("AZURE_KEYVAULT_HSM_URL"), credential); +``` +Please note that we are using the HSM URL, not the keyvault URL. + +To get the settings we will call the GetSettings API + +```CPP + // Get all settings + SettingsListResult settingsList = settingsClient.GetSettings().Value; +``` + +#### GetSetting + +To get a specific setting we will call the GetSetting API bassing the setting name as a string parameter. + +```CPP + Setting setting = settingsClient.GetSetting(settingsList.Value[0].Name).Value; +``` + +#### UpdateSetting + +To update the value of any of the the available settings, we will call the UpdateSettings API as follows: +```CPP + UpdateSettingOptions options; + options.Value = ; + +Setting updatedSetting + = settingsClient.UpdateSetting(settingsList.Value[0].Name, options).Value; +``` ## Contributing For details on contributing to this repository, see the [contributing guide][azure_sdk_for_cpp_contributing]. @@ -47,4 +174,9 @@ Azure SDK for C++ is licensed under the [MIT](https://github.com/Azure/azure-sdk [azure_sub]: https://azure.microsoft.com/free/ [api_reference]: https://azure.github.io/azure-sdk-for-cpp/keyvault.html [administration_client_src]: https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/keyvault/azure-security-keyvault-administration -[keyvault_docs]: https://docs.microsoft.com/azure/key-vault/ \ No newline at end of file +[keyvault_docs]: https://docs.microsoft.com/azure/key-vault/ +[access_control]: https://learn.microsoft.com/azure/key-vault/managed-hsm/access-control +[access_policy]: https://learn.microsoft.com/azure/key-vault/general/assign-access-policy +[rbac_guide]: https://learn.microsoft.com/azure/key-vault/general/rbac-guide +[best_practices]: https://learn.microsoft.com/azure/key-vault/managed-hsm/best-practices +[built_in_roles]: https://learn.microsoft.com/azure/key-vault/managed-hsm/built-in-roles diff --git a/sdk/keyvault/azure-security-keyvault-administration/test/samples/sample1-basic-operations/sample1_administration.cpp b/sdk/keyvault/azure-security-keyvault-administration/test/samples/sample1-basic-operations/sample1_administration.cpp index 2deb47ada..d744145bd 100644 --- a/sdk/keyvault/azure-security-keyvault-administration/test/samples/sample1-basic-operations/sample1_administration.cpp +++ b/sdk/keyvault/azure-security-keyvault-administration/test/samples/sample1-basic-operations/sample1_administration.cpp @@ -40,11 +40,12 @@ int main() // Get all settings SettingsListResult settingsList = settingsClient.GetSettings().Value; - std::cout << "Number of settings found : " << settingsList.Value.size(); + std::cout << "Number of settings found : " << settingsList.Value.size() << std::endl; Setting setting = settingsClient.GetSetting(settingsList.Value[0].Name).Value; - std::cout << "Retrieved setting with name " << setting.Name << ", with value " << setting.Value; + std::cout << "Retrieved setting with name " << setting.Name << ", with value " << setting.Value + << std::endl; UpdateSettingOptions options; options.Value = setting.Value; @@ -53,7 +54,7 @@ int main() = settingsClient.UpdateSetting(settingsList.Value[0].Name, options).Value; std::cout << "Retrieved updated setting with name " << updatedSetting.Name << ", with value " - << updatedSetting.Value; + << updatedSetting.Value << std::endl; } catch (Azure::Core::Credentials::AuthenticationException const& e) { diff --git a/sdk/keyvault/azure-security-keyvault-administration/test/ut/settings_client_test.cpp b/sdk/keyvault/azure-security-keyvault-administration/test/ut/settings_client_test.cpp index 731b54cce..96ca975f9 100644 --- a/sdk/keyvault/azure-security-keyvault-administration/test/ut/settings_client_test.cpp +++ b/sdk/keyvault/azure-security-keyvault-administration/test/ut/settings_client_test.cpp @@ -22,13 +22,16 @@ TEST_F(SettingsClientTest, GetSettings) auto testName = ::testing::UnitTest::GetInstance()->current_test_info()->name(); EXPECT_EQ(testName, testName); CreateHSMClientForTest(); - // create certificate method contains all the checks - auto const& client = GetClientForTest(testName); - auto result = client.GetSettings(); - EXPECT_EQ(result.Value.Value.size(), 1); - auto setting = result.Value.Value[0]; - EXPECT_EQ(setting.Name, "AllowKeyManagementOperationsThroughARM"); - EXPECT_EQ(setting.Value, "false"); + if (m_keyVaultHsmUrl != m_keyVaultUrl) + { + // create certificate method contains all the checks + auto const& client = GetClientForTest(testName); + auto result = client.GetSettings(); + EXPECT_EQ(result.Value.Value.size(), 1); + auto setting = result.Value.Value[0]; + EXPECT_EQ(setting.Name, "AllowKeyManagementOperationsThroughARM"); + EXPECT_EQ(setting.Value, "false"); + } } TEST_F(SettingsClientTest, GetSetting) @@ -36,40 +39,46 @@ TEST_F(SettingsClientTest, GetSetting) auto testName = ::testing::UnitTest::GetInstance()->current_test_info()->name(); CreateHSMClientForTest(); // create certificate method contains all the checks - auto const& client = GetClientForTest(testName); - auto result = client.GetSetting("AllowKeyManagementOperationsThroughARM"); - EXPECT_EQ(result.Value.Name, "AllowKeyManagementOperationsThroughARM"); - EXPECT_EQ(result.Value.Value, "false"); + if (m_keyVaultHsmUrl != m_keyVaultUrl) + { + auto const& client = GetClientForTest(testName); + auto result = client.GetSetting("AllowKeyManagementOperationsThroughARM"); + EXPECT_EQ(result.Value.Name, "AllowKeyManagementOperationsThroughARM"); + EXPECT_EQ(result.Value.Value, "false"); + } } TEST_F(SettingsClientTest, UpdateSetting) { auto testName = ::testing::UnitTest::GetInstance()->current_test_info()->name(); CreateHSMClientForTest(); - // create certificate method contains all the checks - auto const& client = GetClientForTest(testName); + if (m_keyVaultHsmUrl != m_keyVaultUrl) { - UpdateSettingOptions options; - options.Value = "false"; - auto result = client.UpdateSetting("AllowKeyManagementOperationsThroughARM", options); + // create certificate method contains all the checks + auto const& client = GetClientForTest(testName); + { + UpdateSettingOptions options; + options.Value = "false"; + auto result = client.UpdateSetting("AllowKeyManagementOperationsThroughARM", options); - EXPECT_EQ(result.Value.Name, "AllowKeyManagementOperationsThroughARM"); - EXPECT_EQ(result.Value.Value, "false"); - } - { - UpdateSettingOptions options; - options.Value = "true"; - auto result = client.UpdateSetting("AllowKeyManagementOperationsThroughARM", options); + EXPECT_EQ(result.Value.Name, "AllowKeyManagementOperationsThroughARM"); + EXPECT_EQ(result.Value.Value, "false"); + } + { + UpdateSettingOptions options; + options.Value = "true"; + auto result = client.UpdateSetting("AllowKeyManagementOperationsThroughARM", options); - EXPECT_EQ(result.Value.Name, "AllowKeyManagementOperationsThroughARM"); - EXPECT_EQ(result.Value.Value, "true"); - } - { - UpdateSettingOptions options; - options.Value = "false"; - auto result = client.UpdateSetting("AllowKeyManagementOperationsThroughARM", options); + EXPECT_EQ(result.Value.Name, "AllowKeyManagementOperationsThroughARM"); + EXPECT_EQ(result.Value.Value, "true"); + } + { + UpdateSettingOptions options; + options.Value = "false"; + auto result = client.UpdateSetting("AllowKeyManagementOperationsThroughARM", options); - EXPECT_EQ(result.Value.Name, "AllowKeyManagementOperationsThroughARM"); - EXPECT_EQ(result.Value.Value, "false"); + EXPECT_EQ(result.Value.Name, "AllowKeyManagementOperationsThroughARM"); + EXPECT_EQ(result.Value.Value, "false"); + } } } diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/ut/key_client_create_test_live.cpp b/sdk/keyvault/azure-security-keyvault-keys/test/ut/key_client_create_test_live.cpp index 0fa92130a..5cb035b1b 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/test/ut/key_client_create_test_live.cpp +++ b/sdk/keyvault/azure-security-keyvault-keys/test/ut/key_client_create_test_live.cpp @@ -270,7 +270,7 @@ TEST_F(KeyVaultKeyClient, CreateKeyWithReleasePolicyOptions) "equals":"0123456789" } ], - "authority":"https://sharedeus.eus.test.attest.azure.net/" + "authority":"https://sharedeus.eus.attest.azure.net" } ], "version":"1.0.0"