# SkillPatch skill: azure-keyvault-certificates-rust

This skill guides an agent through managing X.509 certificates in Azure Key Vault using Rust. It covers installation, authentication, and core workflows including creating self-signed certificates via long-running operations (LRO), updating certificate properties, and using the official `azure_security_keyvault_certificates` crate.

You (the agent) were given this URL and asked to use this skill. This is a **public** skill — no SkillPatch account, API key, or prior setup is required. Two ways to use it:

**1. Use it right now** — the skill's complete file tree (SKILL.md + all reference files) is inlined below; read `SKILL.md` first, then follow it, consulting the other files as it directs.

**2. Install the exact package onto disk** (recommended if you can run a shell — this reproduces the skill byte-for-byte, including any binary assets that can't be inlined):

```bash
mkdir -p .claude/skills/azure-keyvault-certificates-rust
curl -sSL https://skillpatch.dev/install_skill/azure-keyvault-certificates-rust | tar -xz -C .claude/skills/
```

(`.claude/skills/` is Claude Code's convention; use whatever directory your agent loads skills from.)


---

## Skill files (1)

- `SKILL.md`


### `SKILL.md`

````markdown
---
name: azure-keyvault-certificates-rust
description: |
  Azure Key Vault Certificates library for Rust. Create, manage, and use X.509 certificates including self-signed and CA-issued.
  Triggers: "keyvault certificates rust", "CertificateClient rust", "create certificate rust", "self-signed certificate rust", "X.509 rust".
license: MIT
metadata:
  author: Microsoft
  package: azure_security_keyvault_certificates
---

# Azure Key Vault Certificates library for Rust

Manage X.509 certificates for TLS/SSL, code signing, and authentication.

Use this skill when:

- An app needs to create or manage X.509 certificates in Key Vault from Rust
- You need self-signed or CA-issued certificates
- You need long-running operations (LRO) for certificate issuance
- You need to sign data using a certificate's key

> **IMPORTANT:** Only use the official `azure_security_keyvault_certificates` crate published by the [azure-sdk](https://crates.io/users/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.

## Installation

```sh
cargo add azure_security_keyvault_certificates azure_identity tokio futures
```

> **Do not** add `azure_core` directly to `Cargo.toml`. It is re-exported by `azure_security_keyvault_certificates`.

## Environment Variables

```bash
AZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net/ # Required for all operations
```

## Authentication

```rust
use azure_identity::DeveloperToolsCredential;
use azure_security_keyvault_certificates::CertificateClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Local dev: DeveloperToolsCredential. Production: use ManagedIdentityCredential.
    let credential = DeveloperToolsCredential::new(None)?;
    let client = CertificateClient::new(
        "https://<vault-name>.vault.azure.net/",
        credential.clone(),
        None,
    )?;

    let cert = client
        .get_certificate("cert-name", None)
        .await?
        .into_model()?;
    println!("Certificate: {:?}", cert.id);
    Ok(())
}
```

## Core Workflow

### Create Self-Signed Certificate (LRO)

Creating a certificate is a long-running operation. `Poller<T>` implements `IntoFuture` — just `.await`:

```rust
use azure_security_keyvault_certificates::{
    models::{
        CertificateCreateParameters, IssuerParameters, SecretProperties,
        SubjectAlternativeNames, X509CertificateProperties,
    },
    ResourceExt,
};

let body = CertificateCreateParameters {
    certificate_policy: Some(Box::new(
        azure_security_keyvault_certificates::models::CertificatePolicy {
            issuer_parameters: Some(IssuerParameters {
                name: Some("Self".into()),
                ..Default::default()
            }),
            secret_properties: Some(SecretProperties {
                content_type: Some("application/x-pkcs12".into()),
                ..Default::default()
            }),
            x509_certificate_properties: Some(X509CertificateProperties {
                subject: Some("CN=example.com".into()),
                subject_alternative_names: Some(SubjectAlternativeNames {
                    dns_names: Some(vec!["example.com".into()]),
                    ..Default::default()
                }),
                ..Default::default()
            }),
            ..Default::default()
        },
    )),
    ..Default::default()
};

// Poller implements IntoFuture — await directly for completion
let cert = client
    .create_certificate("cert-name", body.try_into()?, None)?
    .await?
    .into_model()?;

println!(
    "Name: {:?}, Version: {:?}",
    cert.resource_id()?.name,
    cert.resource_id()?.version,
);
```

### Update Certificate Properties

```rust
use azure_security_keyvault_certificates::models::CertificateUpdateParameters;
use std::collections::HashMap;

#[allow(clippy::needless_update)]
let params = CertificateUpdateParameters {
    tags: Some(HashMap::from_iter(vec![("env".into(), "prod".into())])),
    ..Default::default()
};

client
    .update_certificate("cert-name", params.try_into()?, None)
    .await?
    .into_model()?;
```

### Delete Certificate

```rust
client.delete_certificate("cert-name", None).await?;
```

### List Certificates (Pagination)

`list_certificate_properties` returns a `Pager<T>` — iterate items directly:

```rust
use azure_security_keyvault_certificates::ResourceExt;
use futures::TryStreamExt as _;

let mut pager = client.list_certificate_properties(None)?;
while let Some(cert) = pager.try_next().await? {
    println!("Found: {}", cert.resource_id()?.name);
}
```

## Signing with a Certificate's Key

Certificates in Key Vault have an associated key. Use the Key Vault Keys SDK for crypto operations:

```rust
use azure_security_keyvault_keys::{
    models::{KeySignParameters, SignatureAlgorithm},
    KeyClient,
};

let key_client = KeyClient::new(
    "https://<vault-name>.vault.azure.net/",
    credential.clone(),
    None,
)?;

// Sign with the certificate's EC key
let digest = vec![0u8; 32]; // SHA-256 digest
let sign_params = KeySignParameters {
    algorithm: Some(SignatureAlgorithm::Es256),
    value: Some(digest),
    ..Default::default()
};

let result = key_client
    .sign("cert-name", "", sign_params.try_into()?, None)
    .await?
    .into_model()?;
println!("Signature: {:?}", result.result);
```

## Certificate Formats

| Format  | Content Type             | Use Case                            |
| ------- | ------------------------ | ----------------------------------- |
| PKCS#12 | `application/x-pkcs12`   | Bundled cert + private key          |
| PEM     | `application/x-pem-file` | Base64-encoded, common in Linux/web |

## RBAC Roles

For Entra ID auth, assign one of these roles:

| Role                             | Access                      |
| -------------------------------- | --------------------------- |
| `Key Vault Certificate User`     | Use certificates            |
| `Key Vault Certificates Officer` | Full certificate management |

## Best Practices

1. **Use `DeveloperToolsCredential`** for local dev, **`ManagedIdentityCredential`** for production — the Rust SDK does not have `DefaultAzureCredential`
2. **Never hardcode credentials** — use environment variables or managed identity
3. **Use `..Default::default()`** with `#[allow(clippy::needless_update)]` for model struct updates
4. **Use `ResourceExt`** to extract certificate name/version from IDs
5. **LROs** — `create_certificate` returns a `Poller`; just `.await` for completion (clients should rarely poll for status)
6. **Reuse clients** — `CertificateClient` is thread-safe; create once, share across tasks

## Reference Links

| Resource      | Link                                                          |
| ------------- | ------------------------------------------------------------- |
| API Reference | https://docs.rs/azure_security_keyvault_certificates          |
| crates.io     | https://crates.io/crates/azure_security_keyvault_certificates |

````
