1 unstable release
new 0.1.0 | Feb 19, 2025 |
---|
#1245 in Network programming
Used in akv-cli
345KB
6.5K
SLoC
Azure Key Vault secrets client library for Rust
Azure Key Vault is a cloud service that provides a secure storage of secrets, such as passwords and database connection strings.
The Azure Key Vault secrets client library allows you to securely store and control the access to tokens, passwords, API keys, and other secrets. This library offers operations to create, retrieve, update, delete, purge, backup, restore, and list the secrets and its versions.
Source code | Package (crates.io) | API reference documentation | Product documentation
Getting started
Install the package
Install the Azure Key Vault secrets client library for Rust with Cargo:
cargo add azure_security_keyvault_secrets
Prerequisites
- An Azure subscription.
- An existing Azure Key Vault. If you need to create an Azure Key Vault, you can use the Azure Portal or Azure CLI.
- Authorization to an existing Azure Key Vault using either RBAC (recommended) or access control.
If you use the Azure CLI, replace <your-resource-group-name>
and <your-key-vault-name>
with your own, unique names:
az keyvault create --resource-group <your-resource-group-name> --name <your-key-vault-name>
Install dependencies
Add the following crates to your project:
cargo add azure_identity tokio
Authenticate the client
In order to interact with the Azure Key Vault service, you'll need to create an instance of the SecretClient
. You need a vault url, which you may see as "DNS Name" in the portal, and credentials to instantiate a client object.
The example shown below use a DefaultAzureCredential
, which is appropriate for most local development environments. Additionally, we recommend using a managed identity for authentication in production environments. You can find more information on different ways of authenticating and their corresponding credential types in the Azure Identity documentation.
The DefaultAzureCredential
will automatically pick up on an Azure CLI authentication. Ensure you are logged in with the Azure CLI:
az login
Instantiate a DefaultAzureCredential
to pass to the client. The same instance of a token credential can be used with multiple clients if they will be authenticating with the same identity.
Set and Get a Secret
use azure_identity::DefaultAzureCredential;
use azure_security_keyvault_secrets::{
models::{SecretBundle, SecretSetParameters},
ResourceExt, SecretClient,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a new secret client
let credential = DefaultAzureCredential::new()?;
let client = SecretClient::new(
"https://your-key-vault-name.vault.azure.net/",
credential.clone(),
None,
)?;
// Create a new secret using the secret client.
let secret_set_parameters = SecretSetParameters {
value: Some("secret-value".into()),
..Default::default()
};
let secret: SecretBundle = client
.set_secret("secret-name", secret_set_parameters.try_into()?, None)
.await?
.into_body()
.await?;
// Get version of created secret.
let version = secret.resource_id()?.version.unwrap_or_default();
// Retrieve a secret using the secret client.
let secret: SecretBundle = client
.get_secret("secret-name", version.as_ref(), None)
.await?
.into_body()
.await?;
println!("{:?}", secret.value);
Ok(())
}
Key concepts
SecretBundle
A SecretBundle
is the fundamental resource within Azure Key Vault. From a developer's perspective, Azure Key Vault APIs accept and return secret values as strings.
SecretClient
The SecretClient
provides asynchronous operations for working with Key Vault secrets.
Thread safety
We guarantee that all client instance methods are thread-safe and independent of each other. This ensures that the recommendation of reusing client instances is always safe, even across threads.
Examples
The following section provides several code snippets using the SecretClient
, covering some of the most common Azure Key Vault secrets service related tasks:
Create a secret
set_secret
creates a Key Vault secret to be stored in the Azure Key Vault. If a secret with the same name already exists, then a new version of the secret is created.
use azure_identity::DefaultAzureCredential;
use azure_security_keyvault_secrets::{models::SecretSetParameters, ResourceExt, SecretClient};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let credential = DefaultAzureCredential::new()?;
let client = SecretClient::new(
"https://your-key-vault-name.vault.azure.net/",
credential.clone(),
None,
)?;
// Create a new secret using the secret client.
let secret_set_parameters = SecretSetParameters {
value: Some("secret-value".into()),
..Default::default()
};
let secret = client
.set_secret("secret-name", secret_set_parameters.try_into()?, None)
.await?
.into_body()
.await?;
println!(
"Secret Name: {:?}, Value: {:?}, Version: {:?}",
secret.resource_id()?.name,
secret.value,
secret.resource_id()?.version
);
Ok(())
}
Retrieve a secret
get_secret
retrieves a secret previously stored in the Azure Key Vault. Setting the secret-version
to an empty string will return the latest version.
use azure_identity::DefaultAzureCredential;
use azure_security_keyvault_secrets::SecretClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let credential = DefaultAzureCredential::new()?;
let client = SecretClient::new(
"https://your-key-vault-name.vault.azure.net/",
credential.clone(),
None,
)?;
// Retrieve a secret using the secret client.
let secret = client
.get_secret("secret-name", "secret-version", None)
.await?
.into_body()
.await?;
println!("Secret Value: {:?}", secret.value);
Ok(())
}
Update an existing secret
update_secret
updates a secret previously stored in the Azure Key Vault. Only the attributes of the secret are updated. To update the value, call SecretClient::set_secret
on a secret with the same name.
use azure_identity::DefaultAzureCredential;
use azure_security_keyvault_secrets::{models::SecretUpdateParameters, SecretClient};
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let credential = DefaultAzureCredential::new()?;
let client = SecretClient::new(
"https://your-key-vault-name.vault.azure.net/",
credential.clone(),
None,
)?;
// Update a secret using the secret client.
let secret_update_parameters = SecretUpdateParameters {
content_type: Some("text/plain".into()),
tags: Some(HashMap::from_iter(vec![(
"tag-name".into(),
"tag-value".into(),
)])),
..Default::default()
};
client
.update_secret(
"secret-name",
"",
secret_update_parameters.try_into()?,
None,
)
.await?
.into_body()
.await?;
Ok(())
}
Delete a secret
delete_secret
will tell Key Vault to delete a secret but it is not deleted immediately. It will not be deleted until the service-configured data retention period - the default is 90 days - or until you call purge_secret
on the returned DeletedSecretBundle.id
.
use azure_identity::DefaultAzureCredential;
use azure_security_keyvault_secrets::SecretClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let credential = DefaultAzureCredential::new()?;
let client = SecretClient::new(
"https://your-key-vault-name.vault.azure.net/",
credential.clone(),
None,
)?;
// Delete a secret using the secret client.
client.delete_secret("secret-name", None).await?;
Ok(())
}
List secrets
This example lists all the secrets in the specified Azure Key Vault. The value is not returned when listing all secrets. You will need to call SecretClient::get_secret
to retrieve the value.
use azure_identity::DefaultAzureCredential;
use azure_security_keyvault_secrets::{ResourceExt, SecretClient};
use futures::TryStreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a new secret client
let credential = DefaultAzureCredential::new()?;
let client = SecretClient::new(
"https://your-key-vault-name.vault.azure.net/",
credential.clone(),
None,
)?;
let mut pager = client.get_secrets(None)?.into_stream();
while let Some(secrets) = pager.try_next().await? {
let Some(secrets) = secrets.into_body().await?.value else {
continue;
};
for secret in secrets {
// Get the secret name from the ID.
let name = secret.resource_id()?.name;
println!("Found Secret with Name: {}", name);
}
}
Ok(())
}
Troubleshooting
General
When you interact with the Azure Key Vault secrets client library using the Rust SDK, errors returned by the service correspond to the same HTTP status codes returned for REST API requests.
For example, if you try to retrieve a secret that doesn't exist in your Azure Key Vault, a 404
error is returned, indicating Not Found
.
use azure_identity::DefaultAzureCredential;
use azure_security_keyvault_secrets::SecretClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let credential = DefaultAzureCredential::new()?;
let client = SecretClient::new(
"https://ronnieg-keyvault.vault.azure.net/",
credential.clone(),
None,
)?;
match client.get_secret("secret-name", "", None).await {
Ok(response) => println!("Secret Value: {:?}", response.into_body().await?.value),
Err(err) => println!("Error: {:#?}", err.into_inner()?),
}
Ok(())
}
You will notice that additional information is logged, like the Client Request ID of the operation.
Error: HttpError {
status: NotFound,
details: ErrorDetails {
code: Some(
"SecretNotFound",
),
message: Some(
"A secret with (name/id) secret-name1 was not found in this key vault. If you recently deleted this secret you may be able to recover it using the correct recovery command. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125182",
),
},
..
}
Contributing
See the CONTRIBUTING.md for details on building, testing, and contributing to these libraries.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://opensource.microsoft.com/cla/.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
Dependencies
~14–26MB
~383K SLoC