at 22.05-pre 4.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.dex; 7 fixClient = client: if client ? secretFile then ((builtins.removeAttrs client [ "secretFile" ]) // { secret = client.secretFile; }) else client; 8 filteredSettings = mapAttrs (n: v: if n == "staticClients" then (builtins.map fixClient v) else v) cfg.settings; 9 secretFiles = flatten (builtins.map (c: if c ? secretFile then [ c.secretFile ] else []) (cfg.settings.staticClients or [])); 10 11 settingsFormat = pkgs.formats.yaml {}; 12 configFile = settingsFormat.generate "config.yaml" filteredSettings; 13 14 startPreScript = pkgs.writeShellScript "dex-start-pre" ('' 15 '' + (concatStringsSep "\n" (builtins.map (file: '' 16 ${pkgs.replace-secret}/bin/replace-secret '${file}' '${file}' /run/dex/config.yaml 17 '') secretFiles))); 18in 19{ 20 options.services.dex = { 21 enable = mkEnableOption "the OpenID Connect and OAuth2 identity provider"; 22 23 settings = mkOption { 24 type = settingsFormat.type; 25 default = {}; 26 example = literalExpression '' 27 { 28 # External url 29 issuer = "http://127.0.0.1:5556/dex"; 30 storage = { 31 type = "postgres"; 32 config.host = "/var/run/postgres"; 33 }; 34 web = { 35 http = "127.0.0.1:5556"; 36 }; 37 enablePasswordDB = true; 38 staticClients = [ 39 { 40 id = "oidcclient"; 41 name = "Client"; 42 redirectURIs = [ "https://example.com/callback" ]; 43 secretFile = "/etc/dex/oidcclient"; # The content of `secretFile` will be written into to the config as `secret`. 44 } 45 ]; 46 } 47 ''; 48 description = '' 49 The available options can be found in 50 <link xlink:href="https://github.com/dexidp/dex/blob/v${pkgs.dex.version}/config.yaml.dist">the example configuration</link>. 51 ''; 52 }; 53 }; 54 55 config = mkIf cfg.enable { 56 systemd.services.dex = { 57 description = "dex identity provider"; 58 wantedBy = [ "multi-user.target" ]; 59 after = [ "networking.target" ] ++ (optional (cfg.settings.storage.type == "postgres") "postgresql.service"); 60 61 serviceConfig = { 62 ExecStart = "${pkgs.dex-oidc}/bin/dex serve /run/dex/config.yaml"; 63 ExecStartPre = [ 64 "${pkgs.coreutils}/bin/install -m 600 ${configFile} /run/dex/config.yaml" 65 "+${startPreScript}" 66 ]; 67 RuntimeDirectory = "dex"; 68 69 AmbientCapabilities = "CAP_NET_BIND_SERVICE"; 70 BindReadOnlyPaths = [ 71 "/nix/store" 72 "-/etc/resolv.conf" 73 "-/etc/nsswitch.conf" 74 "-/etc/hosts" 75 "-/etc/localtime" 76 "-/etc/dex" 77 ]; 78 BindPaths = optional (cfg.settings.storage.type == "postgres") "/var/run/postgresql"; 79 CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; 80 # ProtectClock= adds DeviceAllow=char-rtc r 81 DeviceAllow = ""; 82 DynamicUser = true; 83 LockPersonality = true; 84 MemoryDenyWriteExecute = true; 85 NoNewPrivileges = true; 86 PrivateDevices = true; 87 PrivateMounts = true; 88 # Port needs to be exposed to the host network 89 #PrivateNetwork = true; 90 PrivateTmp = true; 91 PrivateUsers = true; 92 ProcSubset = "pid"; 93 ProtectClock = true; 94 ProtectHome = true; 95 ProtectHostname = true; 96 # Would re-mount paths ignored by temporary root 97 #ProtectSystem = "strict"; 98 ProtectControlGroups = true; 99 ProtectKernelLogs = true; 100 ProtectKernelModules = true; 101 ProtectKernelTunables = true; 102 ProtectProc = "invisible"; 103 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; 104 RestrictNamespaces = true; 105 RestrictRealtime = true; 106 RestrictSUIDSGID = true; 107 SystemCallArchitectures = "native"; 108 SystemCallFilter = [ "@system-service" "~@privileged @resources @setuid @keyring" ]; 109 TemporaryFileSystem = "/:ro"; 110 # Does not work well with the temporary root 111 #UMask = "0066"; 112 }; 113 }; 114 }; 115}