{
  config,
  lib,
  ...
}:
with lib; let
  inherit (config.services) vouch-proxy;
in {
  options = with types; {
    services.nginx.virtualHosts = let
      vouchModule = { config, ... }: {
        options = {
          vouch = {
            enable = mkEnableOption "vouch auth proxy";
            proxyOrigin = mkOption {
              type = str;
            };
            authUrl = mkOption {
              type = str;
            };
            url = mkOption {
              type = str;
            };
          };
        };
        config = mkMerge [
          {
            vouch = mkIf vouch-proxy.enable {
              proxyOrigin = let
                inherit (vouch-proxy.settings.vouch) listen port;
                host = if listen == "0.0.0.0" || listen == "[::]" then "localhost" else listen;
              in mkOptionDefault "http://${host}:${toString port}";
              authUrl = mkOptionDefault vouch-proxy.authUrl;
              url = mkOptionDefault vouch-proxy.url;
            };
          }
          (mkIf config.vouch.enable {
            extraConfig = ''
              auth_request /validate;
              error_page 401 = @error401;
            '';
            locations = {
              "/" = {
                extraConfig = ''
                  add_header Access-Control-Allow-Origin ${config.vouch.url};
                  add_header Access-Control-Allow-Origin ${config.vouch.authUrl};
                  proxy_set_header X-Vouch-User $auth_resp_x_vouch_user;
                '';
              };
              "@error401" = {
                extraConfig = ''
                  return 302 ${config.vouch.url}/login?url=$scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
                '';
              };
              "/validate" = {
                recommendedProxySettings = false;
                proxyPass = "${config.vouch.proxyOrigin}/validate";
                extraConfig = ''
                  proxy_set_header Host $host;
                  proxy_pass_request_body off;
                  proxy_set_header Content-Length "";
                  auth_request_set $auth_resp_x_vouch_user $upstream_http_x_vouch_user;
                  auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;
                  auth_request_set $auth_resp_err $upstream_http_x_vouch_err;
                  auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;
                '';
              };
            };
          })
        ];
      };
    in mkOption {
      type = attrsOf (submodule vouchModule);
    };
  };
}
