Linux desktop application sandbox.
Go to file
Ophestra cae567c109
All checks were successful
Build / Create distribution (push) Successful in 1m27s
Test / Run NixOS test (push) Successful in 3m37s
proc/priv/shim: remove unnecessary state
These values are only used during process creation.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-01-19 18:09:07 +09:00
.gitea/workflows fortify: switch to static linking 2025-01-16 17:32:52 +09:00
acl fortify: switch to static linking 2025-01-16 17:32:52 +09:00
cmd proc: remove duplicate compile-time fortify reference 2025-01-18 11:59:33 +09:00
comp fortify: zsh complete show instance list 2024-12-21 21:13:53 +09:00
dbus dbus: implement dbus_parse_address 2025-01-12 23:24:03 +09:00
dist proc: remove duplicate compile-time fortify reference 2025-01-18 11:59:33 +09:00
fst fst: hide sockets exposed via Filesystem 2025-01-15 10:13:18 +09:00
helper helper/bwrap: append --sync-fd before -- 2025-01-18 12:30:03 +09:00
internal proc/priv/shim: remove unnecessary state 2025-01-19 18:09:07 +09:00
ldd ldd: trim leading and trailing white spaces from name 2024-12-26 16:53:01 +09:00
wl fortify: switch to static linking 2025-01-16 17:32:52 +09:00
xcb fortify: switch to static linking 2025-01-16 17:32:52 +09:00
.gitignore nix: generate application package build script 2024-12-29 00:42:21 +09:00
bundle.nix cmd/fpkg: expose nixGL wrappers 2024-12-30 02:02:20 +09:00
error.go migrate to git.gensokyo.uk/security/fortify 2024-12-20 00:20:02 +09:00
flake.lock nix: update flake lock 2024-12-29 23:14:16 +09:00
flake.nix nix: do not force static linking on nix 2025-01-17 22:56:16 +09:00
go.mod migrate to git.gensokyo.uk/security/fortify 2024-12-20 00:20:02 +09:00
LICENSE apply MIT license 2024-07-16 20:49:00 +09:00
main.go proc/priv/init: early init check 2025-01-18 12:33:33 +09:00
nixos.nix nix: implement flake checks 2024-12-16 20:54:28 +09:00
options.md release: 0.2.10 2025-01-18 22:50:08 +09:00
options.nix nix: implement flake checks 2024-12-16 20:54:28 +09:00
package.nix release: 0.2.10 2025-01-18 22:50:08 +09:00
parse.go linux/std: handle fsu exit status 1 2025-01-01 21:34:57 +09:00
print.go linux/std: handle fsu exit status 1 2025-01-01 21:34:57 +09:00
README.md migrate to git.gensokyo.uk/security/fortify 2024-12-20 00:20:02 +09:00
test.nix fortify: switch to static linking 2025-01-16 17:32:52 +09:00

Fortify

Go Reference Go Report Card

Lets you run graphical applications as another user in a confined environment with a nice NixOS module to configure target users and provide launchers and desktop files for your privileged user.

Why would you want this?

  • It protects the desktop environment from applications.

  • It protects applications from each other.

  • It provides UID isolation on top of the standard application sandbox.

If you have a flakes-enabled nix environment, you can try out the tool by running:

nix run git+https://git.gensokyo.uk/security/fortify -- help

Module usage

The NixOS module currently requires home-manager to function correctly.

Full module documentation can be found here.

To use the module, import it into your configuration with

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";

    fortify = {
      url = "git+https://git.gensokyo.uk/security/fortify";

      # Optional but recommended to limit the size of your system closure.
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, fortify, ... }:
  {
    nixosConfigurations.fortify = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        fortify.nixosModules.fortify
      ];
    };
  };
}

This adds the environment.fortify option:

{ pkgs, ... }:

{
  environment.fortify = {
    enable = true;
    stateDir = "/var/lib/persist/module/fortify";
    users = {
      alice = 0;
      nixos = 10;
    };

    apps = [
      {
        name = "chromium";
        id = "org.chromium.Chromium";
        packages = [ pkgs.chromium ];
        userns = true;
        mapRealUid = true;
        dbus = {
          system = {
            filter = true;
            talk = [
              "org.bluez"
              "org.freedesktop.Avahi"
              "org.freedesktop.UPower"
            ];
          };
          session =
            f:
            f {
              talk = [
                "org.freedesktop.FileManager1"
                "org.freedesktop.Notifications"
                "org.freedesktop.ScreenSaver"
                "org.freedesktop.secrets"
                "org.kde.kwalletd5"
                "org.kde.kwalletd6"
              ];
              own = [
                "org.chromium.Chromium.*"
                "org.mpris.MediaPlayer2.org.chromium.Chromium.*"
                "org.mpris.MediaPlayer2.chromium.*"
              ];
              call = { };
              broadcast = { };
            };
        };
      }
      {
        name = "claws-mail";
        id = "org.claws_mail.Claws-Mail";
        packages = [ pkgs.claws-mail ];
        gpu = false;
        capability.pulse = false;
      }
      {
        name = "weechat";
        packages = [ pkgs.weechat ];
        capability = {
          wayland = false;
          x11 = false;
          dbus = true;
          pulse = false;
        };
      }
      {
        name = "discord";
        id = "dev.vencord.Vesktop";
        packages = [ pkgs.vesktop ];
        share = pkgs.vesktop;
        command = "vesktop --ozone-platform-hint=wayland";
        userns = true;
        mapRealUid = true;
        capability.x11 = true;
        dbus = {
          session =
            f:
            f {
              talk = [ "org.kde.StatusNotifierWatcher" ];
              own = [ ];
              call = { };
              broadcast = { };
            };
          system.filter = true;
        };
      }
      {
        name = "looking-glass-client";
        groups = [ "plugdev" ];
        extraPaths = [
          {
            src = "/dev/shm/looking-glass";
            write = true;
          }
        ];
        extraConfig = {
          programs.looking-glass-client.enable = true;
        };
      }
    ];
  };
}