416 karma · joined March 10, 2011
MIT PhD 2008 from the PDOS group
[ my public key: https://keybase.io/max; my proof: https://keybase.io/max/sigs/qfuA9DvtaEpA5I3h42XnrOdlozCYGfn3nNsn492YAvU ]
https://github.com/foks-proj/go-foks/blob/main/lib/merkle/bi... https://github.com/foks-proj/go-foks/blob/main/lib/merkle/cl...
I'm not sure exactly what system you're describing, but I hope it doesn't involve hand-marshaling and unmarshaling of data structures. Your requirement (b) seems at odds with forward-compatibility. Lack of forward-compatibility complicates upgrades, especially in federated systems when you cannot expect all nodes to upgrade at once.
I might be biased, but it's been possible to write a sufficiently complex system (https://github.com/foks-proj/go-foks) without feeling "tortured." It's actually quite the opposite, the cleanest system I've programmed in for these use cases, and I've tried many over the last 25 years. Never am I guessing how to verify an object, I'm not sure how that follows.
I also think it's worth noting that the same mechanism works for MAC'ing, Encryption and prefixed hashing. Just today I came across this IDL code:
struct ChunkNoncePayload @0xadba174b7e8dcc08 {
id @0 : lib.FileID;
offset @1 : lib.Offset;
final @2 : Bool;
}
And the following Go code for making a nonce for encrypting a chunk of a large file: pld := lcl.ChunkNoncePayload{
Id: fid,
Offset: offset,
Final: isFinal,
}
hsh, err := core.PrefixedHash(&pld)
if err != nil {
return nil, err
}
var ret [24]byte
copy(ret[:], (\*hsh)[0:24])
return &ret, nil
As in signing, it's nice to know this nonce won't conflict with some other nonce for a different data type, and the domain separation in the IDL guarantees that.I think this system is nice because it gives you compile-time guarantees that you can't sign without a domain separator, and you can't reuse a domain separator by accident. Also, I like the idea of generating these things randomly, since it's faster and scales better than any other alternative I could think of. And it even scales into some world where lots of different projects are using this system and sharing the same private keys (not a very likely world, I grant you).
(edit on where the OIDs can be, and added another CVE)
The best docs for the KV store are in the white paper, Section 5.1. White paper is linked to from foks.pub
Postgres seemed to check all the boxes for me. I wanted to keep things very simple at first in terms of setup and ongoing management, so didn't introduce other storage backends for other parts of the system.
I wonder if the policy you describe could be implemented as world-visible team with world-visible users. Others have commented on the need for something like this, so I think it should be pursued with high priority. What's slighlty fuzzy to me is how these totally world-viewable teams and users would interact with more closed-down users on other servers.
- limiting users to delete/push/force; this is possible but I don't see how to cryptographically guarantee it. The server can't really help since it doesn't know what's a pack, index data block or ref. The clients can enforce this policy, but then it would be possible to make an evil client that skirts the policy. How much protection do you think you need?
- the server repo right now is implemented 100% as a postgresql DB, so yes, I think that means it's incremental backup-friendly? [1]
- e2ee git has trouble being as efficient as regular git since the server can't tell you which blocks it has; however, there are pretty good optimizations made using indices and packfiles, the white paper has more details, and I hope to write a blog on it soon.
- I'm not sure about the sqlite question. Is there a good way to backup sqlite incrementally over standard git? If not, then maybe the KV-store is better fit for this application.
I agree that git over E2EE is the best storage, even for things like PDFs and photos. Yeah, FOKS should be hostable with a very thin VPS. The storage needs will scale (n log n) as the number of users due to the Merkle Tree, but for small n, this is likely fine!
[1] https://www.postgresql.org/docs/17/continuous-archiving.html...
I wonder, what sort of interface is right for you? A library to compile against or a CLI app to shell out to? If a library, which languages?
This is a great point and I thought a lot about this. This is the sort of thing that can be changed later if it's really a good idea, but I got to thinking that having non-local admins would mean more server-to-server communication and more server-to-server trust, and I was trying to avoid that.
Imagine alice@foo is an admin of bluejays@bar. One thing alice@foo will need to do is to make signed changes to bluejays@bar, when adding or removing members, let's say. Right now, the server at bar will check the validity of these signatures, that they were made with the alice@foo's latest key. So in other words, there would have to be some way for bar to authenticate to foo to allow bar to read alice's sigchain and to determine her latest key.
I was thinking that keeping foo and bar separated was a good idea both in terms of privilege separation and keeping the network simpler (which would in turn be good for uptime and would simplify software upgrades).
The KV-Store and Git server are implemented as "applications" on top of the FOKS infrastructure, so they aren't coupled. They see a sequence of Per-Team-Keys (PTKs); they use the older ones for decryption and the newest for encryption. I'd really love to see all sorts of other applications built on top of FOKS but we might need to do some work as to nailing the right plugin architecture.
The add vs invite distinction referred to above is because servers can choose different visibility policies. You can set up a server at foks.yourdomain.cc, and set it to "open-viewership", which means that any user can see any other user by default. If you and Bob are both on that host, you can add him to your team without his permission. But other hosts, like foks.app, do not work this way, and Bob has to authorize you to view him.
There is very little server-to-server communication, which simplifies the design and software upgrades.
- As Zoom employees, our primary objective is now to bring the technology at play in Keybase to Zoom products.
- We are still making regular updates to Keybase. These updates consist primarily of bugfixes, security fixes, performance improvements and patches and updates to third party libraries. For instance, the app is currently undergoing a major rewrite to be compatible with recent versions of React and React Native. We are not currently pursuing any major new features. The paper trail for these updates is visible for all to see here: https://github.com/keybase/client/tags
- The current plan -- which can be inferred from our ongoing maintenance to the product -- is to keep Keybase running in a performant, usable, free, E2EE, high-security form for the foreseeable future. Should this plan change, we promise to give as much advance notice as possible.
There goes my weekend!
When we first started Keybase, we used Slack as other teams did, but were gradually moving all Slack-based workflows over to Keybase. As such, we didn't use it for anything beyond communicating when Keybase was down. But I was very worried. I knew I used a good, random, one-time password for Slack, so it couldn't have been that the password was stolen from somewhere else. Had my computer been rooted? Had my side-hustle password manager been compromised (oneshallpass.com). I immediately contacted Slack security and asked them if this issue was on their side, and they neglected to point me to the relevant blog article from 2015 (which didn't detail the extent of the compromise, we now know). They just said they take security very seriously and hinted I was at fault.
In the subsequent few weeks, I reset all of my passwords, threw away all my computers, bought new computers, factory-reset my phone, rotated all of my Keybase devices, and reestablished everything from the ground up. It cost me a lot of time, money and stress. In the end, I was pretty sure but not 100% convinced that if I had been rooted, that the attackers couldn't follow me to my new setup. But with these things, you can really never know for sure.
I got the email today that my account might have been compromised in the attack. I would say for sure that it was compromised, and I can breathe a big sigh of relief, that was the explanation I wanted to hear all along.
It was great to know throughout this ordeal that the product we're building --- Keybase --- solves this problem in a fundamental way, not with adding further workarounds (2FA while better than just password alone, reminds me a bit of the 3-digit verification code on the back of your credit card; and if Slack's credential database is compromised again, 2FA won't help at all). With Keybase, all of your data is E2E encrypted, and your encryption keys never leave your device. A would-be attacker who compromised our database would have no ability to access any important user data.
Summary: estimated cost to me:
- $5000 worth of hardware
- 60 hours of labor
- 25 hours of lost sleep
- 10 additional hours of team effort
Fortunately: * Keybase does not communicate sensitive information in slack such as cap tables, financials, employment decisions or compensation discussions, team reviews, company devops secrets, stupid memes that could be taken out of context, or private DM'ing. Basically we just use a `#breaking` channel in Slack, for when we break Keybase.
* Keybase itself is immune from this kind of break-in.
Edits: wordsmithing and improvementsAlso: Import your Slack team to Keybase: https://keybase.io/slack-importer