mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
## Why The user-verification API previously returned an unsupported provider on macOS. Enable native verification using biometric-protected credentials. ## What changed - Implement credential status, creation, reuse, deletion, and challenge signing with P-256 Secure Enclave keys in the Data Protection Keychain. - Require biometric authentication through the key's access-control policy and use a fresh `LAContext` for each signature. - Report Touch ID hardware support independently of enrollment and current readiness, and map native failures to structured verification errors. - Serialize credential operations across processes with cancellable file-lock waits. Invalidate pending authentication on cancellation and wait for the signer to exit before releasing the lock. ## Testing Add unit tests for lock contention and cancellation, authentication teardown and late-result rejection, native error classification, and validation of Secure Enclave key attributes. GitOrigin-RevId: 93268962cd824b2befc1a0c54b99dcb77a0f1044
55 lines
2.6 KiB
Rust
55 lines
2.6 KiB
Rust
//! Maps macOS Security and LocalAuthentication failures to stable errors without exposing localized OS diagnostics.
|
|
|
|
use crate::UserVerificationCancellationReason;
|
|
use crate::UserVerificationError;
|
|
use crate::UserVerificationFailureReason;
|
|
use crate::UserVerificationUnavailableReason;
|
|
|
|
pub(crate) fn classify(domain: &str, code: i64) -> UserVerificationError {
|
|
tracing::debug!(domain, code, "native user-verification operation failed");
|
|
match (domain, code) {
|
|
("NSOSStatusErrorDomain", -128) | ("com.apple.LocalAuthentication", -2 | -3) => {
|
|
UserVerificationError::Cancelled {
|
|
reason: UserVerificationCancellationReason::UserCancelled,
|
|
message: "authentication was cancelled".to_string(),
|
|
}
|
|
}
|
|
("com.apple.LocalAuthentication", -4 | -9) => UserVerificationError::Cancelled {
|
|
reason: UserVerificationCancellationReason::Interrupted,
|
|
message: "authentication was interrupted".to_string(),
|
|
},
|
|
("NSOSStatusErrorDomain", -25293) | ("com.apple.LocalAuthentication", -1) => {
|
|
UserVerificationError::Failed {
|
|
reason: UserVerificationFailureReason::AuthenticationFailed,
|
|
message: "biometric authentication failed".to_string(),
|
|
}
|
|
}
|
|
("com.apple.LocalAuthentication", -5 | -6 | -7 | -8 | -12 | -13) => {
|
|
UserVerificationError::Unavailable {
|
|
reason: UserVerificationUnavailableReason::BiometricsUnavailable,
|
|
message: "biometric authentication is not available right now".to_string(),
|
|
}
|
|
}
|
|
("com.apple.LocalAuthentication", -1004) => UserVerificationError::Unavailable {
|
|
reason: UserVerificationUnavailableReason::ProviderUnavailable,
|
|
message: "authentication UI is not permitted in this process".to_string(),
|
|
},
|
|
("NSOSStatusErrorDomain", -34018) => UserVerificationError::Unavailable {
|
|
reason: UserVerificationUnavailableReason::ProviderUnavailable,
|
|
message: "this binary is missing the required keychain entitlements".to_string(),
|
|
},
|
|
("NSOSStatusErrorDomain", -25291 | -25308) => UserVerificationError::Unavailable {
|
|
reason: UserVerificationUnavailableReason::ProviderUnavailable,
|
|
message: "the platform keychain is not available right now".to_string(),
|
|
},
|
|
_ => UserVerificationError::Failed {
|
|
reason: UserVerificationFailureReason::ProviderError,
|
|
message: "the platform could not complete user verification".to_string(),
|
|
},
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[path = "error_tests.rs"]
|
|
mod tests;
|