Recursivity
All projects
Open source

Lockbox

An offline TOTP/HOTP authenticator for iOS and Android

View on GitHub
LanguageSwift 6 / SwiftUI · Kotlin / Compose
PlatformiOS 17+ and Android
Network codeNone
LicenseMIT
  • Pinned accounts first, each code counting down on its own ring — generated on the device, with nothing to sync.
    Pinned accounts first, each code counting down on its own ring — generated on the device, with nothing to sync.

Lockbox generates the same six- or eight-digit two-factor codes as Google Authenticator or Raivo OTP. The difference is what is absent: the app contains no networking layer at all. Nothing is uploaded, nothing is synced, and there is no backend to compromise.

Secrets live in the iOS Keychain. Accounts are cleared from memory when the app is backgrounded and re-prompted on return, so a shoulder-surfed app switcher gives nothing away.

Features

Honest about the limits

This app has not been independently security audited. It ships a SECURITY.md that documents the storage design, the known limitations, and how to report a vulnerability — and both the README and the repo description say the audit gap out loud, because an authenticator that oversells itself is worse than one that doesn't exist.

The test suite covers the RFC 6238 and RFC 4226 reference vectors, otpauth:// URI parsing, and Raivo import/export round-tripping. It runs on macOS through the Swift Package manifest with no simulator needed, which keeps the fast path fast.

On Android

The same app exists for Android, written in Kotlin with the interface in Jetpack Compose. The rule that defines it did not get relaxed in the port: still no networking layer, still nothing to sync, and secrets held by the platform’s own secure storage rather than a file the app manages itself — the Keychain on iOS, the system keystore on Android.

Stack

LanguageSwift 6, strict concurrency checking set to complete
UISwiftUI, iOS 17+
AndroidKotlin and Jetpack Compose, with secrets in the system keystore
StorageKeychain
CryptoSwiftOTP and Apple's swift-crypto, via Swift Package Manager — nothing vendored
ProjectXcodeGen; project.yml is the source of truth and the .xcodeproj is not checked in