Eating Our Own Cooking - NoPorts for Secrets Management

TL;DR

We chose Vaultwarden for our shared secrets management, and hid it behind a NoPorts tunnel so that it can't be found and attacked.

Why did we need something?

Daily life is full of secrets - passwords, API keys, tokens, the list goes on. I’ve been using Bitwarden ever since the demise of Mitro. But there’s plenty of choice out there, which is why the EFF has a handy guide.

That works fine for the secrets that are just mine, but there are a bunch of things that need to be shared with colleagues (at least in case of emergency). In our case we use atSigns for a whole bunch of our infrastructure, and the .atKeys files for those atSigns need to be kept somewhere secure.

Where?

The most trivial way of doing this would be to put the keys into a shared document or folder, with very limited sharing. The problem with that is that the sign in to that shared environment becomes the keys to the kingdom. We wanted something where a single account compromise wouldn’t lay bare the shared secrets. Damage limitation, a reduced blast area.

This brought me around to looking at the various ‘team’ offerings for password managers. But they were all kind of pricey.

NoPorts + Policy + Vaultwarden

The solution we picked is Vaultwarden, a Bitwarden compatible service that can be self hosted.

Getting to our Vaultwarden requires a NoPorts connection, and an atKey that’s been given permission to connect in the associated policy manager.

Vaultwarden is configured to require MFA, so access to the secrets needs three credentials:

  1. An atSign (and associated private key) that's been permissioned to connect.
  2. A (strong) Vaultwarden password.
  3. An MFA token.

As we’re doing ‘authenticate before connect’ in step 1 our Vaultwarden service isn’t exposed to any brute force attacks or exploitation of any potential zero-day vulnerabilities. But even if somebody does gain access to an atSign key we still have multi-factor authentication between them and the secrets.

Techie details

HTTPS

Vaultwarden expects a connection over HTTPS, and we achieve that using Caddy as a reverse proxy. Caddy gets certificates from LetsEncrypt using DNS verification (so we never need to open ports to a web server). The DNS name used in the certificate resolves to 127.0.0.1, which is the entry point for the NoPorts tunnel.

Storage

Vaultwarden’s database is mounted to an NFS service that provides regular snapshots and multi availability zone replication. So we won’t lose all our secrets if the host running Vaultwarden has some nasty accident.