Skip to main content

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}