Cool! I've love to hear more about the security and crypto design. I started writing up some questions but after asking so many it feels like I should just check out the code and answer some of them for myself. Still, I left the discussion here in case you're interested :)

I've been working on a similar tool in Rust: https://github.com/ketralnis/secrets. My focus has been less APIs and more person-to-person (e.g. sharing the team's twitter password between humans that need to use it) but I'd love to hear how you've solved some of the conceptual problems that I've struggled with in trying to make it secure.

Some issues that I've struggled with:

1. withstanding attacks on the file format, some of which are described in this paper: https://www.cs.ox.ac.uk/files/6487/pwvault.pdf. My answer has been the logging system that I talk about in Auditing below but I'd love to hear how you withstand some of these attacks in your system where it looks like you don't even control the file format (is that mysql?)

2. bootstrapping trust. how do I know I haven't been MitM'd, and how can I avoid having to trust the server? My system has a public/private key for every user, so when I share a password with you I'm encrypting it to your public key. The worst possible case then is that I inject my public key claiming to be you because then I get the passwords instead of you. Preventing this while also allowing for public keys to be rotated after a compromise of a client machine is currently stumping me. My current solution is to keep a record of every public key I've seen before, when I see a new one prompt the user to double check it out-of-band (like SSH does), and to just refuse to ever use a new public key for a user that I've seen before. But I bet that users don't actually check this, just like with SSH. And ideally I wouldn't rely on less secure out-of-band communication channels.

3. And speaking of verification, here's how I'm asking users if everything looks right:

=== secrets.vm ===
common name: secrets.vm
fingerprint: b957e10c998faa9909cff3ba4ec35485d04708c3ecc7481fe14d7f07bc0229cd
public key: c15e697e4807793ef8a9461a7b2c6cf2266d1ec1480a594e83b54e7b75e07702
public sign: f1db594eb55fe97657c57f2aa01afd1210a46d42d80d5552ac4d548162d4968e
mnemonic: AM ROBE KIT OMEN BATE ICY TROY RON WHAT HIP OMIT SUP LID CLAY AVER LEAR CAVE REEL CAN PAM FAN LUND RIFT ACME
does that look right? [y/n]

AFAICT these word-based (it's rfc1751) or sentence based (as recommended by https://www.usenix.org/conference/usenixsecurity16/technical...) are the best we have but do users actually verify these? How do you help your users prove that your server is really your server before they store secrets in it, in a way that they'll actually verify?

4. Auditing. How can I, as an end user or as an admin of the server, prove that the server hasn't been tampered with to inject rogue keys? Right now I have a sketch for a merkle tree type log system where the server (1) logs every action (2) links every "fact" (a key, a secret, a user) to an entry in the log and (3) signs every log entry along with the log entry before it. Then a user can reconstruct the current state of the database to make sure that it matches. The upside is that it's pretty hard to forge, but the downside is that it's prohibitively expensive to verify: you really have to check the whole thing so you don't want that happening every time you retrieve a secret. And there are some tricky bits like making sure that the log doesn't have orphan entries that are easy to get wrong. Do you have a good solution to the auditing problem?

5. Keeping the crypto itself simple and auditable. I use libnacl for the actual crypto and openssl for TLS. I've found that simply writing down every way the crypto is used (https://github.com/ketralnis/secrets/blob/master/DESIGN.md) that I've found a lot of cases where it was too complicated and likely to be messed up. Finding that out made a big difference to me in how I write it: now I describe it first and then write the code and that has made a huge difference in keeping it simple. I don't see really any documentation on your crypto, how do you know you're doing it right?