Session Management: Idle Timeouts and Step-Up Auth (Android)
Part 9 of our Android security series. Part 8 covered Credential Manager — getting the user signed in. This post covers what happens for…
Session Management: Idle Timeouts and Step-Up Auth (Android)

Part 9 of our Android security series. Part 8 covered Credential Manager — getting the user signed in. This post covers what happens for the rest of the session, until they sign out.
What it is, in one line
Session management is everything that happens after login: how long a session stays valid while the user does nothing, and when the app should ask for re-authentication even though they’re technically still signed in.
Why “just stay logged in forever” isn’t the answer
Mobile users expect long-lived sessions — nobody wants to log into their banking app every single time they open it. But “long-lived” and “no limits at all” aren’t the same thing. A phone left unlocked on a table, or lost with the app still open, is a real exposure window. The fix isn’t shortening every session — it’s being deliberate about which actions need a fresh check, even inside a session that’s otherwise still valid.
Idle timeout: lock the app, not just the account
An idle timeout doesn’t sign the user out of your backend — it locks the app itself after a period of inactivity, requiring a quick re-check (PIN, biometric) to resume:
class IdleTimeoutTracker(private val timeoutMs: Long = 5 * 60 * 1000) {
private var lastActiveAt = System.currentTimeMillis()
fun onUserInteraction() {
lastActiveAt = System.currentTimeMillis()
}
fun isIdleTimedOut(): Boolean =
System.currentTimeMillis() - lastActiveAt > timeoutMs
}
Hook this into Activity.onUserInteraction() and check it in onResume():
override fun onResume() {
super.onResume()
if (idleTracker.isIdleTimedOut()) {
showLockScreen() // biometric or PIN re-entry, not a full re-login
}
}
The right timeout length depends on what the app does — a few minutes for banking or health apps, longer for something low-stakes like a note-taking app. There’s no universal number; match it to what’s actually at risk if the phone is picked up unlocked.
Step-up auth: not every action deserves the same trust level
The idea behind step-up auth: being logged in is enough to browse, but certain actions — adding a new payee, changing a password, viewing a full card number — deserve a fresh, explicit check, even mid-session.
suspend fun performSensitiveAction(action: () -> Unit) {
val freshAuth = requestBiometricConfirmation(
title = "Confirm it's you",
subtitle = "Required for this action"
)
if (freshAuth) {
action()
}
}
Tie this to the CryptoObject pattern from Part 7 wherever the action involves decrypting or signing something — the same principle applies: the check should gate the actual operation, not just a UI flag.
Good candidates for step-up auth: changing account credentials, adding a payment method, large transactions, viewing full sensitive records (not just masked previews), disabling security features like biometrics itself.
Server-side session expiry still matters
App-level idle locking is a UX layer — it doesn’t replace real session expiry enforced by your backend. The access token itself should still have a reasonable lifetime, checked server-side on every request, regardless of what the app’s lock screen is doing locally. Think of app-level locking as protecting the device in someone’s hand right now; server-side expiry protects against a token that leaked or was captured somewhere else entirely.
What to do when a session actually expires
fun handleSessionExpired() {
clearTokensFromStorage() // from Part 6's secure storage
clearInMemoryUserState()
navigateToLogin(message = "Your session expired. Please sign in again.")
}
Clear tokens from wherever you stored them (DataStore + Tink from Part 6), not just from memory — a stale token sitting in storage is still a stale token.
Quick checklist
- [ ] Idle timeout locks the app locally, sized to the sensitivity of what the app does
- [ ] Sensitive actions require step-up auth, even mid-session
- [ ] Step-up checks gate the actual operation (via
CryptoObjectwhere relevant), not just a UI boolean - [ ] Server-side token expiry enforced independently of any app-level lock screen
- [ ] Expired sessions clear tokens from persistent storage, not just app memory
The one-line takeaway
Treat “signed in” as a spectrum, not a switch — idle timeouts protect against the phone in the wrong hands right now, and step-up auth makes sure the highest-value actions always get a fresh check, no matter how long the session’s been open.
Next up in the series: Token refresh & rotation — keeping sessions alive through flaky networks without opening a security hole.
메타데이터
- post_id
- a653fa39f711
- slug
- session-management-idle-timeouts-and-step-up-auth-android-a653fa39f711
- url
- https://medium.com/@khizarkhan8/session-management-idle-timeouts-and-step-up-auth-android-a653fa39f711
- canonical_url
- https://medium.com/@khizarkhan8/session-management-idle-timeouts-and-step-up-auth-android-a653fa39f711
- author_url
- https://medium.com/@khizarkhan8
- status
- ok
- fetched_at
- 2026-08-21 01:45:42