Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Azure Key Vault Keys library for Rust. Create, manage, and use cryptographic keys including RSA, EC, and HSM-protected keys. Triggers: "keyvault keys rust", "KeyClient rust", "create key rust", "encrypt rust", "wrap key rust", "sign rust".
.claude/skills/microsoft-azure-keyvault-keys-rust/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 19% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 25% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 47% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 60% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 25% | 0% |
Secure storage and management of cryptographic keys — RSA, EC, and HSM-protected.
Use this skill when:
> IMPORTANT: Only use the official azure_security_keyvault_keys crate published by the azure-sdk crates.io user. Do NOT use unofficial or community crates. Official crates use underscores in names and none have version 0.21.0.
shcargo add azure_security_keyvault_keys azure_identity tokio futures
> If your code uses azure_core types directly, add azure_core to Cargo.toml. If you only use azure_security_keyvault_keys re-exports, direct azure_core dependency is optional.
bashAZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net/ # Required for all operations
Rust Azure SDK code must not use DefaultAzureCredential. The Rust identity crate does not provide that type.
rustuse azure_identity::DeveloperToolsCredential; use azure_security_keyvault_keys::KeyClient; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { // Local dev: DeveloperToolsCredential. Production: use ManagedIdentityCredential. let credential = DeveloperToolsCredential::new(None)?; let client = KeyClient::new( "https://<vault-name>.vault.azure.net/", credential.clone(), None, )?; let key = client.get_key("key-name", None).await?.into_model()?; println!("Key: {:?}", key.key); Ok(()) }
Prefer the crate README/examples when checking public operation shapes such as key creation, wrapping, and version-aware unwrap flows.
rustuse azure_security_keyvault_keys::{ models::{CreateKeyParameters, CurveName, KeyType}, ResourceExt, }; // Create an EC key let body = CreateKeyParameters { kty: Some(KeyType::Ec), curve: Some(CurveName::P256), ..Default::default() }; let key = client .create_key("key-name", body.try_into()?, None) .await? .into_model()?; println!( "Name: {:?}, Type: {:?}, Version: {:?}", key.resource_id()?.name, key.key.as_ref().map(|k| k.kty.as_ref()), key.resource_id()?.version, );
rustuse azure_security_keyvault_keys::models::UpdateKeyPropertiesParameters; use std::collections::HashMap; #[allow(clippy::needless_update)] let params = UpdateKeyPropertiesParameters { tags: Some(HashMap::from_iter(vec![("env".into(), "prod".into())])), ..Default::default() }; client .update_key_properties("key-name", params.try_into()?, None) .await? .into_model()?;
rustclient.delete_key("key-name", None).await?;
list_key_properties returns a Pager<T> — iterate items directly:
rustuse azure_security_keyvault_keys::ResourceExt; use futures::TryStreamExt as _; let mut pager = client.list_key_properties(None)?; while let Some(key) = pager.try_next().await? { println!("Found: {}", key.resource_id()?.name); }
Key Vault performs crypto operations server-side — the private key never leaves the HSM:
rustuse azure_security_keyvault_keys::{ models::{ CreateKeyParameters, EncryptionAlgorithm, KeyOperationParameters, KeyType, }, ResourceExt, ResourceId, }; use rand::random; // Create a key encryption key (KEK) let body = CreateKeyParameters { kty: Some(KeyType::Rsa), key_size: Some(2048), ..Default::default() }; let key = client .create_key("kek-name", body.try_into()?, None) .await? .into_model()?; // Generate a symmetric data encryption key (DEK) let dek = random::<u32>().to_le_bytes().to_vec(); // Wrap the DEK with the KEK let mut params = KeyOperationParameters { algorithm: Some(EncryptionAlgorithm::RsaOaep256), value: Some(dek.clone()), ..Default::default() }; let wrapped = client .wrap_key("kek-name", params.clone().try_into()?, None) .await? .into_model()?; // Retain the key version used to wrap so you can unwrap with the same version later let ResourceId { version, .. } = wrapped.resource_id()?; let key_version = version.as_deref().unwrap_or_default(); // Unwrap to recover the DEK params.value = wrapped.result; let unwrapped = client .unwrap_key("kek-name", key_version, params.try_into()?, None) .await? .into_model()?; assert!(matches!(unwrapped.result, Some(ref result) if result.eq(&dek)));
| Type | Use Case | Parameter | | ------- | ----------------------------- | ----------------- | | EC | Signing, key agreement | KeyType::Ec | | RSA | Encryption, signing, wrapping | KeyType::Rsa | | Oct | Symmetric operations (HSM) | KeyType::Oct | | EC-HSM | HSM-protected EC keys | KeyType::EcHsm | | RSA-HSM | HSM-protected RSA keys | KeyType::RsaHsm |
For Entra ID auth, assign one of these roles:
| Role | Access | | -------------------------- | ----------------------- | | Key Vault Crypto User | Use keys for crypto ops | | Key Vault Crypto Officer | Full key management |
cargo add to manage dependencies, never edit Cargo.toml directly. Add and remove Rust SDK dependencies with cargo commands instead of manual manifest edits.azure_core only when importing azure_core types directly. If your code imports azure_core::http::Url, azure_core::http::RequestContent, or azure_core::error::ErrorKind, include azure_core; otherwise a direct dependency is optional.DeveloperToolsCredential for local dev, ManagedIdentityCredential for production — Rust does not provide a single DefaultAzureCredential type..Default::default() with #[allow(clippy::needless_update)] for model struct updatesResourceExt to extract key name/version from key IDsKeyClient is thread-safe; create once, share across taskscargo clippy -- -D warnings when the prompt, eval, or CI expects lint-clean output| Resource | Link | | ------------- | ----------------------------------------------------------------------------------------------- | | API Reference | https://docs.rs/azure_security_keyvault_keys/latest/azure_security_keyvault_keys | | crates.io | https://crates.io/crates/azure_security_keyvault_keys | | Source Code | https://github.com/Azure/azure-sdk-for-rust/tree/main/sdk/keyvault/azure_security_keyvault_keys |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 12,573 | 5,904 | -53% | 1 | 1 | 0% | 2,826 | 3,367 | +19% | 0 | 0 | — |
case-02 | fail→pass | 14,209 | 9,125 | -36% | 1 | 1 | 0% | 3,373 | 4,214 | +25% | 0 | 0 | — |
case-03 | fail→pass | 12,628 | 8,537 | -32% | 1 | 1 | 0% | 2,457 | 3,612 | +47% | 0 | 0 | — |
case-04 | pass→pass | 8,918 | 3,771 | -58% | 1 | 1 | 0% | 1,653 | 2,628 | +59% | 0 | 0 | — |
case-05 | fail→pass | 10,288 | 5,500 | -47% | 1 | 1 | 0% | 2,025 | 3,236 | +60% | 0 | 0 | — |
case-14 | pass→pass | 10,010 | 2,171 | -78% | 1 | 1 | 0% | 1,888 | 2,370 | +26% | 0 | 0 | — |
case-06 | pass→pass | 9,117 | 5,942 | -35% | 1 | 1 | 0% | 1,994 | 3,272 | +64% | 0 | 0 | — |
case-07 | fail→pass | 11,684 | 5,117 | -56% | 1 | 1 | 0% | 2,556 | 3,198 | +25% | 0 | 0 | — |
case-08 | fail→pass | 7,643 | 3,750 | -51% | 1 | 1 | 0% | 1,579 | 2,776 | +76% | 0 | 0 | — |
case-09 | pass→pass | 10,917 | 4,980 | -54% | 1 | 1 | 0% | 2,336 | 3,136 | +34% | 0 | 0 | — |
case-10 | fail→pass | 11,057 | 5,972 | -46% | 1 | 1 | 0% | 2,471 | 3,389 | +37% | 0 | 0 | — |
case-11 | pass→pass | 9,041 | 3,393 | -62% | 1 | 1 | 0% | 1,568 | 2,716 | +73% | 0 | 0 | — |
case-12 | fail→fail | 9,185 | 2,929 | -68% | 1 | 1 | 0% | 1,767 | 2,499 | +41% | 0 | 0 | — |
case-13 | pass→pass | 5,748 | 2,356 | -59% | 1 | 1 | 0% | 1,135 | 2,403 | +112% | 0 | 0 | — |
case-15 | pass→pass | 5,704 | 2,100 | -63% | 1 | 1 | 0% | 1,128 | 2,365 | +110% | 0 | 0 | — |
case-16 | fail→pass | 13,219 | 3,962 | -70% | 1 | 1 | 0% | 2,575 | 2,800 | +9% | 0 | 0 | — |
case-17 | pass→pass | 7,278 | 1,615 | -78% | 1 | 1 | 0% | 1,193 | 2,210 | +85% | 0 | 0 | — |
case-18 | pass→pass | 10,946 | 3,947 | -64% | 1 | 1 | 0% | 1,955 | 2,725 | +39% | 0 | 0 | — |
case-19 | pass→pass | 6,953 | 2,148 | -69% | 1 | 1 | 0% | 1,409 | 2,261 | +60% | 0 | 0 | — |
case-20 | fail→pass | 7,192 | 5,718 | -20% | 1 | 1 | 0% | 1,623 | 3,229 | +99% | 0 | 0 | — |
case-21 | pass→pass | 5,372 | 5,104 | -5% | 1 | 1 | 0% | 1,131 | 3,008 | +166% | 0 | 0 | — |
case-22 | pass→pass | 8,479 | 7,771 | -8% | 1 | 1 | 0% | 1,925 | 3,733 | +94% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +41 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.