Bitwarden client with self-hosted http server

As of bitwarden-cli 2025.11 http urls are disallowed:

Unable to fetch ServerConfig from http://localhost:<port>/api InsecureUrlNotAllowedError: Insecure URL not allowed. All URLs must use HTTPS.

Of course I could use an older version but I’d like to at least buy myself some time before migrating to https.

Based on the PR [PM-25250] Prevent configuration and access of self hosted urls over http by coroiu · Pull Request #17095 · bitwarden/clients · GitHub it seems they make an exception for dev builds; however I tried overriding preConfigure by adding the following (I couldn’t figure out which envvar is getting used):

export NODE_ENV=development
export ENV=development
export BIT_ENVIRONMENT=development

none of these seem to take effect - I still get the runtime error.
Has anyone found a workaround in the meantime?

Wouldn’t it be not only more proper but also easier to migrate to https than to look for unsupported workarounds?

I’m running the server locally, and I have no idea how to produce a valid cert. (But that’s also why not-using TLS is a non-issue otherwise.) Self-signing is a PITA from what I understand.

And I assumed rebuilding with whatever envvar set would only take 5 min compared to the alternative.

If you have a domain on any of the supported providers it’s pretty easy to create certificate with the security.acme module & DNS challenge.

Or you can create a local ca with openssl and add the ca.crt to security.pki.certificateFiles.

I have multiple services on this machine. So to successfully migrate I would need to

  • Set up some TLS mechanism
  • Get that cert trusted by my system and browsers
  • Throw up a reverse proxy to route to the correct service accordingly

I looked into acme before and it looked rough, and some providers on there have additional restrictions that prevent using acme.

I also don’t really see a huge return on setting up TLS for a locally running server - I’m really just looking for if someone has experience with this app specifically, not to reconfigure all dozen+ services just to get this one app running.

Ended up making a patch out of the revert of [PM-25250] Prevent configuration and access of self hosted urls over … · bitwarden/clients@48fb8b2 · GitHub and used that in my override. Funny how I forgot that was an option :sweat_smile:

The longterm fix looks more like below. Since I use tailscale, I had an option to enable HTTPS, which I did, then generated the cert/key pair for the machine in question below and encrypted via sops:

sudo tailscale cert --cert-file secrets/tailnet/<fqdn>/crt.bin --key-file secrets/tailnet/<fqdn>/key.bin <fqdn>
sudo chown -R <user>:users secrets/tailnet/<fqdn>
sops -e -i secrets/tailnet/<fqdn>/crt.bin
sops -e -i secrets/tailnet/<fqdn>/key.bin

Then consumed this via my config:

    services.nginx = {
      enable = mkDefault true;
      recommendedBrotliSettings = true;
      sslProtocols = "TLSv1.3";
      commonHttpConfig = ''
        # from Mozilla Guideline v5.7, nginx 1.27.3, OpenSSL 3.4.0, modern config
        # https://ssl-config.mozilla.org/#server=nginx&version=1.27.3&config=modern&openssl=3.4.0&guideline=5.7

        # modern configuration
        ssl_ecdh_curve X25519:prime256v1:secp384r1;
        ssl_prefer_server_ciphers off;
      '';

      virtualHosts.${cfg.fqdn} = {
        forceSSL = true;
        sslCertificate = config.sops.secrets."${cfg.fqdn}.crt".path;
        sslCertificateKey = config.sops.secrets."${cfg.fqdn}.key".path;
      };
    };

    sops.secrets =
      let
        _nginxUser = config.services.nginx.user;
      in
      {
        "${cfg.fqdn}.crt" = {
          format = "binary";
          owner = _nginxUser;
          sopsFile = ../../secrets/tailnet/${cfg.fqdn}/crt.bin;
        };

        "${cfg.fqdn}.key" = {
          format = "binary";
          owner = _nginxUser;
          sopsFile = ../../secrets/tailnet/${cfg.fqdn}/key.bin;
        };
      };
  services = {
    nginx.virtualHosts.${config.tailnet.fqdn} = {
      locations."^~ /bw/" = { inherit (config.ports.vaultwarden) proxyPass; };
    };

    vaultwarden = {
      enable = true;

      config = {
        ROCKET_ADDRESS = "127.0.0.1";
        ROCKET_PORT = config.ports.vaultwarden.port;
      };
    };
  };

Obviously I had some options ports.<name>.* and tailnet.fqdn defined in advance, and I’m using sops-nix, I think those should be self-explanatory or at least explainable elsewhere.

EDIT: I removed the DOMAIN setting as I realised I had misconfigured the proxyPass setting - ensure to keep a trailing slash there so that URLs are correctly rewritten, and also enable proxyWebsockets. ref Proxy examples · dani-garcia/vaultwarden Wiki · GitHub