at 25.11-pre 5.1 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10let 11 cfg = config.services.dex; 12 fixClient = 13 client: 14 if client ? secretFile then 15 ( 16 (builtins.removeAttrs client [ "secretFile" ]) 17 // { 18 secret = client.secretFile; 19 } 20 ) 21 else 22 client; 23 filteredSettings = mapAttrs ( 24 n: v: if n == "staticClients" then (builtins.map fixClient v) else v 25 ) cfg.settings; 26 secretFiles = flatten ( 27 builtins.map (c: optional (c ? secretFile) c.secretFile) (cfg.settings.staticClients or [ ]) 28 ); 29 30 settingsFormat = pkgs.formats.yaml { }; 31 configFile = settingsFormat.generate "config.yaml" filteredSettings; 32 33 startPreScript = pkgs.writeShellScript "dex-start-pre" ( 34 concatStringsSep "\n" ( 35 map (file: '' 36 replace-secret '${file}' '${file}' /run/dex/config.yaml 37 '') secretFiles 38 ) 39 ); 40 41 restartTriggers = 42 [ ] 43 ++ (optionals (cfg.environmentFile != null) [ cfg.environmentFile ]) 44 ++ (filter (file: builtins.typeOf file == "path") secretFiles); 45in 46{ 47 options.services.dex = { 48 enable = mkEnableOption "the OpenID Connect and OAuth2 identity provider"; 49 50 environmentFile = mkOption { 51 type = types.nullOr types.path; 52 default = null; 53 description = '' 54 Environment file (see {manpage}`systemd.exec(5)` 55 "EnvironmentFile=" section for the syntax) to define variables for dex. 56 This option can be used to safely include secret keys into the dex configuration. 57 ''; 58 }; 59 60 settings = mkOption { 61 type = settingsFormat.type; 62 default = { }; 63 example = literalExpression '' 64 { 65 # External url 66 issuer = "http://127.0.0.1:5556/dex"; 67 storage = { 68 type = "postgres"; 69 config.host = "/var/run/postgres"; 70 }; 71 web = { 72 http = "127.0.0.1:5556"; 73 }; 74 enablePasswordDB = true; 75 staticClients = [ 76 { 77 id = "oidcclient"; 78 name = "Client"; 79 redirectURIs = [ "https://example.com/callback" ]; 80 secretFile = "/etc/dex/oidcclient"; # The content of `secretFile` will be written into to the config as `secret`. 81 } 82 ]; 83 } 84 ''; 85 description = '' 86 The available options can be found in 87 [the example configuration](https://github.com/dexidp/dex/blob/v${pkgs.dex-oidc.version}/config.yaml.dist). 88 89 It's also possible to refer to environment variables (defined in [services.dex.environmentFile](#opt-services.dex.environmentFile)) 90 using the syntax `$VARIABLE_NAME`. 91 ''; 92 }; 93 }; 94 95 config = mkIf cfg.enable { 96 systemd.services.dex = { 97 description = "dex identity provider"; 98 wantedBy = [ "multi-user.target" ]; 99 after = [ 100 "networking.target" 101 ] ++ (optional (cfg.settings.storage.type == "postgres") "postgresql.service"); 102 path = with pkgs; [ replace-secret ]; 103 restartTriggers = restartTriggers; 104 serviceConfig = 105 { 106 ExecStart = "${pkgs.dex-oidc}/bin/dex serve /run/dex/config.yaml"; 107 ExecStartPre = [ 108 "${pkgs.coreutils}/bin/install -m 600 ${configFile} /run/dex/config.yaml" 109 "+${startPreScript}" 110 ]; 111 112 RuntimeDirectory = "dex"; 113 BindReadOnlyPaths = [ 114 "/nix/store" 115 "-/etc/dex" 116 "-/etc/hosts" 117 "-/etc/localtime" 118 "-/etc/nsswitch.conf" 119 "-/etc/resolv.conf" 120 "${config.security.pki.caBundle}:/etc/ssl/certs/ca-certificates.crt" 121 ]; 122 BindPaths = optional (cfg.settings.storage.type == "postgres") "/var/run/postgresql"; 123 # ProtectClock= adds DeviceAllow=char-rtc r 124 DeviceAllow = ""; 125 DynamicUser = true; 126 LockPersonality = true; 127 MemoryDenyWriteExecute = true; 128 NoNewPrivileges = true; 129 PrivateDevices = true; 130 PrivateMounts = true; 131 # Port needs to be exposed to the host network 132 #PrivateNetwork = true; 133 PrivateTmp = true; 134 PrivateUsers = true; 135 ProcSubset = "pid"; 136 ProtectClock = true; 137 ProtectHome = true; 138 ProtectHostname = true; 139 ProtectSystem = "strict"; 140 ProtectControlGroups = true; 141 ProtectKernelLogs = true; 142 ProtectKernelModules = true; 143 ProtectKernelTunables = true; 144 ProtectProc = "invisible"; 145 RestrictAddressFamilies = [ 146 "AF_INET" 147 "AF_INET6" 148 "AF_UNIX" 149 ]; 150 RestrictNamespaces = true; 151 RestrictRealtime = true; 152 RestrictSUIDSGID = true; 153 SystemCallArchitectures = "native"; 154 SystemCallFilter = [ 155 "@system-service" 156 "~@privileged @setuid @keyring" 157 ]; 158 UMask = "0066"; 159 } 160 // optionalAttrs (cfg.environmentFile != null) { 161 EnvironmentFile = cfg.environmentFile; 162 }; 163 }; 164 }; 165 166 # uses attributes of the linked package 167 meta.buildDocsInSandbox = false; 168}