grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / security / tpm2.nix
blobbd3c8a5b0c4356af7d1e3a36316793867f26dabb
1 { lib, pkgs, config, ... }:
2 let
3   cfg = config.security.tpm2;
5   # This snippet is taken from tpm2-tss/dist/tpm-udev.rules, but modified to allow custom user/groups
6   # The idea is that the tssUser is allowed to access the TPM and kernel TPM resource manager, while
7   # the tssGroup is only allowed to access the kernel resource manager
8   # Therefore, if either of the two are null, the respective part isn't generated
9   udevRules = tssUser: tssGroup: ''
10     ${lib.optionalString (tssUser != null) ''KERNEL=="tpm[0-9]*", MODE="0660", OWNER="${tssUser}"''}
11     ${lib.optionalString (tssUser != null || tssGroup != null)
12       ''KERNEL=="tpmrm[0-9]*", MODE="0660"''
13       + lib.optionalString (tssUser != null) '', OWNER="${tssUser}"''
14       + lib.optionalString (tssGroup != null) '', GROUP="${tssGroup}"''
15      }
16   '';
18 in {
19   options.security.tpm2 = {
20     enable = lib.mkEnableOption "Trusted Platform Module 2 support";
22     tssUser = lib.mkOption {
23       description = ''
24         Name of the tpm device-owner and service user, set if applyUdevRules is
25         set.
26       '';
27       type = lib.types.nullOr lib.types.str;
28       default = if cfg.abrmd.enable then "tss" else "root";
29       defaultText = lib.literalExpression ''if config.security.tpm2.abrmd.enable then "tss" else "root"'';
30     };
32     tssGroup = lib.mkOption {
33       description = ''
34         Group of the tpm kernel resource manager (tpmrm) device-group, set if
35         applyUdevRules is set.
36       '';
37       type = lib.types.nullOr lib.types.str;
38       default = "tss";
39     };
41     applyUdevRules = lib.mkOption {
42       description = ''
43         Whether to make the /dev/tpm[0-9] devices accessible by the tssUser, or
44         the /dev/tpmrm[0-9] by tssGroup respectively
45       '';
46       type = lib.types.bool;
47       default = true;
48     };
50     abrmd = {
51       enable = lib.mkEnableOption ''
52         Trusted Platform 2 userspace resource manager daemon
53       '';
55       package = lib.mkOption {
56         description = "tpm2-abrmd package to use";
57         type = lib.types.package;
58         default = pkgs.tpm2-abrmd;
59         defaultText = lib.literalExpression "pkgs.tpm2-abrmd";
60       };
61     };
63     pkcs11 = {
64       enable = lib.mkEnableOption ''
65         TPM2 PKCS#11 tool and shared library in system path
66         (`/run/current-system/sw/lib/libtpm2_pkcs11.so`)
67       '';
69       package = lib.mkOption {
70         description = "tpm2-pkcs11 package to use";
71         type = lib.types.package;
72         default = pkgs.tpm2-pkcs11;
73         defaultText = lib.literalExpression "pkgs.tpm2-pkcs11";
74       };
75     };
77     tctiEnvironment = {
78       enable = lib.mkOption {
79         description = ''
80           Set common TCTI environment variables to the specified value.
81           The variables are
82           - `TPM2TOOLS_TCTI`
83           - `TPM2_PKCS11_TCTI`
84         '';
85         type = lib.types.bool;
86         default = false;
87       };
89       interface = lib.mkOption {
90         description = ''
91           The name of the TPM command transmission interface (TCTI) library to
92           use.
93         '';
94         type = lib.types.enum [ "tabrmd" "device" ];
95         default = "device";
96       };
98       deviceConf = lib.mkOption {
99         description = ''
100           Configuration part of the device TCTI, e.g. the path to the TPM device.
101           Applies if interface is set to "device".
102           The format is specified in the
103           [
104           tpm2-tools repository](https://github.com/tpm2-software/tpm2-tools/blob/master/man/common/tcti.md#tcti-options).
105         '';
106         type = lib.types.str;
107         default = "/dev/tpmrm0";
108       };
110       tabrmdConf = lib.mkOption {
111         description = ''
112           Configuration part of the tabrmd TCTI, like the D-Bus bus name.
113           Applies if interface is set to "tabrmd".
114           The format is specified in the
115           [
116           tpm2-tools repository](https://github.com/tpm2-software/tpm2-tools/blob/master/man/common/tcti.md#tcti-options).
117         '';
118         type = lib.types.str;
119         default = "bus_name=com.intel.tss2.Tabrmd";
120       };
121     };
122   };
124   config = lib.mkIf cfg.enable (lib.mkMerge [
125     {
126       # PKCS11 tools and library
127       environment.systemPackages = lib.mkIf cfg.pkcs11.enable [
128         (lib.getBin cfg.pkcs11.package)
129         (lib.getLib cfg.pkcs11.package)
130       ];
132       services.udev.extraRules = lib.mkIf cfg.applyUdevRules
133         (udevRules cfg.tssUser cfg.tssGroup);
135       # Create the tss user and group only if the default value is used
136       users.users.${cfg.tssUser} = lib.mkIf (cfg.tssUser == "tss") {
137         isSystemUser = true;
138         group = "tss";
139       };
140       users.groups.${cfg.tssGroup} = lib.mkIf (cfg.tssGroup == "tss") {};
142       environment.variables = lib.mkIf cfg.tctiEnvironment.enable (
143         lib.attrsets.genAttrs [
144           "TPM2TOOLS_TCTI"
145           "TPM2_PKCS11_TCTI"
146         ] (_: ''${cfg.tctiEnvironment.interface}:${
147           if cfg.tctiEnvironment.interface == "tabrmd" then
148             cfg.tctiEnvironment.tabrmdConf
149           else
150             cfg.tctiEnvironment.deviceConf
151         }'')
152       );
153     }
155     (lib.mkIf cfg.abrmd.enable {
156       systemd.services."tpm2-abrmd" = {
157         wantedBy = [ "multi-user.target" ];
158         serviceConfig = {
159           Type = "dbus";
160           Restart = "always";
161           RestartSec = 30;
162           BusName = "com.intel.tss2.Tabrmd";
163           ExecStart = "${cfg.abrmd.package}/bin/tpm2-abrmd";
164           User = "tss";
165           Group = "tss";
166         };
167       };
169       services.dbus.packages = lib.singleton cfg.abrmd.package;
170     })
171   ]);
173   meta.maintainers = with lib.maintainers; [ lschuermann ];