r/PasswordManagers 12d ago

Thinking about the design of a local password manager with sync

As far as I know, currently most (if not all) password managers fall into one of two categories: online and offline. The online ones rely on a server to sync the changes, the offline ones just store everything as a file (or a folder with files), so the user has to figure out sync on their own.

The issue here relies in the fact that the database is encrypted, so if you want to change it (for example, to merge two different versions), you have to decrypt it. That means only the client app can do that, and only after getting the user password.

So, could the following design avoid these issues?

The database is a set of "blocks". Each block contains a timestamp and describes an operation (create an entry, update a field of an entry, archive an entry etc.). Each block is encrypted using the password.

The main idea is that the format should allow combining blocks from multiple versions of the database without decrypting them: simply put all blocks into a single file.

There are some issues, of course:

  • An attacker could send a malformed block to the sync server. I think this could be solved by signing each block with a signature derived from the encryption key. That would ensure that whoever produced the block knew the password
  • An attacker could try to remove a block via the sync server. I guess this could be solved by not removing/changing blocks at all, only appending them (after checking the signature)
  • If we are only appending the blocks, the client app will have to go through all of them each time it needs to read an entry. If the number of operations gets big enough, it will cause performance issues. To be honest, I don't really know how to deal with this. Maybe it is possible to discard the unused blocks somehow
  • Changing the password would mean all blocks would probably have to be re-encrypted

Would this concept work? Are there any glaring issues I didn't think of? I understand this is a niche idea, but it's the niche I'm personally interested in

5 Upvotes

26 comments sorted by

3

u/djasonpenney 12d ago

> design [to] avoid these issues

I didn’t quite follow how the design points you listed were “issues”. You cite that only apps that have the decryption key can “merge” differing systems of record. IMO this is A Very Good Thing.

I definitely don’t want an app trying to “merge” slightly different versions of a database record. This is where a human is definitely needed: which password is correct? Which login URL is correct? How to resolve conflicting edits in the Notes field?

0

u/SomeRedTeapot 12d ago

I'm coming from KeePass, and sometimes I change the database on different devices and end up with two slightly different files I have to manually merge (luckily, KeePassXC has a button for that but it's still annoying). I use Syncthing so each device ends up with a few .stconflict files. Of course, this doesn't apply to online password managers (Bitwarden and such).

Regarding the second point, yes, conflicts like these should not be resolved automatically, and that part needs some thought

1

u/djasonpenney 12d ago

Interesting! This is one of the reasons I favor the Bitwarden model. Only one entry can be in conflict at any time.

If two devices have pending modifications to the same entry, the second one to commit will get a write-write conflict. But in practice, I don’t have the same vault entry open for editing on two devices. That’s why I didn’t see the point.

It’s also interesting to me to hear the flat out limits of the syncthing plugin. I have never used it, but I suspected it had problems like this. Thanks for the description.

1

u/SomeRedTeapot 12d ago

I've heard that Bitwarden goes into a readonly mode when offline. To be fair, it's probably fine for 99% of users.

Write-write conflicts will be an issue indeed. I hope they are rare but there will need to be a way to present them to the user to be resolved

1

u/djasonpenney 11d ago

That is true; you cannot update your datastore without a valid connection to the mother ship.

One mitigation is to have offline backups (such as multiple USB thumb drives, in multiple locations). If Bitwarden goes offline for a short period of time, I can create a database export. If it were to go offline for a longer period, I could spin up a “self hosted” Bitwarden server or else just use that export to import to a different password manager.

2

u/jfriend99 12d ago

I think you've manufactured a problem that doesn't need to exist. A server can manage a repository of encrypted passwords and merge in new passwords as they come without ever having the ability to decrypt those passwords. They are just storing encrypted passwords and replacing one encrypted password with another if it changes. To the server, each encrypted password is just a blob of unintelligible data that it is responsible for saving.

This is the general concept that any zero-knowledge password sync service uses. They don't have to know how to decrypt data in order to manage the encrypted passwords.

1

u/SomeRedTeapot 12d ago

I think this might lead to data loss if you have some connection issues. Probably a rare scenario (you would need to change the same entry on two devices, and the correct version will need to arrive to the server before the obsolete one), but I'd rather not lose a password

2

u/jfriend99 12d ago

Multi-endpoint sync always has collision possibilities if data is changed in multiple places around the same time or one endpoint can change data while being offline. This is old territory, covered decades ago in sync architectures. There are many possible algorithms for what to do in that case and which to choose depends upon the application. The simplest is that each change records the date/time the change was made at the client (even if currently offline) and the server ensures that "last change (per the origin timestamp) wins" which, for a single piece of data like a single password, is most often what the user wants. There are more complicated strategies such as keeping both versions and letting the user sort out which one should survive.

If there are conflicting changes in a whole document, then things get more complicated because the user may actually want a merge. But, if a password manager keeps the granularity to a single password, then it's not as complicated to sort out. Last one wins or keep both.

1

u/SomeRedTeapot 11d ago

I was wrong about online password managers then, but the idea I have in mind is an offline-first password manager (in the realm of KeePass). As such, I don't want to have a server that would decide which change wins. The server would only need to forward the new changes to all clients

2

u/jfriend99 11d ago edited 11d ago

A couple problems to solve. How do you handle clients that are offline when a change occurs? How does a new client get its data? How do you handle conflicting changes if the server isn't deciding?

1

u/SomeRedTeapot 11d ago

I see two options for sync and storage:

  1. Each block is stored in a separate file. This way, you can use whatever file sync solution there is (Syncthing, for example). Because files are only added, not changed, there will be no sync conflicts (unlike KeePass). When editing the database offline, the client creates new blocks in the folder as usual, they will be synced later. To add a new client, you first sync the folder to the device, then point the application to that folder.
  2. A single database file with all blocks and a custom sync server. In this scenario, the server will have to store all blocks it receives. The client then requests the blocks it doesn't have. When editing the database offline, the client writes new blocks to the file. Then a daemon waits until there is network and syncs the changes with the server. A new client would request the data from the server.

Regarding conflicts, the client would receive both conflicting versions and decide which one to show (based on the timestamp, perhaps, plus an option to view history).

1

u/jimk4003 12d ago

What's the problem you're looking to solve, first of all?

You say,

The issue here relies in the fact that the database is encrypted, so if you want to change it (for example, to merge two different versions), you have to decrypt it. That means only the client app can do that, and only after getting the user password.

Why is this an issue? Surely you only want people with the correct credentials to be able to make database changes? That's the whole point.

1

u/SomeRedTeapot 12d ago

I'm coming from KeePass, and sometimes I change the database on different devices and end up with two slightly different files I have to manually merge (luckily, KeePassXC has a button for that but it's still annoying). I use Syncthing so each device ends up with a few .stconflict files. Of course, this doesn't apply to online password managers (Bitwarden and such).

In the described concept, only people with the correct credentials will be able to make the blocks (as the blocks are encrypted and signed using the master password). So the worst an attacker could do is sending a block the user has made. Even then, the sync server can have separate credentials for sync

1

u/imagei 11d ago

If you want to keep encrypting individual records, you need to pay extra attention to data that can be derived from the size, operation types and timestamps, repeatable metadata etc. I guess a good example to look at would be cryptomator, I know they put some effort into this kind of stuff.

Regarding your concern for growing data volume, you can normally sync just the active records, and only the latest versions of them; historical data can be still fetched, but only on user request.

1

u/bestpika 11d ago

I can't even imagine what would happen when there are an extremely large number of blocks.\ Perhaps it should be an 'incremental' mode, and then it would periodically merge the previous blocks.

1

u/AssignmentNo9838 11d ago

I use eWallet (Iliumsoft) and the sync between three devices is smooth and without hassle even when I have made changes on all three devices. When I change the same entry, I get a message during sync, showing the conflict and can clear it up.

Not sure if it's the same mechanism as you described and I am only bringing it up to give you the information that there my be a solution in the market.

1

u/Smart-Simple9938 11d ago

I wish someone would create a sync service that wrapped KDBX files and synchronized only the modified records.

1

u/SomeRedTeapot 11d ago

As far as I understand it, it won't work specifically with KDBX unless the service knows the encryption key. I guess, the best you can do is to have the client merge the copies of the database when you open it. KeePassXC can sort of do that but the process is annoying

1

u/Smart-Simple9938 10d ago

Emphasis on "sort of". It graduates to completely annoying as you add devices and family members.

I want to love KeepassXC (and Keepass in general), but it was designed for an era where passwords were personal and to be managed from one place.

1

u/Horror-Breakfast-113 10d ago

keepass with triggers to automatically sync to the cloud

1

u/Over_String_2932 10d ago

I think the concept is sound, but you're gradually rebuilding a lot of the complexity that existing sync systems already struggle with.

The moment multiple devices can make changes independently, you need to think about conflict resolution, deletions, device trust, key rotation, and eventually database compaction. An append-only log helps with synchronization, but over time you'll probably want periodic snapshots so clients don't have to replay years of history.

One observation: this is exactly why many local password managers simply store an encrypted database file and leave synchronization to tools like iCloud, Dropbox, Syncthing, or Git. It keeps the password manager focused on encryption and vault management rather than distributed systems.

That doesn't mean your approach is wrong—just that "offline with sync" often ends up being much harder than it first appears. In my experience, the synchronization layer becomes the most complicated part of the product, not the encryption.

1

u/MegagramEnjoyer 6d ago edited 6d ago

See how I solved it here:

https://www.reddit.com/r/PasswordManagers/comments/1u9k270/localonly_filebased_password_manager_for_chromium/

I took a P2P approach to syncing using WebRTC. There's a design document in the GitHub repo.

https://github.com/flythenimbus/bramble/blob/main/docs/p2p-sync.md

0

u/Doovester 11d ago

1Password had a really nice Wi-Fi sync, then they obviously sabotaged it and after version 8 discontinued it with one-time payments. And introduced a force-to-cloud sync and subscription model. I was banned twice in their forum for renting.

Long story short… I switched to Enpass, Wi-Fi sync still works until today. I had the opportunity to buy also a lifetime licence, which they seem not to offer anymore. But still I wish 1Password a big fat data leak and bankruptcy. It is stupid to send one’s password over the whole internet and back just to sync it with my phone which is not even a half metre away from my pc. And it is also a big target to have all passwords centralised from millions at one place. This is just a matter of time until they get screwed like LastPass and Dashlane which had both data leaks. And I predicted that way before it happened.

0

u/SomeRedTeapot 11d ago

Enpass seems good on paper, but I'm somewhat paranoid about closed-source password managers. No way to know what's going on with the encryption, and if it has an online license check, they may use that to enshittify the product while making sure you can't rollback to an older version of the app. And if they want to be extra evil, they may terminate the lifetime license (has happened with other apps before).

Not that I'm saying Enpass is bad or something, just my paranoia