As cool as a native code back-end for Bitwarden would be I would be more interested in seeing vendor native mobile apps (Swift/Xcode, Kotlin/Android Studio) and putting the Xamarin code out to pasture. Would also like to see an improvement in the desktop Electron app as well or at least get it to feature parity with the web vault. All of that said Bitwarden is a fantastic product and I recommend that over every other server-based password manager out there.
Why move away from Xamarin? It works. Reduces development needs. Xamarin iOS uses Ahead-of-Time compile which is pretty close to native at that point. Phones are fast enough now to handle a little extra UI layer code like I'm sure Swift and Kotlin have. Most end-users don't even know what Xamarin is.
Bitwarden on iOS suffers from high latency user interaction, it’s much less usable than the iOS native keychain for this reason. I assumed the bottleneck is the public API for password managers, but maybe part of it is Xamarin?
The bitwarden mobile apps are using Xamarin? That's actually pretty impressive...I've never had any of the weird issues with the bitwarden app that I've had with other Xamarin apps in the past.
The desktop app looks and feels like an electron app, so I'm far less impressed by it. At the very least it would be nice to have it in Qt or something like that.
> The desktop app looks and feels like an electron app, so I'm far less impressed by it.
That is because it IS an Electron app.
> At the very least it would be nice to have it in Qt or something like that.
Sure, I hope so too. Unfortunately there are very few serious alternative password managers that are not using Electron for the desktop app these days. Seems like 1Password is on the way out too.
Yeah, it is kind of amazing how quickly 1pw went to hell. It was a great app at one time. Then they forced cloud storage, subscriptions, Electron... it is like they decided to start acting like a private capital sunsetting cash extractor.
I will freely admit I am strongly biased against Xamarin as there are so few cases where I think it's unequivocally the right choice, and Bitwarden isn't one of them. It would make more sense to take the work done in their desktop electron app and use that as part of an Ionic hybrid mobile app than to screw around with the layercake of bugs and mismatched APIs that Xamarin is. Moreover, since this is a serious app from a security point of view it really should go full vendor native IMO.
"desktop electron app and use that as part of an Ionic hybrid mobile app"
Whatever you think of Xamarin, there is a special place in hell for all the buggy JS based mobile software. Its not an improvement, just a different flavour of crap.
On iOS I pretty much stick with Castamatic and Overcast, both are full native iOS apps but neither are open source. I'm sure there's something listed at http://www.NewPodcastApps.com which is iOS and full Xcode native.
So far, Bitwarden has an Android app (two of those didn't), has been security audited (I didn't see anything for those other ones), and the biggest thing is Bitwarden has a much better pricing structure around non business users. It has a free tier and plans for families/non business users, as well as business use. Those others had nothing comparable that I could see except for a limited free tier.
Feature wise (ignoring the mobile apps), some of those seem to have some comparable features like emergency access, sharing, folders, etc, but locked behind a pricing structure that makes them less useful.
So from a look at those other ones, Bitwarden is the superior product for non business/security conscious family use at least. And for business use I don't see how those other ones are better anyway.
I admit Bitwarden is probably the most advanced, but the alternatives I named above (Psono, Passbolt, Passwork) seem not that far behind and some of your research seems a bit superficial.
> Bitwarden has an Android app (two of those didn't)
That's just wrong. All three of the alternatives I mentioned have an Android app. I haven't used any of them, though.
Looking more closely at Passwork, they claim to have open/auditable source code, but I can't find any public code. So they are out of the game anyway.
> Bitwarden has a much better pricing structure around non business users. It has a free tier and plans for families/non business users, as well as business use. Those others had nothing comparable that I could see except for a limited free tier.
Psono's full-featured enterprise version is free for anyone with up to 10 users. I don't see any such generous offer at Bitwarden or elsewhere.
And both, Psono and Passbolt offer unlimited business tiers for only 3€ per user per month which seems to be in the range of what Bitwarden costs. I don't really see your argument for the pricing.
The peculiar problems faced by families, work organisations, 2fa - they've put some time into thing about every sub-problem I've come up with.
Well, just about everything. I'd love if they would let me run my own read only backup servers - ie, a server that mirrors my data stored on theirs, that my device will connect to if theirs isn't up, and that supports a read only version of the web interface.
I’ve been really diving into Rust over this holiday break and reading through code bases like this is really helpful. Little things like a shared db connection are not intuitive on the first pass when everything is under such a strict borrow/move/release paradigm. I’m going to study this a little closer but it still isn’t super clear to me. In other languages I would probably implement a singleton of some sort. I know that can be done with Rust but I’m struggling to find examples that I can understand in the wild. Most examples are small single main.rs files.
I know this is off-topic but isn't Rust meant to be more of a systems-level language? It seems to me that Go would be a better choice for server-side API (assuming .NET 5 and 6 are too bloated and slow for your tastes).
Or is Rust finding a niche in userpace apps even though it was designed for systems level use? I am not saying apps shouldn't be written in Rust, I just don't understand the appeal. What am I missing?
I personally don’t see the appeal of Go. With Rust, I can write a concurrent, safe, and C-performant program with modern programming features like matches, generic programming, and a dedicated package manager (never understood go get). To boot, Rust has a strong ecosystem and the fastest web framework out there (Actix). It takes roughly the same amount of code to do networking stuff in Rust and Go, but with Rust it is more performant and I can sleep better knowing that if it compiled, it is at least safe and won’t have any concurrency bugs.
A quick back of the paper example, I am doing Advent of Code this year and the same exact implementation took 40 ms in Rust and 350 ms in Go. Not to mention the Rust implementation, despite being the same semantically, was more concise and clear due to Rust’s extensive Iterator trait methods. A small difference you might say, but it’s just one less reason for me to switch.
You choose golang because you basically want java with less memory usage and static single binary deploys for your backend server applications.
Go was designed to be a language that development scales very well with it's focus on simplicity and very fast compile speed.
Rust on the other hand, was designed to make certain hard things less hard, at the cost of complexity, ease of learning, speed of development (high amount of restrictions) and compile speed. If you have a multi-million line monolith made in rust, I bet your compile speed and edit-build-run cycle will take a very long time and be very painful compared to the same golang one. Hiring will also be harder because the minimum IQ & experience bar is higher and you couldn't have productive jr engineers get up to speed on it nearly as quickly.
Java is way more expressive and better designed than golang. So no, golang is not Java with less memory. It's also possible to deploy Java as a single JAR file.
Is this more a matter of preference? Some people feel it is more expressive, others feel it is too verbose. Some people prefer the object oriented design principles, others are turned off by them and really just want structs.
I agree the single file argument is not extremely convincing. Especially because engineers are often on Mac on Windows machine and compiling for Linux. While Go does support this, as soon as you have to use a c library dependency (in my experience this was sqlite), then we had to start compiling in the environment we wanted. Easy to solve with docker but deployment wasn't the reason I like Go.
I should spend some time thinking about why but overall I just "feel" more productive with Go vs Java (including Kotlin). Go's standard library, docs (with links to the source code), everything just feels super readable and understandable.
I don't see much debate agains Go using less memory. I can confirm this was my experience as well. My experience is that it uses a lot less CPU as well.
No it isn't. On many times I've been able to simplify golang code that is dozens of line long into something that is only a few lines long in Java, while improving readability and reliability. This is especially useful when exploring a new code base and spending a lot of time perusing boilerplate trying to figure out what's going on.
Whether or not it’s clear significantly depends on one’s familiarity with the language.
I’ve been working through the latest AoC in Rust and it’s been eventually very nice looking once I’ve got all the functional features used correctly, but my Go solutions from last year are also elegantly read.
The biggest difference to me is explicitly managing memory or not. This is neither an explicit advantage or disadvantage though. In some cases, it’s tremendously powerful, and in others, it’s an unnecessary cognitive load.
Good to know! I've been looking at Go because it's "smaller, lighter, faster" than C# but from this description Rust might be a better next language to learn. Thank you!
Do be warned that although interesting and rewarding and amazing in all sort of ways Rust is not easy. Where Go was designed such that it takes hours to pick up, Rust requires weeks, and possibly months before you build the intuition around the borrow checker.
If you've been looking at go, it's really not much of an investment to try it out (I wouldn't heartily recommend it as I dislike the language but you do you).
All those quotes are funny. "Smaller" as in the amount of keyword? Because you definitely need to type a lot more to get the same thing done. "Lighter" as in executable size? I'll give you this for the basic hello world apps. "Faster" ? That's just not true.
learn both. golang is vastly more productive than rust for me. better tooling, faster build times, smaller less complex language.
rust is fantastic for building highly performant safe code at the expense of developer productivity. builds times are atrocious and tooling isn't as polished as golang.
The build times and a major differentiator to me. All my Rust projects with a handful of crates (those in turn have their own dependencies) take tens of minutes to build. In Go, a project with similar dependencies compiles in seconds.
> Or is Rust finding a niche in userpace apps even though it was designed for systems level use? I am not saying apps shouldn't be written in Rust, I just don't understand the appeal. What am I missing?
A good type system is appealing regardless of the context.
The ecosystem can also be nice (or known) e.g. serde is amazing when dealing with all sorts of serialisation schemes. The tighter resource control can also be useful for application space, and it was most certainly one of the goals for vaultwarden as complexity aside the heft of the official server was a large part of the motivation (e.g. the ability to run it on a Pi or a small VPS)
An other longer-term option is that I can imagine e.g. coding something in rust then extracting its core or bits and bobs to libraries, and exposing that in C or Python or what have you. Nowhere near as attractive (or easy) with Go.
Once I got used to writing in Rust, I found it really hard to mess up. I sort of like it for applications, although some idioms can be a bit verbose and hard to parse visually and mentally.
First, thanks to default immutability of variables and the borrow checker, I trust that I'm far less likely to accidentally mutate something and cause an action-at-a-distance bug.
Second, I absolutely love idiomatic Rust error handling of returning a Result (especially combined with the question-mark operator). It forces me to deal with error conditions. Unlike C# or Python or Java or C++, I don't have to worry that any code could throw an exception at any time. (Rust code can panic, but panics generally represent unrecoverable errors — see http://joeduffyblog.com/2016/02/07/the-error-model/#bugs-are... ) And unlike Go or C, I don't have to remember to check the error every single time.
I still have to write functionality tests for Rust code, but once I've done that I feel like the code is mostly locked down. It's harder to get to that sense of security in other languages.
> Unlike C# or Python or Java or C++, I don't have to worry that any code could throw an exception at any time. (Rust code can panic, but panics generally represent unrecoverable errors — see http://joeduffyblog.com/2016/02/07/the-error-model/#bugs-are... )
I just don't understand this logic. Exceptions are the same (C++ exceptions use the very same unwinding mechanism than panics in Rust as far as I can see), why would you forbid yourself to catch_unwind ? It's just making your software worse for no reason, users always will be happier with an app that shows a small "warning: internal error. Document backup saved in </some/place/>. $software will now shutdown", than seeing macOS or Windows's crash dialog.
For application code, you can change the behavior of Rust panics. Although I haven't verified this myself, I fully expect that you can achieve saving a document and exiting gracefully.
The distinction is that panicking should (almost) never be used for recoverable errors. You can, but that's not idiomatic and would only be appropriate within the confines of your own application. Recoverable errors in Rust should be handled by return values, typically via either Result or Option.
This is unlike all the other options I listed (except Go, and C++ with exceptions disabled), where it is idiomatic to use exceptions to handle recoverable errors.
In theory, (strictly) checked exceptions are equivalent (isomorphic) to error codes as an error handling mechanism. But as soon as unchecked exceptions are allowed, it all falls apart and you must contend with the problem of "invisible control flow". Not having to deal with "invisible control flow" in Rust is one of the things that makes me much more confident that the code actually does what it looks like it does.
The Joe Duffy blog post I linked to earlier compares various error handling methods, including checked exceptions. It's very long, but interacting deeply with this blog post helped me to level up my understanding of error handling. FWIW I did a presentation on Duffy's article for the San Diego chapter of Papers We Love: https://www.youtube.com/watch?v=GwPBC4mWfFQ
I know that this is a fairly contrarian take, but I strongly believe than the emphasis on idiomatism is more harm than good. The only thing that matters is the language spec - everything that fits in there is kosher. Idioms just create pointless fights and tabs vs spaces situations where there doesn't need to be any.
> Not having to deal with "invisible control flow" in Rust is one of the things that makes me much more confident that the code actually does what it looks like it does.
no, you just choose to ignore it. I can also write C++ code with throw and no try..catch and that will give the same result (as I pretty much use exceptions like one would use panic! in rust). I don't know anyone who would say that this is a good idea. My sweet spot is to have a few catch handlers around the main loop which catch 99% of the unrecoverable issues, and sometimes, when it turns out that an issue has a way to be recovered (or that maybe it doesn't matter), then someone gets a try..catch block.
Like most articles about exceptions, that Joe Duffy post talks about the problem of "where the control flow goes". I've written my first lines of C++ something like 17-18 years ago now and not once it has actually been an issue. Consultants sure do love selling it as one though.
> I know that this is a fairly contrarian take, but I strongly believe than the emphasis on idiomatism is more harm than good.
My response is that adherence to common idioms is simultaneously beneficial and harmful. It is beneficial because shared assumptions and shared understanding facilitate cooperation, yet it is harmful because it impedes innovation. Whether it is more beneficial or more harmful on balance depends on the situation and on individual taste.
I'd like to think that our perspectives are compatible.
> > Not having to deal with "invisible control flow" in Rust is one of the things that makes me much more confident that the code actually does what it looks like it does.
> no, you just choose to ignore it.
I guess you could characterize things that way. For example, in the Rust library code I write, I choose to ignore certain unrecoverable errors — e.g. out-of-memory panics from allocating ordinary sized objects, even though such panics can theoretically occur.
But the distinction here is that I also expect e.g. invalid argument values or "file not found" errors to be handled via Rust's Result type. I don't choose to ignore such events — I expect all recoverable errors to be handled via visible control flow, where you can identify every location in the code that such an error might occur. This makes it easier to reason about control flow for all circumstances save unrecoverable errors.
> My sweet spot is to have a few catch handlers around the main loop which catch 99% of the unrecoverable issues
Yes, that's an Anders-Hejlsberg-endorsed way of doing things. "The exception handling should be centralized, and you should just protect yourself as the exceptions propagate out to the handler."https://www.artima.com/articles/the-trouble-with-checked-exc...
I think the preference for one way of doing things can depend on what problem domain you work in. That approach is highly suitable for applications programming.
(Duffy has done a lot of work on operating systems; my biggest projects have been libraries.)
> Consultants sure do love selling it as one though.
EDIT: I'm not very happy about that take, and I originally wrote up a lengthy response — but it turns out I had incorrectly recalled that this was not the first such interaction we've had. (I was recalling an obnoxious post from a different European with the first initial "j"). I've deleted my response because it's OT and not worth dealing with if it's not something recurring.
> And unlike Go or C, I don't have to remember to check the error every single time.
How do you mean? I’ve been writing Rust frequently lately and you still have to check the case. Do you mean that the compiler will nag you if you stunt so you don’t have to remember to do it because you’ll be reminded?
That’s one of the things common Go linters do that I wish was built into the compiler. It’s silly that an unused dependency is a compiler error but an unchecked error/return value is not.
I mean that in Rust, you have to work kinda hard to drop an error on the floor and leave it unhandled.
It's easy and idiomatic to write code which calls `unwrap`, so that's what everybody does when they don't want or need to write sophisticated error handling code. But that's not the same as forgetting to check a return value — when something goes wrong, `unwrap` panics.
I mean, if you're determined you can definitely drop an error in Rust, e.g. with a `match` arm that does nothing. But the easy path is to `unwrap`.
I started off with standard materials like "Rust By Example". I also tried to use Rust for simple stuff like command line utilities.
Then I started working on a personal project, which motivated me to bull through lots of difficult problems. (This personal project happens to have been bindings for Apple Core Audio, but the point is to pick something you care about enough to motivate yourself.)
Finally, I've found users.rust-lang.org invaluable.
The first major challenge for me was the error handling ("WTF is `Box<dyn std::error::Error>`? What is `Box`? What is `dyn`?"). It got in the way as soon as I even tried to write command line utilities. Once you learn it, it's amazing, but out of the gate I continually stumbled and fell flat on my face.
The second challenge was harder: coming from OOP languages, I was accustomed to structuring everything as large mutable heap-allocated classes with private fields, accessors, and an emphasis on opaque data structures and encapsulation. That is not idiomatic Rust, so I had to unlearn it and discover architectural alternatives.
I don't know exactly how long it took before I felt comfortable, since I was learning in disconnected spurts rather than immersively all at once. It wasn't quick, though.
It's definitely true that being good for writing services wasn't really a big design goal of rust and it's far from the lowest friction language to do it in. However it is still a mainstream high performance language with a rich type system and amazing compile time error checking and that makes it attractive to use for many other things if you are already used to it.
Programming languages like C and C++ have been used to write user space apps for decades. A language which can only be used for kernel space code is a niche within a niche within a niche.
If Rust were only capable of that it would barely register on anyone's radar and be dead on arrival. In fact it's only recently that serious work was started on using Rust in a mainstream kernel (Linux); every project that Rust is known for is running in user space.
People are confused about what system programming means and a lot of that confusion comes from parts of the Rust community which want to carve out a niche for Rust and keep claiming that Rust is particularly suited to system programming, as opposed to Go or D or other languages which are in reality also capable of tackling many system programming jobs, but have a garbage collector.
Why are the Rust proponents so triggered by what seems to be an honest question about the popularity of Rust? I don't know the first thing about Elixir or Erlang but I realize there are some powerful properties of BEAM and if there seemed to be a trend to rewrite apps into BEAM apps I would want to know what am I missing out on that, if clued-in, I would join the rush as well. I think that's what OP is saying here (perhaps clumsily) but why vote the question down so aggressively? Makes you look like a thin-skinned lot who don't like to explain yourselves which would be a reason to avoid the "Rustacean" community.
To be fair, if there were a trend to write things in Erlang and someone posted “why use Erlang and not Rust? what am i missing?” I would also expect that to be down-voted. Nothing specific to Rustaceans here. I don’t agree with downvoting the comment because it is contributing to a conversation which is what HN is all about, but it was probably the assumption that Go is already the winner in the space of networked apps when Rust has many good technical qualities as well. Like you said, clumsily worded.
Where are you seeing "triggered" comments? Every reply to that person has been very balanced and neutral, and the question seems to have a positive vote at this point.
I actually know Go very well. Wrote it for years. I like learning languages and using them in all kinds of different ways. I see a lot of overlap with Go and Rust. My interest in Rust is the small runtime and potential code reusability between server, client (mobile and web [wasm]). No GC means much smaller runtime in WASM I’m hoping.
I'm not very opinionated on Rust's comparison to other languages, but to me it does seem like rewriting things in rust (which now even has its own acronym RIIR) has become trendy.
Trendy enough that the very fact that rust tools happen to be written in that language is used as a main selling point.
This is true for basically every budding community. "Rustaceans" writing tools for writing rust, in rust, seems like a gimmick, but every language goes through this period. JavaScript is probably the single biggest offender I can think of, but other examples include rewriting Vim plugins in Lua even though neovim supports vimscript, rewriting literally anything in Go, rewriting python libraries in Julia, etc.
I don't think the example of rewriting python in Julia is the same. Most python libraries get re-written (or implemented) in a faster language. If your choice is rewriting in C++/Fortran, or writing rewriting in Julia, The Julia version will be way nicer to use, and will probably be faster than calling the low level library from python.
You're talking about rewriting performance sensitive code when it makes sense to do so. I'm talking about rewriting random libraries because developers like to wallow in their tooling.
Go can't be used for many "systems programming" problem domains because it's garbage collected. That objection is always looming when people try to call Go a "systems programming language", so I think a lot of people now classify Go as an applications programming language instead.
The only people who did that was the Go team itself, and they did so in contravention of the usual interpretation of the term, as by it they meant either the completely meaningless "you can built systems with it", or that you could build systems services or utilities (which is not what is usually meant by "systems language").
I'm not aware of any official or standard definition of system programming. There's application programming and anything which doesn't fit in there is system programming which can be low-level, middleware, etc.
Go is appropriate for writing services / daemons, command line tools, servers, etc. It's not well suited for writing operating system code and very performance-intensive code (databases, audio/video, etc), but there's still a big overlap with Rust.
It seems to me that this whole discussion keeps coming up because parts of the Rust community are worried about the competition. And they have reason to be :-)
I‘m on Mobile right now, but in that case you’d wrap your db in a Arc<RwLock<~>> (or Rc<> if you don’t need concurrency.). Then, anytime you need to access the DB, you’d try to lock the RwLock’s Writer or reader.
It is a matter of tradeoffs and requirements. Arc<RwLock> is a solid solution for most use cases. If the requirement is (just making up an unlikely extreme scenario) to have a huge amount of threads which constantly lock the RwLock a better solution might be to just open multiple connections per database, each per thread. SQLite, for example, is build with this in mind.
For a reasonable amount of locking, The Arc / RwLock dance offers good performance (other languages, like Swift, use something like Arc for every property access (although the compiler tries to optimise it away)).
The safety is actually better because you're forced to think about the failure case. I don't have good memories of Objective-C where some Foundation calls don't throw (in they don't have an error parameter), but just throw random undocumented exceptions. (Not saying that some Rust calls don't panic, but knowing that something can go wrong is much better than learning about it in production).
Under the hood most (all? Hesitate to say all but probably all) clients will have some form of mutex lock to at the very least control access to the file (eg socket) they use to pass messages to the server. If you find an example otherwise I’d like to hear it, though do keep in mind the mutex may not even be implemented in userspace.
Which is to say, accessing a client may or may not be thread safe (depending on the client implementation) but assuming it’s not a multiplexing client, it almost certainly uses some kind of locking mechanism under the hood
Even if it is a multiplexing client, if you saturate the internal clients you will either need to wait for a client to stop writing to its socket (through perhaps a lockless consumer model) or create a new internal client (slow).
In Rust, abstractions tend to be zero-cost, but things that actually impact runtime are as fast as you write them.
Concurrency problems don't magically disappear because your language can check for them. You still need to use memory-safe patterns, but the compiler will force your hand and prevent you from doing unsafe things accidentally.
In the end, this makes it far easier to build correct, concurrent applications. If you decide to try some fancy new pattern that doesn't require locking, the compiler can guarantee the memory safety of your new implementation.
Yes, but I can see it being worth while when you can spare the tiny amount of overhead, especially in a project that's meant to be self hosted like this.
When Lastpass began charging for multi-device access, I sought out free alternatives that could be self-hosted, because I figured I wanted to own my passwords, even if they're encrypted at-rest, and I didn't want to have my life held hostage by a company that has a change of heart regarding the cost of password availability.
I had heard of Bitwarden before, and looked into it. The stack struck me as incredible for a security product: numerous services that need to be updated in-sync provides a wide surface area for attack, and ultimately encourages you to use their managed solution, IMO. Keepass is better, but the surface area is still quite broad.
Ultimately, I settled on `pass`[1], made by the creator of wireguard. It takes advantage of a clever inversion of responsibilities, where clients store the passwords and sync with git. You can have a "dumb" git remote with no local private key; even if compromised there's not much to consume. Encryption is powered by GPG, so the security surface area is managing your private keys, which is a very well-understood problem.
It's probably the best product for security-minded hacker types. As a simple offering (a shell wrapper around GPG + git), it's easy to build clients for, which means there are many OS/browser-integrated clients to choose from. Similarly, it was trivial to import everything from Lastpass.
Maybe most important of all, once setup, it passed the spouse/parent test for me. They needed me there for setup, but once setup I haven't needed to give additional support for the last year, ymmv.
LastPass was great for almost 10 years until LogMeIn bought them and they've been messing around with the business model and pricing ever since. I paid $12/year for several years to get mobile access. Then after they were bought I was somehow automatically upgraded to their premium plan for $36/yr. They had given notice but it went into my Promotions inbox and it was months before I realized it. Every year since they've tried different pricing models and it's been frustrating to keep up with.
I had been planning on switching over to Bitwarden in a couple months when my current LastPass subscription runs out, but I just found out that LogMeIn is spinning them off into a separate company again - https://www.zdnet.com/article/logmein-announces-plan-to-spin...
Trusting a company with your most valuable long-term data (passwords, medical/family records, etc.) is a losing game on a long enough time horizon (5 years, let alone 15 or 25).
You can arbitrage by trying to choose more than one. But IMO, the most robust solution is to make your data "dumb" and commoditize the storage layer.
With something like pass, I have my passwords physically located on all my devices, encrypted at-rest. Plus, I have a backup on a home server that can be regularly backed up to any commodity storage provider (backblaze, aws, whatever).
With this, you'd need to both lose (1) all your devices (2) internet access to those devices. This kind of thing is a bit predictable, and can be mitigated.
With a managed secret-manager service, mere corporate shenanigans or internet connectivity problems can take them away from you! Those are less predictable, and the only mitigation is to move to a service that doesn't have these problems.
> They had given notice but it went into my Promotions inbox and it was months before I realized it.
That's why I have them disabled in my gmail accounts, I have several missed important emails because they landed in the wrong section. I disabled them in my work email too. My boss keep it on and it causes my boss issues with missing RFQ and requests.
I went with Keepass, it is free, open source, cross-platform. Been using Keepass for 10 years. I control my data and my file, so I don't need to worry about potential data breach which several other SaaS password management failed to keep it secure. My keepass database (vault) resides in my OneDrive and synced across all of my devices that have Keepass. And I like Keepass will generate a backup of the database before saving the entry in case of corruption. It happened to me once 5 years ago and it was in Dropbox storage that time, somehow Dropbox failed to sync the change and ended up corrupting the synced vault across of my devices. I have 260+ entries in my keepass.
Neat thing about Keepass, it can check haveibeenpwned.com and compare the password in my vault. It generated a list of password that need to be changed.
This is why I switched to Vaultwarden. The migration was at least simple (self-host server, export LastPass, import to BitWarden) and now I can save TOTP too. And syncing works better.
I don't have any experience with running the bitwarden server, but the primary selling point for this is that it is less resource intensive than the official server backend. The official backend is written in C#, and is currently using .NET 5. I haven't ever felt like .NET apps were particularly bloated, but I guess it's possible to write bloated code in any language. Does anybody have any insights as to what is done poorly in the official version? I also wonder if the performance improvements in .NET 6 would make a difference.
It's been a few years since I looked at the official server setup (I immediately switched to bitwarden_rs, this project), so maybe this isn't as true today:
Mostly it's that the official setup is the same thing that runs their free/paid hosted service. By design, it is quite split apart into separate areas, presumably so they can scale independently of each other: https://github.com/bitwarden/server/blob/master/SETUP.md
But most people are going to want to host self-hosted instances for themselves, their families, or maybe a small company. The official server might be the best route if you're deploying to thousand of users, but that won't be most people.
Another benefit is that this flips all of the "paid" feature flags to true. If you self-host Bitwarden's official setup you still have to pay a subscription to use paid features.
> Another benefit is that this flips all of the "paid" feature flags to true. If you self-host Bitwarden's official setup you still have to pay a subscription to use paid features.
As a developer and cheapskate user myself, I understand the appeal of this.
As a product builder, I struggle with what this means to build a business upon an open core model.
I would have more of a problem with this if it was a simple fork with a few variables modified to enable features rather than a complete rewrite with a compatible API. None of the paid features are technological breakthroughs (e.g. one just checks HIBP to see if passwords have been leaked) so, imo, it's really the re-implementor that did all the work.
I do feel a little bad using the client applications for free given their business model revolves charging for the backend only.
Interesting perspective.
Could you explain why and for whom it's bad?
I can't completely tell from your comment - but do you tend open-source or closed-source as an alternative?
Apart from the pain around dealing with .NET itself, Bitwarden's official server only supports MSSQL which is a nightmare in pretty much every conceivable way (licensing, tooling, packaging, and so on). Vaultwarden seems to support plain old Postgres and SQLite.
> MSSQL which is a nightmare in pretty much every conceivable way (licensing, tooling, packaging, and so on).
Licensing, sure. It's more convenient with Free software for small self-hosted instances... But the rest? You can even get a Linux build in a docker container supplied by MS...
I switched after my instance stock because of a failed migration - this was my fault cause I aborted the upgrade - and I couldn't get it to upgrade anymore.
Iam very happy with vaultwarden ever since
This is the biggest reason for me. I have no problem with .Net and have more experience with C# than Rust, but MSSQL was kind of a deal breaker for me to self host.
Most of the resource usage is on the local installed MS SQL. .NET 5 (core) performance is great. .NET can look like it's uses a chunk of memory while that is configurable as it pre-allocates free space for garbage collection.
I do still run the bitwarden official server. While I would not considered bloated by 2021 standards, it still eats up more that 2GB of RAM for my single-user setup... It prompted me to upgrade the VPS I run it to a more expensive version with more RAM.
So yeah, resource usage is real, especially if you plan to run this on a Pi or on small cloud intances.
I love this, it's how I run my password manager (Using docker-compose and traefik for the ui). Bitwarden works very well in iOS and Android and on Windows10 and in Firefox. Syncs are always instant, I used to use KeePassXC with NextCloud but inevitably I'd have syncing issues (admittedly, not very often). Not anymore.
I still have to dig into the Organization feature to share passwords with my partner.
> Syncs are always instant, I used to use KeePassXC with NextCloud but inevitably I'd have syncing issues (admittedly, not very often).
I uses KeepassXC with OneDrive without syncing issue. I set OneDrive on all on my devices to keep the KDBX file locally and sync it from the cloud if there is any change. Only syncing issue I have is with Dropbox, moved to OneDrive and never have issues with keeping it synced so far. If OneDrive went down, the KDBX file will be there because it is set to keep the file locally.
How much of a difference in size is it between the official ASPNET Core app and the Rust app? As I understand it, deploying on prem with the official server you would deploy using Docker; is there a test suite to simulate dozens of concurrent users and results showing the difference in resources being used?
I have been using Vaultwarden for all my home needs for some time and I love it. I host it on a raspberry pi in a docker container and have had no issues whatsoever.
The way I understand it, the server component is "zero knowledge", meaning you decrypt on clients with your password and the server just serves an encrypted blob. Am I right?
Assuming you're correct, the parent question is still valid. I think you'd at least want to have some redundant backups to protect against loss (not compromise).
We replaced our legacy flash-applet dependant password vault at work with Vaultwarden and it's actually pretty good. With the recent "disable private vaults" feature our biggest complaint about it was solved.
no GC no JIT, server starts instantly, you need to allocate less resources, and it's easier to install, no runtime dependencies, usually, if done correctly