aura_core/effects/biometric.rs
1//! Biometric Authentication Effects Trait Definitions
2//!
3//! This module defines trait interfaces for biometric authentication operations
4//! that interface with platform-specific biometric APIs (TouchID, FaceID,
5//! Windows Hello, fingerprint scanners, etc.).
6//!
7//! # Effect Classification
8//!
9//! - **Category**: Infrastructure Effect
10//! - **Implementation**: `aura-effects` (Layer 3)
11//! - **Usage**: Platform-specific biometric APIs for authentication
12//!
13//! This is an infrastructure effect that provides OS-level biometric integration
14//! with no Aura-specific semantics. Implementations should interface with platform
15//! biometric APIs and provide software fallback for testing environments.
16//!
17//! ## Security Model
18//!
19//! Biometric authentication provides:
20//! - Hardware-backed biometric verification
21//! - Template storage in secure enclaves
22//! - Liveness detection to prevent spoofing
23//! - Privacy-preserving matching (templates never leave device)
24//!
25//! ## Platform Support
26//!
27//! - iOS: Touch ID, Face ID via LocalAuthentication framework
28//! - Android: Fingerprint, Face unlock via BiometricPrompt API
29//! - Windows: Windows Hello (fingerprint, face, iris)
30//! - macOS: Touch ID via LocalAuthentication framework
31//! - Linux: Fingerprint readers via libfprint
32
33use crate::AuraError;
34use async_trait::async_trait;
35use serde::{Deserialize, Serialize};
36
37/// Biometric authentication operation error
38pub type BiometricError = AuraError;
39
40/// Types of biometric authentication supported
41#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
42pub enum BiometricType {
43 /// Fingerprint recognition
44 Fingerprint,
45 /// Face recognition
46 Face,
47 /// Iris recognition
48 Iris,
49 /// Voice recognition
50 Voice,
51 /// Palm print recognition
52 PalmPrint,
53 /// Behavioral biometrics (typing patterns, etc.)
54 Behavioral,
55}
56
57impl BiometricType {
58 /// Get human-readable name for the biometric type
59 pub fn display_name(&self) -> &'static str {
60 match self {
61 BiometricType::Fingerprint => "Fingerprint",
62 BiometricType::Face => "Face ID",
63 BiometricType::Iris => "Iris",
64 BiometricType::Voice => "Voice",
65 BiometricType::PalmPrint => "Palm Print",
66 BiometricType::Behavioral => "Behavioral",
67 }
68 }
69
70 /// Get recommended security level for this biometric type
71 pub fn security_level(&self) -> BiometricSecurityLevel {
72 match self {
73 BiometricType::Fingerprint => BiometricSecurityLevel::High,
74 BiometricType::Face => BiometricSecurityLevel::High,
75 BiometricType::Iris => BiometricSecurityLevel::VeryHigh,
76 BiometricType::Voice => BiometricSecurityLevel::Medium,
77 BiometricType::PalmPrint => BiometricSecurityLevel::High,
78 BiometricType::Behavioral => BiometricSecurityLevel::Low,
79 }
80 }
81}
82
83/// Security level classification for biometric authentication
84#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
85pub enum BiometricSecurityLevel {
86 /// Low security (e.g., behavioral biometrics)
87 Low,
88 /// Medium security (e.g., voice recognition)
89 Medium,
90 /// High security (e.g., fingerprint, face)
91 High,
92 /// Very high security (e.g., iris recognition)
93 VeryHigh,
94}
95
96/// Configuration for biometric enrollment and verification
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct BiometricConfig {
99 /// Biometric type to configure
100 pub biometric_type: BiometricType,
101 /// Require liveness detection during verification
102 pub liveness_detection: bool,
103 /// Allow fallback to alternative authentication if biometric fails
104 pub allow_fallback: bool,
105 /// Timeout for biometric capture (milliseconds)
106 pub capture_timeout_ms: u32,
107 /// Number of retry attempts allowed
108 pub max_retry_attempts: u32,
109 /// Minimum quality threshold (0.0 to 1.0)
110 pub minimum_quality: f32,
111}
112
113impl BiometricConfig {
114 /// Create a high-security configuration for the given biometric type
115 pub fn high_security(biometric_type: BiometricType) -> Self {
116 Self {
117 biometric_type,
118 liveness_detection: true,
119 allow_fallback: false,
120 capture_timeout_ms: 10000, // 10 seconds
121 max_retry_attempts: 3,
122 minimum_quality: 0.8,
123 }
124 }
125
126 /// Create a balanced configuration for the given biometric type
127 pub fn balanced(biometric_type: BiometricType) -> Self {
128 Self {
129 biometric_type,
130 liveness_detection: true,
131 allow_fallback: true,
132 capture_timeout_ms: 15000, // 15 seconds
133 max_retry_attempts: 5,
134 minimum_quality: 0.6,
135 }
136 }
137
138 /// Create a user-friendly configuration for the given biometric type
139 pub fn user_friendly(biometric_type: BiometricType) -> Self {
140 Self {
141 biometric_type,
142 liveness_detection: false,
143 allow_fallback: true,
144 capture_timeout_ms: 30000, // 30 seconds
145 max_retry_attempts: 10,
146 minimum_quality: 0.4,
147 }
148 }
149}
150
151/// Result of biometric enrollment operation
152#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct BiometricEnrollmentResult {
154 /// Whether enrollment was successful
155 pub success: bool,
156 /// Unique identifier for the enrolled template
157 pub template_id: Option<String>,
158 /// Quality score of the enrolled template (0.0 to 1.0)
159 pub quality_score: Option<f32>,
160 /// Number of samples captured during enrollment
161 pub samples_captured: u32,
162 /// Error message if enrollment failed
163 pub error: Option<String>,
164}
165
166/// Result of biometric verification operation
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct BiometricVerificationResult {
169 /// Whether verification was successful
170 pub verified: bool,
171 /// Confidence score of the match (0.0 to 1.0)
172 pub confidence_score: Option<f32>,
173 /// Template ID that was matched
174 pub matched_template_id: Option<String>,
175 /// Whether liveness was detected (if enabled)
176 pub liveness_detected: Option<bool>,
177 /// Time taken for verification (milliseconds)
178 pub verification_time_ms: u32,
179 /// Error message if verification failed
180 pub error: Option<String>,
181}
182
183/// Information about available biometric capabilities
184#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct BiometricCapability {
186 /// Type of biometric supported
187 pub biometric_type: BiometricType,
188 /// Whether this biometric is currently available
189 pub available: bool,
190 /// Whether biometric hardware is present
191 pub hardware_present: bool,
192 /// Whether biometric data is enrolled
193 pub enrolled: bool,
194 /// Security level of this biometric
195 pub security_level: BiometricSecurityLevel,
196 /// Platform-specific capability flags
197 pub platform_features: Vec<String>,
198}
199
200/// Biometric effects interface
201///
202/// This trait defines operations for biometric authentication that interface
203/// with platform-specific biometric APIs and hardware security modules.
204///
205/// # Implementation Notes
206///
207/// - Production: Interface with platform APIs (LocalAuthentication, BiometricPrompt, Windows Hello)
208/// - Testing: Simulate biometric operations with configurable success/failure patterns
209/// - Simulation: Deterministic biometric verification for reproducible testing
210///
211/// # Security Properties
212///
213/// - Templates stored in hardware security modules when available
214/// - Biometric data never transmitted over network
215/// - Liveness detection to prevent spoofing attacks
216/// - Secure template comparison in hardware
217///
218/// # Stability: EXPERIMENTAL
219/// This API is under development and may change in future versions.
220#[async_trait]
221pub trait BiometricEffects: Send + Sync {
222 /// Check what biometric capabilities are available on this device
223 ///
224 /// Queries the platform to determine which biometric authentication
225 /// methods are supported and currently available.
226 ///
227 /// # Returns
228 /// List of available biometric capabilities with their current status
229 async fn get_biometric_capabilities(&self) -> Result<Vec<BiometricCapability>, BiometricError>;
230
231 /// Check if a specific biometric type is available and enrolled
232 ///
233 /// Quick check for whether a specific biometric authentication method
234 /// can be used immediately.
235 ///
236 /// # Parameters
237 /// - `biometric_type`: Type of biometric to check
238 ///
239 /// # Returns
240 /// `true` if the biometric is available and has enrolled data
241 async fn is_biometric_available(
242 &self,
243 biometric_type: BiometricType,
244 ) -> Result<bool, BiometricError>;
245
246 /// Enroll a new biometric template
247 ///
248 /// Captures biometric data from the user and stores a template securely.
249 /// This typically involves multiple samples to create a high-quality template.
250 ///
251 /// # Parameters
252 /// - `config`: Configuration for the enrollment process
253 /// - `user_prompt`: Message to display to the user during enrollment
254 ///
255 /// # Returns
256 /// Result containing enrollment success/failure and template information
257 async fn enroll_biometric(
258 &self,
259 config: BiometricConfig,
260 user_prompt: &str,
261 ) -> Result<BiometricEnrollmentResult, BiometricError>;
262
263 /// Verify a user using biometric authentication
264 ///
265 /// Captures biometric data and compares it against enrolled templates.
266 /// Returns verification result with confidence score.
267 ///
268 /// # Parameters
269 /// - `biometric_type`: Type of biometric to verify
270 /// - `user_prompt`: Message to display to the user during verification
271 /// - `template_id`: Optional specific template to verify against
272 ///
273 /// # Returns
274 /// Result containing verification success/failure and match information
275 async fn verify_biometric(
276 &self,
277 biometric_type: BiometricType,
278 user_prompt: &str,
279 template_id: Option<&str>,
280 ) -> Result<BiometricVerificationResult, BiometricError>;
281
282 /// Delete an enrolled biometric template
283 ///
284 /// Securely removes a biometric template from storage.
285 ///
286 /// # Parameters
287 /// - `biometric_type`: Type of biometric template to remove
288 /// - `template_id`: ID of the specific template to remove (if None, removes all)
289 ///
290 /// # Returns
291 /// Success/failure result
292 async fn delete_biometric_template(
293 &self,
294 biometric_type: BiometricType,
295 template_id: Option<&str>,
296 ) -> Result<(), BiometricError>;
297
298 /// List enrolled biometric templates
299 ///
300 /// Returns information about biometric templates currently enrolled
301 /// on the device, without exposing the actual template data.
302 ///
303 /// # Returns
304 /// List of template IDs and metadata for enrolled biometrics
305 async fn list_enrolled_templates(
306 &self,
307 ) -> Result<Vec<(String, BiometricType, f32)>, BiometricError>; // (id, type, quality)
308
309 /// Test biometric hardware functionality
310 ///
311 /// Performs a basic test of biometric hardware to ensure it's functioning
312 /// correctly. This doesn't require user interaction.
313 ///
314 /// # Parameters
315 /// - `biometric_type`: Type of biometric hardware to test
316 ///
317 /// # Returns
318 /// `true` if hardware is functioning correctly
319 async fn test_biometric_hardware(
320 &self,
321 biometric_type: BiometricType,
322 ) -> Result<bool, BiometricError>;
323
324 /// Configure biometric security settings
325 ///
326 /// Updates platform-specific security settings for biometric authentication.
327 ///
328 /// # Parameters
329 /// - `config`: New configuration to apply
330 ///
331 /// # Returns
332 /// Success/failure result
333 async fn configure_biometric_security(
334 &self,
335 config: BiometricConfig,
336 ) -> Result<(), BiometricError>;
337
338 /// Get biometric authentication statistics
339 ///
340 /// Returns usage statistics and performance metrics for biometric authentication.
341 ///
342 /// # Returns
343 /// Statistics about biometric authentication usage
344 async fn get_biometric_statistics(&self) -> Result<BiometricStatistics, BiometricError>;
345
346 /// Cancel any ongoing biometric operation
347 ///
348 /// Cancels enrollment or verification operations that are currently in progress.
349 async fn cancel_biometric_operation(&self) -> Result<(), BiometricError>;
350
351 /// Check if this implementation supports hardware security
352 fn supports_hardware_security(&self) -> bool;
353
354 /// Get platform-specific biometric capabilities
355 fn get_platform_capabilities(&self) -> Vec<String>;
356}
357
358/// Statistics about biometric authentication usage
359#[derive(Debug, Clone, Serialize, Deserialize, Default)]
360pub struct BiometricStatistics {
361 /// Total number of verification attempts
362 pub total_attempts: u64,
363 /// Number of successful verifications
364 pub successful_verifications: u64,
365 /// Number of failed verification attempts
366 pub failed_attempts: u64,
367 /// Average verification time in milliseconds
368 pub average_verification_time_ms: u32,
369 /// Number of enrolled templates by type
370 pub enrolled_templates_by_type: std::collections::HashMap<BiometricType, u32>,
371 /// Last verification timestamp
372 pub last_verification_at: Option<u64>,
373 /// False acceptance rate (if available)
374 pub false_acceptance_rate: Option<f32>,
375 /// False rejection rate (if available)
376 pub false_rejection_rate: Option<f32>,
377}
378
379/// Helper functions for common biometric operations
380impl BiometricCapability {
381 /// Check if this biometric can be used for authentication
382 pub fn is_usable(&self) -> bool {
383 self.available && self.hardware_present && self.enrolled
384 }
385
386 /// Check if this biometric meets a minimum security level
387 pub fn meets_security_level(&self, required_level: BiometricSecurityLevel) -> bool {
388 matches!(
389 (required_level, &self.security_level),
390 (BiometricSecurityLevel::Low, _)
391 | (
392 BiometricSecurityLevel::Medium,
393 BiometricSecurityLevel::Medium
394 )
395 | (BiometricSecurityLevel::Medium, BiometricSecurityLevel::High)
396 | (
397 BiometricSecurityLevel::Medium,
398 BiometricSecurityLevel::VeryHigh
399 )
400 | (BiometricSecurityLevel::High, BiometricSecurityLevel::High)
401 | (
402 BiometricSecurityLevel::High,
403 BiometricSecurityLevel::VeryHigh
404 )
405 | (
406 BiometricSecurityLevel::VeryHigh,
407 BiometricSecurityLevel::VeryHigh
408 )
409 )
410 }
411}
412
413impl BiometricVerificationResult {
414 /// Check if verification was successful with sufficient confidence
415 pub fn is_verified_with_confidence(&self, minimum_confidence: f32) -> bool {
416 self.verified
417 && self
418 .confidence_score
419 .is_some_and(|score| score >= minimum_confidence)
420 }
421
422 /// Check if liveness was properly detected (when required)
423 pub fn has_liveness(&self) -> bool {
424 self.liveness_detected.unwrap_or(true) // Assume liveness if not checked
425 }
426}
427
428#[cfg(test)]
429mod tests {
430 use super::*;
431
432 #[test]
433 fn test_biometric_type_display_names() {
434 assert_eq!(BiometricType::Fingerprint.display_name(), "Fingerprint");
435 assert_eq!(BiometricType::Face.display_name(), "Face ID");
436 assert_eq!(BiometricType::Iris.display_name(), "Iris");
437 }
438
439 #[test]
440 fn test_biometric_security_levels() {
441 assert_eq!(
442 BiometricType::Fingerprint.security_level(),
443 BiometricSecurityLevel::High
444 );
445 assert_eq!(
446 BiometricType::Iris.security_level(),
447 BiometricSecurityLevel::VeryHigh
448 );
449 assert_eq!(
450 BiometricType::Voice.security_level(),
451 BiometricSecurityLevel::Medium
452 );
453 }
454
455 #[test]
456 fn test_biometric_config_presets() {
457 let high_sec = BiometricConfig::high_security(BiometricType::Face);
458 assert!(high_sec.liveness_detection);
459 assert!(!high_sec.allow_fallback);
460 assert!(high_sec.minimum_quality >= 0.8);
461
462 let user_friendly = BiometricConfig::user_friendly(BiometricType::Fingerprint);
463 assert!(!user_friendly.liveness_detection);
464 assert!(user_friendly.allow_fallback);
465 assert!(user_friendly.max_retry_attempts >= 10);
466 }
467
468 #[test]
469 fn test_biometric_capability_usability() {
470 let usable = BiometricCapability {
471 biometric_type: BiometricType::Fingerprint,
472 available: true,
473 hardware_present: true,
474 enrolled: true,
475 security_level: BiometricSecurityLevel::High,
476 platform_features: vec![],
477 };
478 assert!(usable.is_usable());
479
480 let not_enrolled = BiometricCapability {
481 enrolled: false,
482 ..usable
483 };
484 assert!(!not_enrolled.is_usable());
485 }
486
487 #[test]
488 fn test_security_level_requirements() {
489 let high_sec_capability = BiometricCapability {
490 biometric_type: BiometricType::Iris,
491 available: true,
492 hardware_present: true,
493 enrolled: true,
494 security_level: BiometricSecurityLevel::VeryHigh,
495 platform_features: vec![],
496 };
497
498 assert!(high_sec_capability.meets_security_level(BiometricSecurityLevel::Low));
499 assert!(high_sec_capability.meets_security_level(BiometricSecurityLevel::Medium));
500 assert!(high_sec_capability.meets_security_level(BiometricSecurityLevel::High));
501 assert!(high_sec_capability.meets_security_level(BiometricSecurityLevel::VeryHigh));
502
503 let low_sec_capability = BiometricCapability {
504 security_level: BiometricSecurityLevel::Low,
505 ..high_sec_capability
506 };
507 assert!(low_sec_capability.meets_security_level(BiometricSecurityLevel::Low));
508 assert!(!low_sec_capability.meets_security_level(BiometricSecurityLevel::High));
509 }
510
511 #[test]
512 fn test_verification_result_confidence() {
513 let good_result = BiometricVerificationResult {
514 verified: true,
515 confidence_score: Some(0.95),
516 matched_template_id: Some("template1".to_string()),
517 liveness_detected: Some(true),
518 verification_time_ms: 500,
519 error: None,
520 };
521
522 assert!(good_result.is_verified_with_confidence(0.9));
523 assert!(!good_result.is_verified_with_confidence(0.99));
524 assert!(good_result.has_liveness());
525
526 let low_confidence = BiometricVerificationResult {
527 confidence_score: Some(0.5),
528 ..good_result
529 };
530 assert!(!low_confidence.is_verified_with_confidence(0.9));
531 }
532}