Security is a process
Building a password manager taught me that security is not one feature. It is the sum of encryption choices, password hashing, tokens, validation, vault locking, and deciding what the server should never be able to see.
A self-hosted password manager built as a full product study: from encryption to Android, backend, synchronization, and deployment.
LibrePass was a self-directed open-source project covering a mobile app, backend API, data model, documentation, containerization, and synchronization.
The central architectural decision was a clear split between client and server responsibilities. The Android app owns the user experience, offline work, biometric unlock, and vault operations, while the Spring Boot backend only handles authentication, synchronization, and encrypted payload storage.
The project connected product decisions with technical ones: account creation, adding passwords, and password generation on the user side; validation, token handling, request limits, offline queues, and conflict handling on the system side.
What it taught me
LibrePass was the kind of project that forced me to think about the whole system at once: UX, security, data modeling, synchronization, APIs, deployment, and time constraints.
Building a password manager taught me that security is not one feature. It is the sum of encryption choices, password hashing, tokens, validation, vault locking, and deciding what the server should never be able to see.
Offline mode and data synchronization taught me to design flows that still behave predictably without network access, across multiple devices, and in the presence of data conflicts.
The Android client helped me practice Compose, Material 3, biometrics, local application state, and separation of concerns so the UI was not tightly coupled to synchronization logic.
The backend handled APIs, authorization, rate limits, databases, and synchronization, but not user-data decryption. It was a strong lesson in designing services with explicit trust boundaries.
Separate documentation and deployment notes showed me how valuable it is to record technical decisions, configuration, and flows before a project becomes hard to reconstruct.
The unfinished web client was a practical lesson in scope management. It taught me to separate the valuable core of a product from features that are better kept as references than developed indefinitely.
Android app
The Android app was the main and most polished LibrePass client. It was built natively with Kotlin and Jetpack Compose, which made it fast, lightweight, responsive, and closely aligned with the platform: from smooth UI and Material 3 to local app state, biometrics, and offline work.





Desktop version
The desktop view was the direction for bringing LibrePass beyond the mobile app. It was meant to make vault work more comfortable on a larger screen: browsing entries quickly, managing login data, and using the password manager as part of a daily desktop workflow.
This part of the project was not completed as a production-ready client. It remains a prototype and reference point for the planned interface direction, showing how LibrePass could look outside the native Android experience.
