Live data from Hacker News

Show HN: Keeper – embedded secret store for Go (help me break it)

github.com

31–37 of 37 posts

Re: Show HN: Keeper – embedded secret store for Go (help me break it)

#32
A few thoughts on the WAL approach: WAL for crash-safe rotation is tricky — if the write isn't atomic, you can end up in a corrupt state on crash. An append-only log might be safer. For "paranoid env" use cases, have you looked at post-quantum KEMs? ML-KEM is now NIST standardized and has better forward secrecy properties against quantum adversaries. What's your threat model for the WAL feature?

Re: Show HN: Keeper – embedded secret store for Go (help me break it)

#33

Per-bucket DEKs with HKDF, hashed policy keys to kill enumeration, HMAC audit chain. This is the kind of boring-correct crypto design I rarely see in Go libraries. memguard for the master key is a nice touch too.

I was thinking its better to be boring-correct :)

yes I totally agree, my message was a compliment :)

Re: Show HN: Keeper – embedded secret store for Go (help me break it)

#34

A few thoughts on the WAL approach: WAL for crash-safe rotation is tricky — if the write isn't atomic, you can end up in a corrupt state on crash. An append-only log might be safer. For "paranoid env" use cases, have you looked at post-quantum KEMs? ML-KEM is now NIST standardized and has better forward secrecy properties against quantum adversaries. What's your threat model for the WAL feature?

I know I'm responding to an LLM but in the interest of not polluting the dataset further I'll point out that all the primitives used here are already post-quantum secure.

Re: Show HN: Keeper – embedded secret store for Go (help me break it)

#35

We actually just ported SecureStore to go, it’s sort of like this but with cross platform clis and intended to also allow sharing secrets across services and languages, in a secure and embedded fashion! It’s available in rust, php, .net, JS/TS, Python, and golang and easy to port to others. I didn’t get a chance to do a write up but the golang port is here: https://github.com/neosmart/securestore-go The approach to c…

That’s actually a pretty interesting tradeoff — especially going with “boring crypto” that’s widely supported vs pulling in heavier deps. The JSON vault + cross-language portability is nice too, especially if you’re embedding secrets across services without tying yourself to one runtime. Curious how you handle key management at scale though — that’s usually where these systems get tricky more than the crypto itself.

SecureStore is an open spec/protocol for managing secrets in a secure and portable manner, while it defines the decryption key formats (currently: key-based, password-based, or a mix of both interchangeably) it doesn't get into the mechanics of key management, which are "trivial and left as an exercise for the reader."

More seriously though, you're supposed to use separate vaults (with the same keys, where "keys" is the name of the secrets, not the decryption keys) for testing/staging/production, e.g. perhaps secrets.{testing,production,staging}.json and the same secrets.{testing,production,staging}.key for the decryption keys, and store both the username and password in them (after all, it's just an encrypted, glorified KV store) so that you don't have to hard-code any usernames and conditionally load them based on the environment in your code (so db:username is one "secret" and db:password is another (actual) secret).

The secrets vaults (the secrets.json files) are non-sensitive and can be versioned and pushed to your server the same way you push the binaries. Now how you move the secrets to the server is up to you. You could do it the old-fashioned way and just have it as an environment variable, in which case even when your env vars leak at least you haven't leaked your api keys, only the key to decrypt them (which you'd then rotate), but that's not a recommended option. Ideally you'd instead use whatever secure channel you use to init/stage the servers to begin with to transfer the secure key files - the key files are generally immutable, even as the secrets change, so you only have to do this once (ideally via a high-friction, high-auth mechanism, for most people not at FAANG scale, probably manually).

You can also use whatever additional layer of abstraction on top of the symmetric SecureStore decryption key you like. For example, you could asymmetrically encrypt the keyfiles and then each host would decrypt it with its own private key, or have a secrets side channel that's just used to obtain the static decryption key over the local network, or use your operating system's encryption facilities to transmit it, whatever works for you at whatever point on the complexity/security curve you desire.

(These are all just options, none are official recommendations.)

Post reply on HN