O Oskar Karpiński
Archived open source

LibrePass

A self-hosted password manager built as a full product study: from encryption to Android, backend, synchronization, and deployment.

Overview

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.

  • Self-hosted password vault with end-to-end encryption before data reaches the server
  • Complete Android app built with Kotlin, Jetpack Compose, Material 3, and biometric unlock
  • Spring Boot backend with REST APIs, database-stored tokens, request validation, and rate limiting
  • Encrypted data storage on PostgreSQL or MySQL with sync logs for change handling
  • Offline-capable mobile workflow with local changes queued until connectivity returns
  • Incomplete Svelte web client, technical documentation, and AGPL-3.0 source code

What it taught me

The most important lessons from LibrePass

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.

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.

E2E encryptionToken authValidation

Synchronization is product work

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.

Offline-firstSync logsConflict handling

Mobile needs architecture

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.

Jetpack ComposeMaterial 3Biometrics

Backend needs boundaries

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.

Spring BootREST APIData model

Documentation scales a project

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.

DocsDockerDeployment

Scope has to close

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.

ScopeProduct thinkingTrade-offs

Android app

Mobile password manager screens

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.

LibrePass Android welcome screen for a self-hosted password manager
Welcome screen
LibrePass Android create account screen
Account creation
LibrePass Android add password entry screen
Add vault entry
LibrePass Android view password entry screen
Encrypted entry details
LibrePass Android password generator screen
Password generator

Desktop version

An unfinished client for larger screens

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.

Unfinished LibrePass desktop version preview with a password manager vault entry list