mirror of
https://github.com/openai/codex.git
synced 2026-10-19 17:28:46 +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
92 lines
3.2 KiB
Rust
92 lines
3.2 KiB
Rust
//! Device credentials and signing, independent of RPC routing, UI, and backend registration.
|
||
|
||
mod credential;
|
||
mod error;
|
||
mod guard;
|
||
mod key_namespace;
|
||
#[cfg(any(target_os = "macos", test))]
|
||
mod lifecycle_lock;
|
||
#[cfg(any(target_os = "macos", test))]
|
||
mod native_operation;
|
||
#[cfg(any(target_os = "macos", test))]
|
||
mod platform_macos;
|
||
#[cfg(not(target_os = "macos"))]
|
||
mod unsupported;
|
||
|
||
pub use credential::UserVerificationKeyCreation;
|
||
pub use credential::UserVerificationKeyDeletion;
|
||
pub use credential::UserVerificationKeyInfo;
|
||
pub use credential::UserVerificationProof;
|
||
pub use credential::UserVerificationRequest;
|
||
pub use credential::UserVerificationStatus;
|
||
pub use error::UserVerificationCancellationReason;
|
||
pub use error::UserVerificationError;
|
||
pub use error::UserVerificationFailureReason;
|
||
pub use error::UserVerificationUnavailableReason;
|
||
pub use guard::UserVerificationRequestGuard;
|
||
pub use key_namespace::UserVerificationKeyNamespace;
|
||
use std::sync::Arc;
|
||
|
||
/// Performs local credential operations for one captured account-user identity.
|
||
/// Implementations never perform network registration. Blocking implementations must run off
|
||
/// the async executor and check the guard after waiting, before effects, and before returning.
|
||
pub trait UserVerificationProvider: Send + Sync {
|
||
/// Reads local readiness without creating credentials or prompting for authentication.
|
||
fn status(
|
||
&self,
|
||
guard: &UserVerificationRequestGuard,
|
||
) -> Result<UserVerificationStatus, UserVerificationError>;
|
||
|
||
/// Creates a protected key only if none exists. Success does not mean server enrollment.
|
||
fn ensure_key(
|
||
&self,
|
||
guard: &UserVerificationRequestGuard,
|
||
) -> Result<UserVerificationKeyCreation, UserVerificationError>;
|
||
|
||
/// Removes the local key idempotently. Backend revocation belongs to the caller.
|
||
fn delete(
|
||
&self,
|
||
guard: &UserVerificationRequestGuard,
|
||
) -> Result<UserVerificationKeyDeletion, UserVerificationError>;
|
||
|
||
/// Authenticates and signs 1–4096 challenge bytes without interpreting an elicitation.
|
||
/// The caller owns approval UI, request correlation, and the captured identity check.
|
||
fn verify(
|
||
&self,
|
||
request: &UserVerificationRequest,
|
||
guard: &UserVerificationRequestGuard,
|
||
) -> Result<UserVerificationProof, UserVerificationError>;
|
||
}
|
||
|
||
/// Reports whether this build contains a native provider, independently of local readiness.
|
||
pub fn platform_supported() -> bool {
|
||
cfg!(target_os = "macos")
|
||
}
|
||
|
||
/// Probes biometric hardware without reading credentials, prompting, or checking enrollment.
|
||
/// This performs local OS work; async callers should run it off their executor during setup.
|
||
pub fn device_supported() -> bool {
|
||
#[cfg(target_os = "macos")]
|
||
{
|
||
platform_macos::device_supported()
|
||
}
|
||
#[cfg(not(target_os = "macos"))]
|
||
{
|
||
false
|
||
}
|
||
}
|
||
|
||
pub fn platform_provider(
|
||
namespace: UserVerificationKeyNamespace,
|
||
) -> Arc<dyn UserVerificationProvider> {
|
||
#[cfg(target_os = "macos")]
|
||
{
|
||
Arc::new(platform_macos::NativeProvider { namespace })
|
||
}
|
||
#[cfg(not(target_os = "macos"))]
|
||
{
|
||
let _ = namespace.label;
|
||
Arc::new(unsupported::UnsupportedProvider)
|
||
}
|
||
}
|