将秘密传递给 NixOps 逻辑网络规范

Passing secrets to NixOps logical network specification

我正在使用 NixOps 将 Web 应用程序部署到 AWS。该应用程序需要设置一些环境变量。我可以通过类似于以下内容的方式实现此目的:

{
  network.description = "Web server";

  webserver = { config, pkgs, ... }: {
    environment.systemPackages = [ webserver ];
    networking.firewall.allowedTCPPorts = [ 80 ];

    systemd.services.webserver = {
      description = "Example webapp";

      environment = {
        SECRET_KEY = "SECRET_VALUE";
      }
    };
  };
}

我希望将此文件签入我的源代码控制系统,但如果可以的话,我不希望 SECRET_VALUE 以明文形式存储。

有没有办法在部署需要时从 GPG 加密文件中读取这些值?或者还有其他方法吗?还是我需要加密整个文件?

理想情况下,您会使用 NixOps 密钥,因为它们的目的是向您的应用程序提供敏感数据,同时将此类内容存储在 Nix 商店之外。

Files in /nix/store/ are readable by every user on that host, so storing secret keys embedded in nix derivations is insecure. To address this, nixops provides the configuration option deployment.keys, which nixops manages separately from the main configuration derivation for each machine. - https://nixos.org/nixops/manual/#idm140737318276736

更具体地说,在您的情况下,Nix 将为您的网络服务器服务创建一个 systemd 单元文件,该文件存储在 /nix/store 中,其中包含您的 SECRET_KEY。

但如果必须使用环境变量,您可以使用builtins.readFile从外部文件读取环境变量的值。当您 build/deploy 时,该文件将需要存在,因此您可以通过不将其存储在 Git 存储库中或使用透明加密(例如 git-crypt)来保护数据罗伯特建议。

{
  network.description = "Web server";

  webserver = { config, pkgs, ... }: {
    environment.systemPackages = [ webserver ];
    networking.firewall.allowedTCPPorts = [ 80 ];

    systemd.services.webserver = {
      description = "Example webapp";

      environment = {
        SECRET_KEY = builtins.readFile ./secret.data;
      }
    };
  };
}