nixos/preload: init
[NixPkgs.git] / nixos / modules / programs / firejail.nix
blob6f79c13d94b44983675b9d3eca8ad503f7dfa1a8
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.programs.firejail;
8   wrappedBins = pkgs.runCommand "firejail-wrapped-binaries"
9     { preferLocalBuild = true;
10       allowSubstitutes = false;
11       # take precedence over non-firejailed versions
12       meta.priority = -1;
13     }
14     ''
15       mkdir -p $out/bin
16       mkdir -p $out/share/applications
17       ${lib.concatStringsSep "\n" (lib.mapAttrsToList (command: value:
18       let
19         opts = if builtins.isAttrs value
20         then value
21         else { executable = value; desktop = null; profile = null; extraArgs = []; };
22         args = lib.escapeShellArgs (
23           opts.extraArgs
24           ++ (optional (opts.profile != null) "--profile=${toString opts.profile}")
25         );
26       in
27       ''
28         cat <<_EOF >$out/bin/${command}
29         #! ${pkgs.runtimeShell} -e
30         exec /run/wrappers/bin/firejail ${args} -- ${toString opts.executable} "\$@"
31         _EOF
32         chmod 0755 $out/bin/${command}
34         ${lib.optionalString (opts.desktop != null) ''
35           substitute ${opts.desktop} $out/share/applications/$(basename ${opts.desktop}) \
36             --replace ${opts.executable} $out/bin/${command}
37         ''}
38       '') cfg.wrappedBinaries)}
39     '';
41 in {
42   options.programs.firejail = {
43     enable = mkEnableOption (lib.mdDoc "firejail");
45     wrappedBinaries = mkOption {
46       type = types.attrsOf (types.either types.path (types.submodule {
47         options = {
48           executable = mkOption {
49             type = types.path;
50             description = lib.mdDoc "Executable to run sandboxed";
51             example = literalExpression ''"''${lib.getBin pkgs.firefox}/bin/firefox"'';
52           };
53           desktop = mkOption {
54             type = types.nullOr types.path;
55             default = null;
56             description = lib.mkDoc ".desktop file to modify. Only necessary if it uses the absolute path to the executable.";
57             example = literalExpression ''"''${pkgs.firefox}/share/applications/firefox.desktop"'';
58           };
59           profile = mkOption {
60             type = types.nullOr types.path;
61             default = null;
62             description = lib.mdDoc "Profile to use";
63             example = literalExpression ''"''${pkgs.firejail}/etc/firejail/firefox.profile"'';
64           };
65           extraArgs = mkOption {
66             type = types.listOf types.str;
67             default = [];
68             description = lib.mdDoc "Extra arguments to pass to firejail";
69             example = [ "--private=~/.firejail_home" ];
70           };
71         };
72       }));
73       default = {};
74       example = literalExpression ''
75         {
76           firefox = {
77             executable = "''${lib.getBin pkgs.firefox}/bin/firefox";
78             profile = "''${pkgs.firejail}/etc/firejail/firefox.profile";
79           };
80           mpv = {
81             executable = "''${lib.getBin pkgs.mpv}/bin/mpv";
82             profile = "''${pkgs.firejail}/etc/firejail/mpv.profile";
83           };
84         }
85       '';
86       description = lib.mdDoc ''
87         Wrap the binaries in firejail and place them in the global path.
88       '';
89     };
90   };
92   config = mkIf cfg.enable {
93     security.wrappers.firejail =
94       { setuid = true;
95         owner = "root";
96         group = "root";
97         source = "${lib.getBin pkgs.firejail}/bin/firejail";
98       };
100     environment.systemPackages = [ pkgs.firejail ] ++ [ wrappedBins ];
101   };
103   meta.maintainers = with maintainers; [ peterhoeg ];