summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/doc/manual/release-notes/rl-2311.section.md2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/security/privacyidea.nix458
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/privacyidea.nix43
-rw-r--r--pkgs/applications/misc/privacyidea/default.nix263
-rw-r--r--pkgs/development/python-modules/privacyidea-ldap-proxy/default.nix32
-rw-r--r--pkgs/top-level/aliases.nix1
-rw-r--r--pkgs/top-level/all-packages.nix2
-rw-r--r--pkgs/top-level/python-aliases.nix2
-rw-r--r--pkgs/top-level/python-packages.nix2
11 files changed, 4 insertions, 803 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md
index 7af4a99906c..276e7c9384e 100644
--- a/nixos/doc/manual/release-notes/rl-2311.section.md
+++ b/nixos/doc/manual/release-notes/rl-2311.section.md
@@ -339,6 +339,8 @@
 
 - `service.borgmatic.settings.location` and `services.borgmatic.configurations.<name>.location` are deprecated, please move your options out of sections to the global scope.
 
+- `privacyidea` (and the corresponding `privacyidea-ldap-proxy`) has been removed from nixpkgs because it has severely outdated dependencies that became unmaintainable with nixpkgs' python package-set.
+
 - `dagger` was removed because using a package called `dagger` and packaging it from source violates their trademark policy.
 
 - `win-virtio` package was renamed to `virtio-win` to be consistent with the upstream package name.
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 4949eb6f298..5647e89e541 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -1176,7 +1176,6 @@
   ./services/security/opensnitch.nix
   ./services/security/pass-secret-service.nix
   ./services/security/physlock.nix
-  ./services/security/privacyidea.nix
   ./services/security/shibboleth-sp.nix
   ./services/security/sks.nix
   ./services/security/sshguard.nix
diff --git a/nixos/modules/services/security/privacyidea.nix b/nixos/modules/services/security/privacyidea.nix
deleted file mode 100644
index 664335cb58e..00000000000
--- a/nixos/modules/services/security/privacyidea.nix
+++ /dev/null
@@ -1,458 +0,0 @@
-{ config, lib, options, pkgs, ... }:
-
-with lib;
-
-let
-  cfg = config.services.privacyidea;
-  opt = options.services.privacyidea;
-
-  uwsgi = pkgs.uwsgi.override { plugins = [ "python3" ]; python3 = pkgs.python310; };
-  python = uwsgi.python3;
-  penv = python.withPackages (const [ pkgs.privacyidea ]);
-  logCfg = pkgs.writeText "privacyidea-log.cfg" ''
-    [formatters]
-    keys=detail
-
-    [handlers]
-    keys=stream
-
-    [formatter_detail]
-    class=privacyidea.lib.log.SecureFormatter
-    format=[%(asctime)s][%(process)d][%(thread)d][%(levelname)s][%(name)s:%(lineno)d] %(message)s
-
-    [handler_stream]
-    class=StreamHandler
-    level=NOTSET
-    formatter=detail
-    args=(sys.stdout,)
-
-    [loggers]
-    keys=root,privacyidea
-
-    [logger_privacyidea]
-    handlers=stream
-    qualname=privacyidea
-    level=INFO
-
-    [logger_root]
-    handlers=stream
-    level=ERROR
-  '';
-
-  piCfgFile = pkgs.writeText "privacyidea.cfg" ''
-    SUPERUSER_REALM = [ '${concatStringsSep "', '" cfg.superuserRealm}' ]
-    SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2:///privacyidea'
-    SECRET_KEY = '${cfg.secretKey}'
-    PI_PEPPER = '${cfg.pepper}'
-    PI_ENCFILE = '${cfg.encFile}'
-    PI_AUDIT_KEY_PRIVATE = '${cfg.auditKeyPrivate}'
-    PI_AUDIT_KEY_PUBLIC = '${cfg.auditKeyPublic}'
-    PI_LOGCONFIG = '${logCfg}'
-    ${cfg.extraConfig}
-  '';
-
-  renderValue = x:
-    if isList x then concatMapStringsSep "," (x: ''"${x}"'') x
-    else if isString x && hasInfix "," x then ''"${x}"''
-    else x;
-
-  ldapProxyConfig = pkgs.writeText "ldap-proxy.ini"
-    (generators.toINI {}
-      (flip mapAttrs cfg.ldap-proxy.settings
-        (const (mapAttrs (const renderValue)))));
-
-  privacyidea-token-janitor = pkgs.writeShellScriptBin "privacyidea-token-janitor" ''
-    exec -a privacyidea-token-janitor \
-      /run/wrappers/bin/sudo -u ${cfg.user} \
-      env PRIVACYIDEA_CONFIGFILE=${cfg.stateDir}/privacyidea.cfg \
-      ${penv}/bin/privacyidea-token-janitor $@
-  '';
-in
-
-{
-  options = {
-    services.privacyidea = {
-      enable = mkEnableOption (lib.mdDoc "PrivacyIDEA");
-
-      environmentFile = mkOption {
-        type = types.nullOr types.path;
-        default = null;
-        example = "/root/privacyidea.env";
-        description = lib.mdDoc ''
-          File to load as environment file. Environment variables
-          from this file will be interpolated into the config file
-          using `envsubst` which is helpful for specifying
-          secrets:
-          ```
-          { services.privacyidea.secretKey = "$SECRET"; }
-          ```
-
-          The environment-file can now specify the actual secret key:
-          ```
-          SECRET=veryverytopsecret
-          ```
-        '';
-      };
-
-      stateDir = mkOption {
-        type = types.str;
-        default = "/var/lib/privacyidea";
-        description = lib.mdDoc ''
-          Directory where all PrivacyIDEA files will be placed by default.
-        '';
-      };
-
-      superuserRealm = mkOption {
-        type = types.listOf types.str;
-        default = [ "super" "administrators" ];
-        description = lib.mdDoc ''
-          The realm where users are allowed to login as administrators.
-        '';
-      };
-
-      secretKey = mkOption {
-        type = types.str;
-        example = "t0p s3cr3t";
-        description = lib.mdDoc ''
-          This is used to encrypt the auth_token.
-        '';
-      };
-
-      pepper = mkOption {
-        type = types.str;
-        example = "Never know...";
-        description = lib.mdDoc ''
-          This is used to encrypt the admin passwords.
-        '';
-      };
-
-      encFile = mkOption {
-        type = types.str;
-        default = "${cfg.stateDir}/enckey";
-        defaultText = literalExpression ''"''${config.${opt.stateDir}}/enckey"'';
-        description = lib.mdDoc ''
-          This is used to encrypt the token data and token passwords
-        '';
-      };
-
-      auditKeyPrivate = mkOption {
-        type = types.str;
-        default = "${cfg.stateDir}/private.pem";
-        defaultText = literalExpression ''"''${config.${opt.stateDir}}/private.pem"'';
-        description = lib.mdDoc ''
-          Private Key for signing the audit log.
-        '';
-      };
-
-      auditKeyPublic = mkOption {
-        type = types.str;
-        default = "${cfg.stateDir}/public.pem";
-        defaultText = literalExpression ''"''${config.${opt.stateDir}}/public.pem"'';
-        description = lib.mdDoc ''
-          Public key for checking signatures of the audit log.
-        '';
-      };
-
-      adminPasswordFile = mkOption {
-        type = types.path;
-        description = lib.mdDoc "File containing password for the admin user";
-      };
-
-      adminEmail = mkOption {
-        type = types.str;
-        example = "admin@example.com";
-        description = lib.mdDoc "Mail address for the admin user";
-      };
-
-      extraConfig = mkOption {
-        type = types.lines;
-        default = "";
-        description = lib.mdDoc ''
-          Extra configuration options for pi.cfg.
-        '';
-      };
-
-      user = mkOption {
-        type = types.str;
-        default = "privacyidea";
-        description = lib.mdDoc "User account under which PrivacyIDEA runs.";
-      };
-
-      group = mkOption {
-        type = types.str;
-        default = "privacyidea";
-        description = lib.mdDoc "Group account under which PrivacyIDEA runs.";
-      };
-
-      tokenjanitor = {
-        enable = mkEnableOption (lib.mdDoc "automatic runs of the token janitor");
-        interval = mkOption {
-          default = "quarterly";
-          type = types.str;
-          description = lib.mdDoc ''
-            Interval in which the cleanup program is supposed to run.
-            See {manpage}`systemd.time(7)` for further information.
-          '';
-        };
-        action = mkOption {
-          type = types.enum [ "delete" "mark" "disable" "unassign" ];
-          description = lib.mdDoc ''
-            Which action to take for matching tokens.
-          '';
-        };
-        unassigned = mkOption {
-          default = false;
-          type = types.bool;
-          description = lib.mdDoc ''
-            Whether to search for **unassigned** tokens
-            and apply [](#opt-services.privacyidea.tokenjanitor.action)
-            onto them.
-          '';
-        };
-        orphaned = mkOption {
-          default = true;
-          type = types.bool;
-          description = lib.mdDoc ''
-            Whether to search for **orphaned** tokens
-            and apply [](#opt-services.privacyidea.tokenjanitor.action)
-            onto them.
-          '';
-        };
-      };
-
-      ldap-proxy = {
-        enable = mkEnableOption (lib.mdDoc "PrivacyIDEA LDAP Proxy");
-
-        configFile = mkOption {
-          type = types.nullOr types.path;
-          default = null;
-          description = lib.mdDoc ''
-            Path to PrivacyIDEA LDAP Proxy configuration (proxy.ini).
-          '';
-        };
-
-        user = mkOption {
-          type = types.str;
-          default = "pi-ldap-proxy";
-          description = lib.mdDoc "User account under which PrivacyIDEA LDAP proxy runs.";
-        };
-
-        group = mkOption {
-          type = types.str;
-          default = "pi-ldap-proxy";
-          description = lib.mdDoc "Group account under which PrivacyIDEA LDAP proxy runs.";
-        };
-
-        settings = mkOption {
-          type = with types; attrsOf (attrsOf (oneOf [ str bool int (listOf str) ]));
-          default = {};
-          description = lib.mdDoc ''
-            Attribute-set containing the settings for `privacyidea-ldap-proxy`.
-            It's possible to pass secrets using env-vars as substitutes and
-            use the option [](#opt-services.privacyidea.ldap-proxy.environmentFile)
-            to inject them via `envsubst`.
-          '';
-        };
-
-        environmentFile = mkOption {
-          default = null;
-          type = types.nullOr types.str;
-          description = lib.mdDoc ''
-            Environment file containing secrets to be substituted into
-            [](#opt-services.privacyidea.ldap-proxy.settings).
-          '';
-        };
-      };
-    };
-  };
-
-  config = mkMerge [
-
-    (mkIf cfg.enable {
-
-      assertions = [
-        {
-          assertion = cfg.tokenjanitor.enable -> (cfg.tokenjanitor.orphaned || cfg.tokenjanitor.unassigned);
-          message = ''
-            privacyidea-token-janitor has no effect if neither orphaned nor unassigned tokens
-            are to be searched.
-          '';
-        }
-      ];
-
-      environment.systemPackages = [ pkgs.privacyidea (hiPrio privacyidea-token-janitor) ];
-
-      services.postgresql.enable = mkDefault true;
-
-      systemd.services.privacyidea-tokenjanitor = mkIf cfg.tokenjanitor.enable {
-        environment.PRIVACYIDEA_CONFIGFILE = "${cfg.stateDir}/privacyidea.cfg";
-        path = [ penv ];
-        serviceConfig = {
-          CapabilityBoundingSet = [ "" ];
-          ExecStart = "${pkgs.writeShellScript "pi-token-janitor" ''
-            ${optionalString cfg.tokenjanitor.orphaned ''
-              echo >&2 "Removing orphaned tokens..."
-              privacyidea-token-janitor find \
-                --orphaned true \
-                --action ${cfg.tokenjanitor.action}
-            ''}
-            ${optionalString cfg.tokenjanitor.unassigned ''
-              echo >&2 "Removing unassigned tokens..."
-              privacyidea-token-janitor find \
-                --assigned false \
-                --action ${cfg.tokenjanitor.action}
-            ''}
-          ''}";
-          Group = cfg.group;
-          LockPersonality = true;
-          MemoryDenyWriteExecute = true;
-          ProtectHome = true;
-          ProtectHostname = true;
-          ProtectKernelLogs = true;
-          ProtectKernelModules = true;
-          ProtectKernelTunables = true;
-          ProtectSystem = "strict";
-          ReadWritePaths = cfg.stateDir;
-          Type = "oneshot";
-          User = cfg.user;
-          WorkingDirectory = cfg.stateDir;
-        };
-      };
-      systemd.timers.privacyidea-tokenjanitor = mkIf cfg.tokenjanitor.enable {
-        wantedBy = [ "timers.target" ];
-        timerConfig.OnCalendar = cfg.tokenjanitor.interval;
-        timerConfig.Persistent = true;
-      };
-
-      systemd.services.privacyidea = let
-        piuwsgi = pkgs.writeText "uwsgi.json" (builtins.toJSON {
-          uwsgi = {
-            buffer-size = 8192;
-            plugins = [ "python3" ];
-            pythonpath = "${penv}/${uwsgi.python3.sitePackages}";
-            socket = "/run/privacyidea/socket";
-            uid = cfg.user;
-            gid = cfg.group;
-            chmod-socket = 770;
-            chown-socket = "${cfg.user}:nginx";
-            chdir = cfg.stateDir;
-            wsgi-file = "${penv}/etc/privacyidea/privacyideaapp.wsgi";
-            processes = 4;
-            harakiri = 60;
-            reload-mercy = 8;
-            stats = "/run/privacyidea/stats.socket";
-            max-requests = 2000;
-            limit-as = 1024;
-            reload-on-as = 512;
-            reload-on-rss = 256;
-            no-orphans = true;
-            vacuum = true;
-          };
-        });
-      in {
-        wantedBy = [ "multi-user.target" ];
-        after = [ "postgresql.service" ];
-        path = with pkgs; [ openssl ];
-        environment.PRIVACYIDEA_CONFIGFILE = "${cfg.stateDir}/privacyidea.cfg";
-        preStart = let
-          pi-manage = "${config.security.sudo.package}/bin/sudo -u privacyidea -HE ${penv}/bin/pi-manage";
-          pgsu = config.services.postgresql.superUser;
-          psql = config.services.postgresql.package;
-        in ''
-          mkdir -p ${cfg.stateDir} /run/privacyidea
-          chown ${cfg.user}:${cfg.group} -R ${cfg.stateDir} /run/privacyidea
-          umask 077
-          ${lib.getBin pkgs.envsubst}/bin/envsubst -o ${cfg.stateDir}/privacyidea.cfg \
-                                                   -i "${piCfgFile}"
-          chown ${cfg.user}:${cfg.group} ${cfg.stateDir}/privacyidea.cfg
-          if ! test -e "${cfg.stateDir}/db-created"; then
-            ${config.security.sudo.package}/bin/sudo -u ${pgsu} ${psql}/bin/createuser --no-superuser --no-createdb --no-createrole ${cfg.user}
-            ${config.security.sudo.package}/bin/sudo -u ${pgsu} ${psql}/bin/createdb --owner ${cfg.user} privacyidea
-            ${pi-manage} create_enckey
-            ${pi-manage} create_audit_keys
-            ${pi-manage} createdb
-            ${pi-manage} admin add admin -e ${cfg.adminEmail} -p "$(cat ${cfg.adminPasswordFile})"
-            ${pi-manage} db stamp head -d ${penv}/lib/privacyidea/migrations
-            touch "${cfg.stateDir}/db-created"
-            chmod g+r "${cfg.stateDir}/enckey" "${cfg.stateDir}/private.pem"
-          fi
-          ${pi-manage} db upgrade -d ${penv}/lib/privacyidea/migrations
-        '';
-        serviceConfig = {
-          Type = "notify";
-          ExecStart = "${uwsgi}/bin/uwsgi --json ${piuwsgi}";
-          ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
-          EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
-          ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID";
-          NotifyAccess = "main";
-          KillSignal = "SIGQUIT";
-        };
-      };
-
-      users.users.privacyidea = mkIf (cfg.user == "privacyidea") {
-        group = cfg.group;
-        isSystemUser = true;
-      };
-
-      users.groups.privacyidea = mkIf (cfg.group == "privacyidea") {};
-    })
-
-    (mkIf cfg.ldap-proxy.enable {
-
-      assertions = [
-        { assertion = let
-            xor = a: b: a && !b || !a && b;
-          in xor (cfg.ldap-proxy.settings == {}) (cfg.ldap-proxy.configFile == null);
-          message = "configFile & settings are mutually exclusive for services.privacyidea.ldap-proxy!";
-        }
-      ];
-
-      warnings = mkIf (cfg.ldap-proxy.configFile != null) [
-        "Using services.privacyidea.ldap-proxy.configFile is deprecated! Use the RFC42-style settings option instead!"
-      ];
-
-      systemd.services.privacyidea-ldap-proxy = let
-        ldap-proxy-env = pkgs.python3.withPackages (ps: [ ps.privacyidea-ldap-proxy ]);
-      in {
-        description = "privacyIDEA LDAP proxy";
-        wantedBy = [ "multi-user.target" ];
-        serviceConfig = {
-          User = cfg.ldap-proxy.user;
-          Group = cfg.ldap-proxy.group;
-          StateDirectory = "privacyidea-ldap-proxy";
-          EnvironmentFile = mkIf (cfg.ldap-proxy.environmentFile != null)
-            [ cfg.ldap-proxy.environmentFile ];
-          ExecStartPre =
-            "${pkgs.writeShellScript "substitute-secrets-ldap-proxy" ''
-              umask 0077
-              ${pkgs.envsubst}/bin/envsubst \
-                -i ${ldapProxyConfig} \
-                -o $STATE_DIRECTORY/ldap-proxy.ini
-            ''}";
-          ExecStart = let
-            configPath = if cfg.ldap-proxy.settings != {}
-              then "%S/privacyidea-ldap-proxy/ldap-proxy.ini"
-              else cfg.ldap-proxy.configFile;
-          in ''
-            ${ldap-proxy-env}/bin/twistd \
-              --nodaemon \
-              --pidfile= \
-              -u ${cfg.ldap-proxy.user} \
-              -g ${cfg.ldap-proxy.group} \
-              ldap-proxy \
-              -c ${configPath}
-          '';
-          Restart = "always";
-        };
-      };
-
-      users.users.pi-ldap-proxy = mkIf (cfg.ldap-proxy.user == "pi-ldap-proxy") {
-        group = cfg.ldap-proxy.group;
-        isSystemUser = true;
-      };
-
-      users.groups.pi-ldap-proxy = mkIf (cfg.ldap-proxy.group == "pi-ldap-proxy") {};
-    })
-  ];
-
-}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 456efe14464..0a3bbf37c6b 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -685,7 +685,6 @@ in {
   predictable-interface-names = handleTest ./predictable-interface-names.nix {};
   printing-socket = handleTest ./printing.nix { socket = true; };
   printing-service = handleTest ./printing.nix { socket = false; };
-  privacyidea = handleTest ./privacyidea.nix {};
   privoxy = handleTest ./privoxy.nix {};
   prometheus = handleTest ./prometheus.nix {};
   prometheus-exporters = handleTest ./prometheus-exporters.nix {};
diff --git a/nixos/tests/privacyidea.nix b/nixos/tests/privacyidea.nix
deleted file mode 100644
index 401ad72c37b..00000000000
--- a/nixos/tests/privacyidea.nix
+++ /dev/null
@@ -1,43 +0,0 @@
-# Miscellaneous small tests that don't warrant their own VM run.
-
-import ./make-test-python.nix ({ pkgs, ...} : rec {
-  name = "privacyidea";
-  meta = with pkgs.lib.maintainers; {
-    maintainers = [ ];
-  };
-
-  nodes.machine = { ... }: {
-    virtualisation.cores = 2;
-
-    services.privacyidea = {
-      enable = true;
-      secretKey = "$SECRET_KEY";
-      pepper = "$PEPPER";
-      adminPasswordFile = pkgs.writeText "admin-password" "testing";
-      adminEmail = "root@localhost";
-
-      # Don't try this at home!
-      environmentFile = pkgs.writeText "pi-secrets.env" ''
-        SECRET_KEY=testing
-        PEPPER=testing
-      '';
-    };
-    services.nginx = {
-      enable = true;
-      virtualHosts."_".locations."/".extraConfig = ''
-        uwsgi_pass unix:/run/privacyidea/socket;
-      '';
-    };
-  };
-
-  testScript = ''
-    machine.start()
-    machine.wait_for_unit("multi-user.target")
-    machine.succeed("curl --fail http://localhost | grep privacyIDEA")
-    machine.succeed("grep \"SECRET_KEY = 'testing'\" /var/lib/privacyidea/privacyidea.cfg")
-    machine.succeed("grep \"PI_PEPPER = 'testing'\" /var/lib/privacyidea/privacyidea.cfg")
-    machine.succeed(
-        "curl --fail http://localhost/auth -F username=admin -F password=testing | grep token"
-    )
-  '';
-})
diff --git a/pkgs/applications/misc/privacyidea/default.nix b/pkgs/applications/misc/privacyidea/default.nix
deleted file mode 100644
index 9cdf4da33ef..00000000000
--- a/pkgs/applications/misc/privacyidea/default.nix
+++ /dev/null
@@ -1,263 +0,0 @@
-{ lib, fetchFromGitHub, cacert, openssl, nixosTests
-, python310, fetchPypi, fetchpatch
-}:
-
-let
-  dropDocOutput = { outputs, ... }: {
-    outputs = lib.filter (x: x != "doc") outputs;
-  };
-
-  # Follow issue below for Python 3.11 support
-  # https://github.com/privacyidea/privacyidea/issues/3593
-  python3' = python310.override {
-    packageOverrides = self: super: {
-      django = super.django_3;
-
-      sqlalchemy = super.sqlalchemy.overridePythonAttrs (oldAttrs: rec {
-        version = "1.3.24";
-        src = fetchPypi {
-          inherit (oldAttrs) pname;
-          inherit version;
-          hash = "sha256-67t3fL+TEjWbiXv4G6ANrg9ctp+6KhgmXcwYpvXvdRk=";
-        };
-        doCheck = false;
-      });
-      # version 3.3.0+ does not support SQLAlchemy 1.3
-      factory-boy = super.factory-boy.overridePythonAttrs (oldAttrs: rec {
-        version = "3.2.1";
-        src = oldAttrs.src.override {
-          inherit version;
-          hash = "sha256-qY0newwEfHXrbkq4UIp/gfsD0sshmG9ieRNUbveipV4=";
-        };
-        postPatch = "";
-      });
-      # fails with `no tests ran in 1.75s`
-      alembic = super.alembic.overridePythonAttrs (lib.const {
-        doCheck = false;
-      });
-      flask-migrate = super.flask-migrate.overridePythonAttrs (oldAttrs: rec {
-        version = "2.7.0";
-        src = fetchPypi {
-          pname = "Flask-Migrate";
-          inherit version;
-          hash = "sha256-ri8FZxWIdi3YOiHYsYxR/jVehng+JFlJlf+Nc4Df/jg=";
-        };
-      });
-      flask-sqlalchemy = super.flask-sqlalchemy.overridePythonAttrs (old: rec {
-        version = "2.5.1";
-        format = "setuptools";
-        src = fetchPypi {
-          pname = "Flask-SQLAlchemy";
-          inherit version;
-          hash = "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912";
-        };
-      });
-      # Taken from by https://github.com/NixOS/nixpkgs/pull/173090/commits/d2c0c7eb4cc91beb0a1adbaf13abc0a526a21708
-      werkzeug = super.werkzeug.overridePythonAttrs (old: rec {
-        version = "1.0.1";
-        src = old.src.override {
-          inherit version;
-          hash = "sha256-bICx5a02ZSkOo5MguR4b4eDV9gZSuWSjBwIW3oPS5Hw=";
-        };
-        nativeCheckInputs = old.nativeCheckInputs ++ (with self; [
-          requests
-        ]);
-        doCheck = false;
-      });
-      # Required by flask-1.1
-      jinja2 = super.jinja2.overridePythonAttrs (old: rec {
-        version = "2.11.3";
-        src = old.src.override {
-          inherit version;
-          hash = "sha256-ptWEM94K6AA0fKsfowQ867q+i6qdKeZo8cdoy4ejM8Y=";
-        };
-        patches = [
-          # python 3.10 compat fixes. In later upstream releases, but these
-          # are not compatible with flask 1 which we need here :(
-          (fetchpatch {
-            url = "https://github.com/thmo/jinja/commit/1efb4cc918b4f3d097c376596da101de9f76585a.patch";
-            hash = "sha256-GFaSvYxgzOEFmnnDIfcf0ImScNTh1lR4lxt2Uz1DYdU=";
-          })
-          (fetchpatch {
-            url = "https://github.com/mkrizek/jinja/commit/bd8bad37d1c0e2d8995a44fd88e234f5340afec5.patch";
-            hash = "sha256-Uow+gaO+/dH6zavC0X/SsuMAfhTLRWpamVlL87DXDRA=";
-            excludes = [ "CHANGES.rst" ];
-          })
-        ];
-      });
-      # Required by jinja2-2.11.3
-      markupsafe = super.markupsafe.overridePythonAttrs (old: rec {
-        version = "2.0.1";
-        src = old.src.override {
-          inherit version;
-          hash = "sha256-WUxngH+xYjizDES99082wCzfItHIzake+KDtjav1Ygo=";
-        };
-      });
-      itsdangerous = super.itsdangerous.overridePythonAttrs (old: rec {
-        version = "1.1.0";
-        src = old.src.override {
-          inherit version;
-          hash = "sha256-MhsDPQfypBNtPsdi6snxahDM1g9TwMka+QIXrOe6Hxk=";
-        };
-      });
-      flask = super.flask.overridePythonAttrs (old: rec {
-        version = "1.1.4";
-        src = old.src.override {
-          inherit version;
-          hash = "sha256-D762GA04OpGG0NbtlU4AQq2fGODo3giLK0GdUmkn0ZY=";
-        };
-      });
-      sqlsoup = super.sqlsoup.overrideAttrs ({ meta ? {}, ... }: {
-        meta = meta // { broken = false; };
-      });
-      click = super.click.overridePythonAttrs (old: rec {
-        version = "7.1.2";
-        src = old.src.override {
-          inherit version;
-          hash = "sha256-0rUlXHxjSbwb0eWeCM0SrLvWPOZJ8liHVXg6qU37axo=";
-        };
-        disabledTests = [ "test_bytes_args" ]; # https://github.com/pallets/click/commit/6e05e1fa1c2804
-      });
-      # Now requires `lingua` as check input that requires a newer `click`,
-      # however `click-7` is needed by the older flask we need here. Since it's just
-      # for the test-suite apparently, let's skip it for now.
-      mako = super.mako.overridePythonAttrs (lib.const {
-        nativeCheckInputs = [];
-        doCheck = false;
-      });
-      # Requires pytest-httpserver as checkInput now which requires Werkzeug>=2 which is not
-      # supported by current privacyIDEA.
-      responses = super.responses.overridePythonAttrs (lib.const {
-        doCheck = false;
-      });
-      flask-babel = (super.flask-babel.override {
-        sphinxHook = null;
-        furo = null;
-      }).overridePythonAttrs (old: (dropDocOutput old) // rec {
-        pname = "Flask-Babel";
-        version = "2.0.0";
-        format = "setuptools";
-        src = fetchPypi {
-          inherit pname;
-          inherit version;
-          hash = "sha256:f9faf45cdb2e1a32ea2ec14403587d4295108f35017a7821a2b1acb8cfd9257d";
-        };
-        disabledTests = [
-          # AssertionError: assert 'Apr 12, 2010...46:00\u202fPM' == 'Apr 12, 2010, 1:46:00 PM'
-          # Note the `\u202f` (narrow, no-break space) vs space.
-          "test_basics"
-          "test_init_app"
-          "test_custom_locale_selector"
-          "test_refreshing"
-        ];
-      });
-      psycopg2 = (super.psycopg2.override {
-        sphinxHook = null;
-        sphinx-better-theme = null;
-      }).overridePythonAttrs dropDocOutput;
-      pyjwt = (super.pyjwt.override {
-        sphinxHook = null;
-        sphinx-rtd-theme = null;
-      }).overridePythonAttrs (old: (dropDocOutput old) // { format = "setuptools"; });
-      beautifulsoup4 = (super.beautifulsoup4.override {
-        sphinxHook = null;
-      }).overridePythonAttrs dropDocOutput;
-      pydash = (super.pydash.override {
-        sphinx-rtd-theme = null;
-      }).overridePythonAttrs (old: rec {
-        version = "5.1.0";
-        src = fetchPypi {
-          inherit (old) pname;
-          inherit version;
-          hash = "sha256-GysFCsG64EnNB/WSCxT6u+UmOPSF2a2h6xFanuv/aDU=";
-        };
-        format = "setuptools";
-        doCheck = false;
-      });
-      pyopenssl = (super.pyopenssl.override {
-        sphinxHook = null;
-        sphinx-rtd-theme = null;
-      }).overridePythonAttrs dropDocOutput;
-      deprecated = (super.deprecated.override {
-        sphinxHook = null;
-      }).overridePythonAttrs dropDocOutput;
-      wrapt = (super.wrapt.override {
-        sphinxHook = null;
-        sphinx-rtd-theme = null;
-      }).overridePythonAttrs dropDocOutput;
-    };
-  };
-in
-python3'.pkgs.buildPythonPackage rec {
-  pname = "privacyIDEA";
-  version = "3.8.1";
-  format = "setuptools";
-
-  src = fetchFromGitHub {
-    owner = pname;
-    repo = pname;
-    rev = "v${version}";
-    hash = "sha256-SYXw8PBCb514v3rcy15W/vZS5JyMsu81D2sJmviLRtw=";
-    fetchSubmodules = true;
-  };
-
-  patches = [
-    # https://github.com/privacyidea/privacyidea/pull/3611
-    (fetchpatch {
-      url = "https://github.com/privacyidea/privacyidea/commit/7db6509721726a34e8528437ddbd4210019b11ef.patch";
-      sha256 = "sha256-ZvtauCs1vWyxzGbA0B2+gG8q5JyUO8DF8nm/3/vcYmE=";
-    })
-  ];
-
-  propagatedBuildInputs = with python3'.pkgs; [
-    cryptography pyrad pymysql python-dateutil flask-versioned flask-script
-    defusedxml croniter flask-migrate pyjwt configobj sqlsoup pillow
-    python-gnupg passlib pyopenssl beautifulsoup4 smpplib flask-babel
-    ldap3 huey pyyaml qrcode oauth2client requests lxml cbor2 psycopg2
-    pydash ecdsa google-auth importlib-metadata argon2-cffi bcrypt segno
-  ];
-
-  passthru.tests = { inherit (nixosTests) privacyidea; };
-
-  nativeCheckInputs = with python3'.pkgs; [ openssl mock pytestCheckHook responses testfixtures ];
-  preCheck = "export HOME=$(mktemp -d)";
-  postCheck = "unset HOME";
-  disabledTests = [
-    # expects `/home/` to exist, fails with `FileNotFoundError: [Errno 2] No such file or directory: '/home/'`.
-    "test_01_loading_scripts"
-
-    # Tries to connect to `fcm.googleapis.com`.
-    "test_02_api_push_poll"
-    "test_04_decline_auth_request"
-
-    # Timezone info not available in build sandbox
-    "test_14_convert_timestamp_to_utc"
-
-    # Fails because of different logger configurations
-    "test_01_create_default_app"
-    "test_03_logging_config_file"
-    "test_04_logging_config_yaml"
-    "test_05_logging_config_broken_yaml"
-  ];
-
-  pythonImportsCheck = [ "privacyidea" ];
-
-  postPatch = ''
-    patchShebangs tests/testdata/scripts
-    substituteInPlace privacyidea/lib/resolvers/LDAPIdResolver.py --replace \
-      "/etc/privacyidea/ldap-ca.crt" \
-      "${cacert}/etc/ssl/certs/ca-bundle.crt"
-  '';
-
-  postInstall = ''
-    rm -r $out/${python3'.sitePackages}/tests
-  '';
-
-  meta = with lib; {
-    description = "Multi factor authentication system (2FA, MFA, OTP Server)";
-    license = licenses.agpl3Plus;
-    homepage = "http://www.privacyidea.org";
-    maintainers = with maintainers; [ ma27 ];
-    platforms = platforms.linux;
-  };
-}
diff --git a/pkgs/development/python-modules/privacyidea-ldap-proxy/default.nix b/pkgs/development/python-modules/privacyidea-ldap-proxy/default.nix
deleted file mode 100644
index 0b2a85f7e94..00000000000
--- a/pkgs/development/python-modules/privacyidea-ldap-proxy/default.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{ lib, buildPythonPackage, fetchFromGitHub, twisted, ldaptor, configobj, fetchpatch }:
-
-buildPythonPackage rec {
-  pname = "privacyidea-ldap-proxy";
-  version = "0.7";
-
-  src = fetchFromGitHub {
-    owner = "privacyidea";
-    repo = pname;
-    rev = "v${version}";
-    sha256 = "1i2kgxqd38xvb42qj0a4a35w4vk0fyp3n7w48kqmvrxc77p6r6i8";
-  };
-
-  patches = [
-    # support for LDAPCompareRequest.
-    (fetchpatch {
-      url = "https://github.com/mayflower/privacyidea-ldap-proxy/commit/a13356717379b174f1a6abf767faa0dbd459f5dd.patch";
-      hash = "sha256-SBTj9ayQ8JFD8BoYIl77nxWVV3PXnHZ8JMlJnxd/nEk=";
-    })
-  ];
-
-  propagatedBuildInputs = [ twisted ldaptor configobj ];
-
-  pythonImportsCheck = [ "pi_ldapproxy" ];
-
-  meta = with lib; {
-    description = "LDAP Proxy to intercept LDAP binds and authenticate against privacyIDEA";
-    homepage = "https://github.com/privacyidea/privacyidea-ldap-proxy";
-    license = licenses.agpl3Only;
-    maintainers = [ ];
-  };
-}
diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix
index 85ac74fae7d..38c4126a20f 100644
--- a/pkgs/top-level/aliases.nix
+++ b/pkgs/top-level/aliases.nix
@@ -710,6 +710,7 @@ mapAliases ({
   pinentry_qt = throw "'pinentry_qt' has been renamed to/replaced by 'pinentry-qt'"; # Converted to throw 2023-09-10
   pinentry_qt5 = pinentry-qt; # Added 2020-02-11
   poetry2nix = throw "poetry2nix is now maintained out-of-tree. Please use https://github.com/nix-community/poetry2nix/"; # Added 2023-10-26
+  privacyidea = throw "privacyidea has been removed from nixpkgs"; # Added 2023-10-31
   probe-rs-cli = throw "probe-rs-cli is now part of the probe-rs package"; # Added 2023-07-03
   processing3 = throw "'processing3' has been renamed to/replaced by 'processing'"; # Converted to throw 2023-09-10
   prometheus-dmarc-exporter = dmarc-metrics-exporter; # added 2022-05-31
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 77aaee8aa69..9d9a3a7a404 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -19871,8 +19871,6 @@ with pkgs;
 
   premake = premake4;
 
-  privacyidea = callPackage ../applications/misc/privacyidea { };
-
   process-compose = callPackage ../applications/misc/process-compose { };
 
   process-viewer = callPackage ../applications/misc/process-viewer { };
diff --git a/pkgs/top-level/python-aliases.nix b/pkgs/top-level/python-aliases.nix
index f11511b81f9..5e273836060 100644
--- a/pkgs/top-level/python-aliases.nix
+++ b/pkgs/top-level/python-aliases.nix
@@ -262,7 +262,7 @@ mapAliases ({
   poster3 = throw "poster3 is unmaintained and source is no longer available"; # added 2023-05-29
   postorius = throw "Please use pkgs.mailmanPackages.postorius"; # added 2022-04-29
   powerlineMemSegment = powerline-mem-segment; # added 2021-10-08
-  privacyidea = throw "privacyidea has been renamed to pkgs.privacyidea"; # added 2021-06-20
+  privacyidea-ldap-proxy = throw "privacyidea-ldap-proxy has been removed from nixpkgs"; # added 2023-10-31
   prometheus_client = prometheus-client; # added 2021-06-10
   prompt_toolkit = prompt-toolkit; # added 2021-07-22
   protonup = protonup-ng; # Added 2022-11-06
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index a71c3ed14ea..797fb18a26f 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -9510,8 +9510,6 @@ self: super: with self; {
 
   prison = callPackage ../development/python-modules/prison { };
 
-  privacyidea-ldap-proxy = callPackage ../development/python-modules/privacyidea-ldap-proxy { };
-
   proboscis = callPackage ../development/python-modules/proboscis { };
 
   process-tests = callPackage ../development/python-modules/process-tests { };