🔐

NutriCore Analytics — Azure Key Vault Manager

Gestión de claves criptográficas para cumplimiento RGPD · Rust + azure_security_keyvault_keys

Azure Key Vault Rust RGPD Art. 32
Crates oficiales
4
azure_security_keyvault_keys · azure_identity · tokio · futures
Tenants activos
4
KEK HSM RSA-2048 por clínica
Operaciones cripto
6
crear · listar · cifrar · firmar · rotar · eliminar

Arquitectura de Cifrado — Envelope Encryption por Tenant

🏥
Clínica
tenant-001
solicitud
🦀
NutriCore
Rust backend
DEK aleatorio
🔑
Azure KV HSM
wrap_key()
DEK cifrado
🗄️
PostgreSQL
dek_cifrado+datos
informe firmado
👨‍⚕️
Médico
ES256 + KEK

Autenticación y Creación de KEK

keyvault_manager.rs Rust
// Producción: ManagedIdentityCredential // Local dev: DeveloperToolsCredential pub fn new_production() -> Result<Self> { let credential = ManagedIdentityCredential::new(None)?; let client = KeyClient::new( "https://nutricore-prod.vault.azure.net/", credential, None )?; Ok(Self { client }) } // Crear KEK RSA-HSM para nueva clínica let params = CreateKeyParameters { kty: Some(KeyType::RsaHsm), key_size: Some(2048), key_ops: Some(vec![ JsonWebKeyOperation::WrapKey, JsonWebKeyOperation::UnwrapKey, ]), tags: Some(HashMap::from_iter([ ("tenant".into(), tenant_id.into()), ("cumplimiento".into(), "RGPD-Art32".into()), ])), ..Default::default() }; client.create_key(&name, params.try_into()?, None).await?.into_model()?;

Envelope Encryption — Datos de Pacientes

wrap_patient_dek() Rust
// 1. DEK generado localmente (32B AES-256) let dek: [u8; 32] = rand::random(); // 2. Cifrar DEK con KEK en Azure HSM // → clave privada NUNCA sale del HSM let params = KeyOperationParameters { algorithm: Some( EncryptionAlgorithm::RsaOaep256 ), value: Some(dek.to_vec()), ..Default::default() }; let wrapped = client .wrap_key(&kek_name, &kek_version, params.try_into()?, None) .await?.into_model()?; // 3. Almacenar en PostgreSQL: // dek_cifrado = wrapped.result // kek_version = "abc123..." // datos = AES-256-GCM(dek, plaintext) // 4. Descifrar para lectura autorizada let dek_plain = client .unwrap_key(&kek_name, &kek_version, wrapped.try_into()?, None) .await?.into_model()?;

Firma Digital de Informes Nutricionales

sign_report() — EC P-256 Rust
// Clave de firma EC P-256 (creación única) let params = CreateKeyParameters { kty: Some(KeyType::Ec), curve: Some(CurveName::P256), key_ops: Some(vec![ JsonWebKeyOperation::Sign, JsonWebKeyOperation::Verify, ]), ..Default::default() }; // Firmar hash SHA-256 del informe (32B) let params = SignParameters { algorithm: Some( SignatureAlgorithm::Es256 ), value: Some(report_hash.to_vec()), ..Default::default() }; let sig = client .sign("signing-key-nutricore", &key_version, params.try_into()?, None) .await?.into_model()?; // sig.result = 64 bytes firma ES256

Tenants Activos (KEKs en Vault)

🏥
Clínica Mediterráneo
kek-clinica-mediterraneo-001 · v2 · RSA-HSM-2048
🏨
Hospital San Carlos
kek-hospital-san-carlos · v1 · RSA-HSM-2048
🥗
Centro Nutricional Bilbao
kek-centro-nutricional-bilbao · v1 · RSA-HSM-2048
🌊
Clínica Marbella Wellness
kek-clinica-marbella-wellness · v1 · RSA-HSM-2048

API — Operaciones implementadas en NutricoreKeyManager

Método Tipo de clave Operación Azure KV Caso de uso
create_tenant_kek(tenant_id) KEK create_key → RSA-HSM-2048 Alta de nueva clínica en la plataforma
rotate_tenant_kek(tenant_id) KEK create_key (nueva versión) Rotación anual obligatoria RGPD
delete_tenant_kek(tenant_id) KEK delete_key (soft-delete 90d) Baja de clínica, purga manual posterior
list_tenant_keks() Meta list_key_properties → Pager Auditoría de tenants activos
wrap_patient_dek(tenant, ver, dek) Cifrado wrap_key → RSA-OAEP-256 Ingreso de paciente, cifrar DEK
unwrap_patient_dek(tenant, ver, ct) Cifrado unwrap_key → RSA-OAEP-256 Lectura autorizada por médico
create_signing_key() Firma create_key → EC P-256 Setup inicial de la plataforma
sign_report(ver, hash_32b) Firma sign → ES256 (64 bytes) Firma de informes nutricionales
update_key_tags(name, tags) Meta update_key_properties Actualizar metadatos de auditoría

RBAC — Roles Entra ID asignados

Crypto User
App principal (AKS)
wrap unwrap sign verify
Crypto Officer
Admin CI/CD
crear rotar eliminar listar
Reader
SIEM / Auditoría
listar get

Mejores prácticas implementadas

1
ManagedIdentityCredential en producción, DeveloperToolsCredential en local. El SDK Rust no soporta DefaultAzureCredential.
2
KeyClient es thread-safe; se crea una sola instancia y se comparte con Arc<NutricoreKeyManager> entre tareas Tokio.
3
La clave privada nunca sale del HSM. Las ops cripto se ejecutan server-side; solo viajan el DEK cifrado y la firma.
4
Versionado de KEK almacenado en BD junto al dek_cifrado, permitiendo rotación sin romper acceso a datos históricos.