1 { config, options, lib, pkgs, ... }:
6 cfg = config.services.cfssl;
8 options.services.cfssl = {
9 enable = mkEnableOption "the CFSSL CA api-server";
12 default = "/var/lib/cfssl";
15 The work directory for CFSSL.
18 If left as the default value this directory will automatically be
19 created before the CFSSL server starts, otherwise you are
20 responsible for ensuring the directory exists with appropriate
21 ownership and permissions.
27 default = "127.0.0.1";
29 description = "Address to bind.";
35 description = "Port to bind.";
39 defaultText = literalExpression ''"''${cfg.dataDir}/ca.pem"'';
41 description = "CA used to sign the new certificate -- accepts '[file:]fname' or 'env:varname'.";
45 defaultText = literalExpression ''"file:''${cfg.dataDir}/ca-key.pem"'';
47 description = "CA private key -- accepts '[file:]fname' or 'env:varname'.";
52 type = types.nullOr types.path;
53 description = "Path to root certificate store.";
56 intBundle = mkOption {
58 type = types.nullOr types.path;
59 description = "Path to intermediate certificate store.";
64 type = types.nullOr types.path;
65 description = "Intermediates directory.";
70 type = types.nullOr types.path;
72 Metadata file for root certificate presence.
73 The content of the file is a json dictionary (k,v): each key k is
74 a SHA-1 digest of a root certificate while value v is a list of key
81 type = types.nullOr types.str;
82 description = "Remote CFSSL server.";
85 configFile = mkOption {
87 type = types.nullOr types.str;
88 description = "Path to configuration file. Do not put this in nix-store as it might contain secrets.";
91 responder = mkOption {
93 type = types.nullOr types.path;
94 description = "Certificate for OCSP responder.";
97 responderKey = mkOption {
99 type = types.nullOr types.str;
100 description = "Private key for OCSP responder certificate. Do not put this in nix-store.";
105 type = types.nullOr types.str;
106 description = "Other endpoint's CA private key. Do not put this in nix-store.";
111 type = types.nullOr types.path;
112 description = "Other endpoint's CA to set up TLS protocol.";
115 mutualTlsCa = mkOption {
117 type = types.nullOr types.path;
118 description = "Mutual TLS - require clients be signed by this CA.";
121 mutualTlsCn = mkOption {
123 type = types.nullOr types.str;
124 description = "Mutual TLS - regex for whitelist of allowed client CNs.";
127 tlsRemoteCa = mkOption {
129 type = types.nullOr types.path;
130 description = "CAs to trust for remote TLS requests.";
133 mutualTlsClientCert = mkOption {
135 type = types.nullOr types.path;
136 description = "Mutual TLS - client certificate to call remote instance requiring client certs.";
139 mutualTlsClientKey = mkOption {
141 type = types.nullOr types.path;
142 description = "Mutual TLS - client key to call remote instance requiring client certs. Do not put this in nix-store.";
145 dbConfig = mkOption {
147 type = types.nullOr types.path;
148 description = "Certificate db configuration file. Path must be writeable.";
151 logLevel = mkOption {
153 type = types.enum [ 0 1 2 3 4 5 ];
154 description = "Log level (0 = DEBUG, 5 = FATAL).";
158 config = mkIf cfg.enable {
159 users.groups.cfssl = {
160 gid = config.ids.gids.cfssl;
163 users.users.cfssl = {
164 description = "cfssl user";
167 uid = config.ids.uids.cfssl;
170 systemd.services.cfssl = {
171 description = "CFSSL CA API server";
172 wantedBy = [ "multi-user.target" ];
173 after = [ "network.target" ];
175 serviceConfig = lib.mkMerge [
177 WorkingDirectory = cfg.dataDir;
182 ExecStart = with cfg; let
183 opt = n: v: optionalString (v != null) ''-${n}="${v}"'';
185 lib.concatStringsSep " \\\n" [
186 "${pkgs.cfssl}/bin/cfssl serve"
187 (opt "address" address)
188 (opt "port" (toString port))
191 (opt "ca-bundle" caBundle)
192 (opt "int-bundle" intBundle)
193 (opt "int-dir" intDir)
194 (opt "metadata" metadata)
195 (opt "remote" remote)
196 (opt "config" configFile)
197 (opt "responder" responder)
198 (opt "responder-key" responderKey)
199 (opt "tls-key" tlsKey)
200 (opt "tls-cert" tlsCert)
201 (opt "mutual-tls-ca" mutualTlsCa)
202 (opt "mutual-tls-cn" mutualTlsCn)
203 (opt "mutual-tls-client-key" mutualTlsClientKey)
204 (opt "mutual-tls-client-cert" mutualTlsClientCert)
205 (opt "tls-remote-ca" tlsRemoteCa)
206 (opt "db-config" dbConfig)
207 (opt "loglevel" (toString logLevel))
210 (mkIf (cfg.dataDir == options.services.cfssl.dataDir.default) {
211 StateDirectory = baseNameOf cfg.dataDir;
212 StateDirectoryMode = 700;
218 ca = mkDefault "${cfg.dataDir}/ca.pem";
219 caKey = mkDefault "${cfg.dataDir}/ca-key.pem";