Skip to content
Snippets Groups Projects
spending.nix 2.77 KiB
Newer Older
# A NixOS module which can run a Ristretto-based issuer for PrivateStorage
# ZKAPs.
{ lib, pkgs, config, ourpkgs, ... }@args: let
  cfg = config.services.private-storage-spending;
in
{
  options = {
    services.private-storage-spending = {
      enable = lib.mkEnableOption "PrivateStorage Spending Service";
      package = lib.mkOption {
        default = ourpkgs.zkap-spending-service;
        type = lib.types.package;
        example = lib.literalExample "ourpkgs.zkap-spending-service";
        description = ''
          The package to use for the spending service.
        '';
      };
      unixSocket = lib.mkOption {
        default = "/run/zkap-spending-service/api.socket";
        type = lib.types.path;
        description = ''
          The unix socket that the spending service API listens on.
        '';
      };
    };
    services.private-storage-spending.domain = lib.mkOption {
      default = config.networking.fqdn;
      type = lib.types.str;
      example = lib.literalExample [ "spending.example.com" ];
      description = ''
        The domain name at which the spending service is reachable.
      '';
    };
  };

  config =
    lib.mkIf cfg.enable {
      systemd.sockets.zkap-spending-service = {
        enable = true;
        wantedBy = [ "sockets.target" ];
        listenStreams = [ cfg.unixSocket ];
      };
      # Add a systemd service to run zkap-spending-service.
      systemd.services.zkap-spending-service = {
        enable = true;
        description = "ZKAP Spending Service";
        wantedBy = [ "multi-user.target" ];

        serviceConfig.NonBlocking = true;

        # It really shouldn't ever exit on its own!  If it does, it's a bug
        # we'll have to fix.  Restart it and hope it doesn't happen too much
        # before we can fix whatever the issue is.
        serviceConfig.Restart = "always";
        serviceConfig.Type = "simple";

        script = let
          httpArgs = "--http-endpoint systemd:domain=UNIX:index=0";
        in
          "exec ${cfg.package}/bin/${cfg.package.meta.mainProgram} run ${httpArgs}";
      };

      services.nginx = {
        enable = true;

        recommendedGzipSettings = true;
        recommendedOptimisation = true;
        recommendedProxySettings = true;
        recommendedTlsSettings = true;

        virtualHosts."${cfg.domain}" = {
          locations."/v1/" = {
            # Only forward requests beginning with /v1/ so
            # we pass less scanning spam on to our backend
            # Want a regex instead? try locations."~ /v\d+/"
            proxyPass = "http://unix:${cfg.unixSocket}";
          };
          locations."/" = {
            # Return a 404 error for any paths not specified above.
            extraConfig = ''
              return 404;
            '';
          };
        };
      };
    };
}