- 
                Notifications
    
You must be signed in to change notification settings  - Fork 165
 
feat: add configurable biometric authentication policies for SecureCredentialsManager #867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…session management
…K-6524-biometric-policy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds configurable biometric authentication policies to SecureCredentialsManager, allowing developers to control when biometric prompts are shown based on different authentication strategies (Always, Session-based, or App Lifecycle-based).
Key changes:
- Introduction of 
BiometricPolicysealed class with three policy types - Enhanced 
LocalAuthenticationOptionsto include policy configuration - Session management functionality in 
SecureCredentialsManager 
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description | 
|---|---|
BiometricPolicy.kt | 
New sealed class defining three biometric authentication policies | 
LocalAuthenticationOptions.kt | 
Added policy parameter and builder method for biometric policy configuration | 
SecureCredentialsManager.kt | 
Integrated session validation logic and biometric session management | 
SecureCredentialsManagerBiometricPolicyTest.kt | 
Comprehensive test coverage for new biometric policy functionality | 
EXAMPLES.md | 
Updated documentation with examples and explanations of BiometricPolicy usage | 
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| private const val NO_SESSION = -1L | ||
| private val lastBiometricAuthTime = AtomicLong(NO_SESSION) | 
    
      
    
      Copilot
AI
    
    
    
      Sep 9, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lastBiometricAuthTime is declared as a companion object property, making it shared across all instances of SecureCredentialsManager. This creates a potential issue where multiple manager instances would interfere with each other's session state. Consider making this an instance variable instead of a companion object property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, why does lastBiometricAuthTime defined as companion object property. This needs to be class property
        
          
                auth0/src/main/java/com/auth0/android/authentication/storage/SecureCredentialsManager.kt
          
            Show resolved
            Hide resolved
        
              
          
                auth0/src/main/java/com/auth0/android/authentication/storage/SecureCredentialsManager.kt
              
                Outdated
          
            Show resolved
            Hide resolved
        
      | import java.util.concurrent.Executor | ||
| 
               | 
          ||
| @RunWith(RobolectricTestRunner::class) | ||
| public class SecureCredentialsManagerBiometricPolicyTest { | 
    
      
    
      Copilot
AI
    
    
    
      Sep 9, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public modifier is unnecessary for test classes in Kotlin. Test classes should have default (internal) visibility.
| public class SecureCredentialsManagerBiometricPolicyTest { | |
| class SecureCredentialsManagerBiometricPolicyTest { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it requires to run the test cases.
| private val testExecutor = Executor { command -> command.run() } | ||
| 
               | 
          ||
| @Before | ||
| public fun setUp() { | 
    
      
    
      Copilot
AI
    
    
    
      Sep 9, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public modifier is unnecessary for test methods in Kotlin. Test methods should have default (internal) visibility.
| public fun setUp() { | |
| fun setUp() { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it requires to run the test cases.
| * The session is invalidated by calling clearBiometricSession() or after the default timeout. | ||
| * @param timeoutInSeconds The duration for which the session remains valid. Defaults to 3600 seconds (1 hour). | ||
| */ | ||
| public data class AppLifecycle(val timeoutInSeconds: Int = 3600) : BiometricPolicy() // Default 1 hour | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs the @jvmoverloads annotation to work with seamlessly java
| is BiometricPolicy.AppLifecycle -> { | ||
| val timeoutMillis = biometricPolicy.timeoutInSeconds * 1000L | ||
| System.currentTimeMillis() - lastAuth < timeoutMillis | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The two cases can be combined
return when (biometricPolicy) {
            is BiometricPolicy.Session ,
            is BiometricPolicy.AppLifecycle -> {
                val timeoutMillis = biometricPolicy.timeoutInSeconds * 1000L
                System.currentTimeMillis() - lastAuth < timeoutMillis
            }
            is BiometricPolicy.Always -> false
            }
    ```        
| 
               | 
          ||
| assert(policy1 === policy2) // Same instance | ||
| assert(policy1 == policy2) // Equal | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case is not needed
| } | ||
| 
               | 
          ||
| @Test | ||
| public fun `BiometricPolicy Session should be data class with timeout parameter`() { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be removed
| } | ||
| 
               | 
          ||
| @Test | ||
| public fun `BiometricPolicy AppLifecycle should be data class with default timeout`() { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
| // ========================= | ||
| 
               | 
          ||
| @Test | ||
| public fun `BiometricPolicy Always should be object type`() { | 
    
      
    
      Copilot
AI
    
    
    
      Sep 30, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public visibility modifier is unnecessary for test methods in Kotlin and should be removed. Kotlin defaults to public visibility for functions, making this redundant.
| } | ||
| 
               | 
          ||
| @Test | ||
| public fun `BiometricPolicy Session should be data class with timeout parameter`() { | 
    
      
    
      Copilot
AI
    
    
    
      Sep 30, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public visibility modifier is unnecessary for test methods in Kotlin and should be removed. Kotlin defaults to public visibility for functions, making this redundant.
Changes
This PR introduces configurable biometric authentication policies for
SecureCredentialsManager, allowing developers to control when biometric prompts are shown when accessing stored credentials. This enhancement improves user experience by reducing authentication friction while maintaining security.References
auth0/react-native-auth0#687 (comment)
Testing
./gradlew :auth0:testDebugUnitTest --tests "*BiometricPolicyTest"Checklist