llm_shield_cloud_azure/
lib.rs

1//! Azure cloud integrations for LLM Shield.
2//!
3//! This crate provides Azure-specific implementations of the cloud abstraction traits
4//! defined in `llm-shield-cloud`:
5//!
6//! - **Secret Management**: Azure Key Vault via `AzureKeyVault`
7//! - **Object Storage**: Azure Blob Storage via `AzureBlobStorage`
8//! - **Metrics**: Azure Monitor Metrics via `AzureMonitorMetrics`
9//! - **Logging**: Azure Monitor Logs via `AzureMonitorLogs`
10//!
11//! # Features
12//!
13//! - Automatic credential discovery (env, Azure CLI, managed identity)
14//! - Built-in caching for secrets (TTL-based)
15//! - Block blob uploads for large objects (>4MB)
16//! - Batched metrics and log export for efficiency
17//! - Full support for Azure retry and timeout policies
18//!
19//! # Architecture
20//!
21//! ```text
22//! ┌─────────────────────────────────────┐
23//! │   LLM Shield Application            │
24//! └─────────────────────────────────────┘
25//!                 │
26//!                 ▼
27//! ┌─────────────────────────────────────┐
28//! │   llm-shield-cloud (traits)         │
29//! │   - CloudSecretManager              │
30//! │   - CloudStorage                    │
31//! │   - CloudMetrics/Logger             │
32//! └─────────────────────────────────────┘
33//!                 │
34//!                 ▼
35//! ┌─────────────────────────────────────┐
36//! │   llm-shield-cloud-azure (impl)     │
37//! │   - AzureKeyVault                   │
38//! │   - AzureBlobStorage                │
39//! │   - AzureMonitorMetrics/Logs        │
40//! └─────────────────────────────────────┘
41//!                 │
42//!                 ▼
43//! ┌─────────────────────────────────────┐
44//! │   Azure Services                    │
45//! │   - Key Vault                       │
46//! │   - Blob Storage                    │
47//! │   - Azure Monitor                   │
48//! └─────────────────────────────────────┘
49//! ```
50//!
51//! # Usage Examples
52//!
53//! ## Secret Management
54//!
55//! ```no_run
56//! use llm_shield_cloud_azure::AzureKeyVault;
57//! use llm_shield_cloud::CloudSecretManager;
58//!
59//! #[tokio::main]
60//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
61//!     // Initialize with vault URL
62//!     let vault = AzureKeyVault::new("https://my-vault.vault.azure.net").await?;
63//!
64//!     // Fetch a secret (automatically cached for 5 minutes)
65//!     let api_key = vault.get_secret("openai-api-key").await?;
66//!     println!("API Key: {}", api_key.as_string());
67//!
68//!     // List all secrets
69//!     let secret_names = vault.list_secrets().await?;
70//!     println!("Found {} secrets", secret_names.len());
71//!
72//!     Ok(())
73//! }
74//! ```
75//!
76//! ## Object Storage
77//!
78//! ```no_run
79//! use llm_shield_cloud_azure::AzureBlobStorage;
80//! use llm_shield_cloud::{CloudStorage, PutObjectOptions};
81//!
82//! #[tokio::main]
83//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
84//!     let storage = AzureBlobStorage::new(
85//!         "mystorageaccount",
86//!         "models"
87//!     ).await?;
88//!
89//!     // Upload a model (automatically uses block blobs for files >4MB)
90//!     let model_data = tokio::fs::read("toxicity-model.onnx").await?;
91//!     storage.put_object("toxicity.onnx", &model_data).await?;
92//!
93//!     // Upload with options
94//!     let options = PutObjectOptions {
95//!         content_type: Some("application/octet-stream".to_string()),
96//!         ..Default::default()
97//!     };
98//!     storage.put_object_with_options("model.onnx", &model_data, &options).await?;
99//!
100//!     // Download and verify
101//!     let downloaded = storage.get_object("toxicity.onnx").await?;
102//!     assert_eq!(model_data, downloaded);
103//!
104//!     Ok(())
105//! }
106//! ```
107//!
108//! ## Metrics
109//!
110//! ```no_run
111//! use llm_shield_cloud_azure::AzureMonitorMetrics;
112//! use llm_shield_cloud::{CloudMetrics, Metric};
113//! use std::collections::HashMap;
114//!
115//! #[tokio::main]
116//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
117//!     let metrics = AzureMonitorMetrics::new(
118//!         "/subscriptions/sub-id/resourceGroups/rg/providers/...",
119//!         "eastus"
120//!     ).await?;
121//!
122//!     let mut dimensions = HashMap::new();
123//!     dimensions.insert("environment".to_string(), "production".to_string());
124//!
125//!     let metric = Metric {
126//!         name: "scan_duration".to_string(),
127//!         value: 123.45,
128//!         timestamp: std::time::SystemTime::now()
129//!             .duration_since(std::time::UNIX_EPOCH)?
130//!             .as_secs(),
131//!         dimensions,
132//!         unit: Some("Milliseconds".to_string()),
133//!     };
134//!
135//!     metrics.export_metric(&metric).await?;
136//!
137//!     Ok(())
138//! }
139//! ```
140//!
141//! ## Logging
142//!
143//! ```no_run
144//! use llm_shield_cloud_azure::AzureMonitorLogs;
145//! use llm_shield_cloud::{CloudLogger, LogLevel, LogEntry};
146//! use std::collections::HashMap;
147//!
148//! #[tokio::main]
149//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
150//!     let logger = AzureMonitorLogs::new(
151//!         "workspace-id",
152//!         "shared-key",
153//!         "LLMShieldLog"
154//!     ).await?;
155//!
156//!     // Simple logging
157//!     logger.log("API server started", LogLevel::Info).await?;
158//!
159//!     // Structured logging
160//!     let mut labels = HashMap::new();
161//!     labels.insert("request_id".to_string(), "req-123".to_string());
162//!
163//!     let entry = LogEntry {
164//!         timestamp: std::time::SystemTime::now(),
165//!         level: LogLevel::Info,
166//!         message: "Request processed successfully".to_string(),
167//!         labels,
168//!         trace_id: Some("trace-789".to_string()),
169//!         span_id: Some("span-012".to_string()),
170//!     };
171//!
172//!     logger.log_structured(&entry).await?;
173//!
174//!     Ok(())
175//! }
176//! ```
177//!
178//! # Azure Credentials
179//!
180//! This crate uses DefaultAzureCredential which tries:
181//!
182//! 1. **Environment variables**: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET
183//! 2. **Azure CLI**: `az login` credentials
184//! 3. **Managed Identity**: For Azure VMs, App Service, Container Apps, etc.
185//!
186//! # RBAC Permissions
187//!
188//! Required Azure RBAC permissions are documented in `rbac-roles/` directory:
189//!
190//! - `key-vault-role.json`: Key Vault permissions
191//! - `storage-role.json`: Blob Storage permissions
192//! - `monitor-role.json`: Azure Monitor permissions
193//!
194//! # Configuration
195//!
196//! Configure Azure integrations via `CloudConfig`:
197//!
198//! ```yaml
199//! cloud:
200//!   provider: azure
201//!   azure:
202//!     key_vault:
203//!       vault_url: https://my-vault.vault.azure.net
204//!       cache_ttl_seconds: 300
205//!     storage:
206//!       account_name: mystorageaccount
207//!       container_name: models
208//!     monitor:
209//!       workspace_id: workspace-id
210//!       log_type: LLMShieldLog
211//! ```
212//!
213//! # Performance
214//!
215//! - **Secret caching**: >90% cache hit rate reduces API calls
216//! - **Block blob uploads**: Automatically used for objects >4MB
217//! - **Batch export**: Metrics (20/batch) and logs (100/batch)
218//! - **Async operations**: All I/O is fully asynchronous with tokio
219//!
220//! # Testing
221//!
222//! Run unit tests:
223//!
224//! ```bash
225//! cargo test -p llm-shield-cloud-azure
226//! ```
227//!
228//! # License
229//!
230//! MIT OR Apache-2.0
231
232// Stub implementations due to SDK breaking changes
233// TODO: Update to latest Azure SDK APIs
234pub mod observability_stub;
235pub mod secrets_stub;
236pub mod storage_stub;
237
238// Re-export main types
239pub use observability_stub::{AzureMonitor, AzureAppInsights};
240pub use secrets_stub::AzureKeyVault;
241pub use storage_stub::AzureBlobStorage;
242
243// Keep original modules but don't compile them
244// #[cfg(feature = "azure-full-impl")]
245// pub mod observability;
246// #[cfg(feature = "azure-full-impl")]
247// pub mod secrets;
248// #[cfg(feature = "azure-full-impl")]
249// pub mod storage;
250
251// Re-export cloud abstractions for convenience
252pub use llm_shield_cloud::{
253    CloudError, CloudLogger, CloudMetrics, CloudSecretManager, CloudStorage, GetObjectOptions,
254    LogEntry, LogLevel, Metric, ObjectMetadata, PutObjectOptions, Result, SecretMetadata,
255    SecretValue,
256};
257
258/// Crate version
259pub const VERSION: &str = env!("CARGO_PKG_VERSION");
260
261/// Crate name
262pub const LIB_NAME: &str = env!("CARGO_PKG_NAME");
263
264#[cfg(test)]
265mod tests {
266    use super::*;
267
268    #[test]
269    fn test_version() {
270        assert!(!VERSION.is_empty());
271        assert_eq!(LIB_NAME, "llm-shield-cloud-azure");
272    }
273}