{
  flake-inputs,
  pkgs,
  config,
  lib,
  ...
}:
{
  options = {
    # Add a custom per-host option to enable HSTS
    services.nginx.virtualHosts = lib.mkOption {
      type = lib.types.attrsOf (
        lib.types.submodule (
          { config, ... }:
          {
            options.enableHSTS = lib.mkEnableOption "HSTS";
            config.extraConfig = lib.mkIf config.enableHSTS ''
              add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
            '';
          }
        )
      );
    };
  };

  config = {
    # Certificate settings
    security.acme = {
      defaults.email = "tm@tlater.net";
      acceptTerms = true;

      certs."tlater.net" = {
        extraDomainNames = [
          "*.tlater.net"
          "tlater.com"
          "*.tlater.com"
        ];
        dnsProvider = "porkbun";
        group = config.users.groups.ssl-cert.name;
        credentialFiles = {
          PORKBUN_API_KEY_FILE = config.sops.secrets."porkbun/api-key".path;
          PORKBUN_SECRET_API_KEY_FILE = config.sops.secrets."porkbun/secret-api-key".path;
        };
      };
    };
    users.groups.ssl-cert = { };

    # Back up the SSL certificate, just in case
    services.backups.acme = {
      user = "acme";
      paths = [ "/var/lib/acme/tlater.net" ];
    };

    systemd.services = {
      nginx.serviceConfig.SupplementaryGroups = [ config.security.acme.certs."tlater.net".group ];

      # Don't attempt to retrieve a certificate if the domain name
      # doesn't *actually* match the cert name
      #
      # TODO(tlater): Set up pebble to retrieve certs "properly"
      # instead
      "acme-tlater.net".serviceConfig.ExecCondition =
        let
          confirm = ''[[ "tlater.net" = "${config.services.nginx.domain}" ]]'';
        in
        ''${pkgs.runtimeShell} -c '${confirm}' '';
    };

    sops.secrets = {
      "porkbun/api-key".owner = "acme";
      "porkbun/secret-api-key".owner = "acme";
    };

    serviceTests =
      let
        testHostConfig =
          { config, ... }:
          {
            imports = [
              ./.
              ../../modules/serviceTests/mocks.nix
            ];

            networking.firewall.allowedTCPPorts = [ 443 ];

            security.acme.certs."tlater.net".extraDomainNames = [ config.services.nginx.domain ];

            services.nginx = {
              domain = "testHost";

              virtualHosts."${config.services.nginx.domain}" = {
                useACMEHost = "tlater.net";
                onlySSL = true;
                enableHSTS = true;
                locations."/".return = "200 ok";
              };
            };
          };
      in
      {
        testNginxSSL = pkgs.testers.runNixOSTest {
          name = "test-nginx-ssl";

          node.specialArgs = { inherit flake-inputs; };
          nodes = {
            testHost = testHostConfig;

            client =
              { pkgs, ... }:
              {
                environment.systemPackages = [ pkgs.curl ];
              };
          };

          testScript = ''
            start_all()

            testHost.wait_for_unit("nginx.service")
            testHost.copy_from_vm("/var/lib/acme/tlater.net/", "certs")
            client.copy_from_host(f"{testHost.out_dir}/certs", "/certs")

            res = client.succeed(" ".join([
                "curl",
                "--show-error",
                "--silent",
                "--dump-header -",
                "--cacert /certs/tlater.net/fullchain.pem",
                "https://testHost",
                "-o /dev/null"
            ]))

            assert "strict-transport-security: max-age=15552000; includeSubDomains" in res
          '';
        };
      };
  };
}
