Linux desktop application sandbox.
Go to file
Ophestra a48386bd56
All checks were successful
Test / Create distribution (push) Successful in 1m27s
Test / Run NixOS test (push) Successful in 4m14s
system/dbus: dump messages on early fault
In the current app implementation this gets dumped in the wait method after resuming output. Wait is never called in an early fault condition, so any error messages get lost.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-02-07 13:20:56 +09:00
.gitea/workflows workflows: fix nix store cache 2025-02-01 21:16:13 +09:00
acl fortify: switch to static linking 2025-01-16 17:32:52 +09:00
cmd nix: configure target users via nixos 2025-01-23 17:04:19 +09:00
comp fortify: zsh complete show instance list 2024-12-21 21:13:53 +09:00
dbus dbus: enable syscall filter 2025-01-22 11:49:23 +09:00
dist nix: configure target users via nixos 2025-01-23 17:04:19 +09:00
fst fst: add missing fields to template 2025-01-22 12:09:25 +09:00
helper helper/seccomp: panic on invalid closeWrite use 2025-02-07 12:58:20 +09:00
internal system/dbus: dump messages on early fault 2025-02-07 13:20:56 +09:00
ldd ldd: enable syscall filter 2025-01-22 02:00:49 +09:00
wl wl: separate inline C 2025-01-23 22:06:29 +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 2025-01-25 19:46:33 +09:00
flake.nix proc/priv/shim: seccomp bpf filter via libseccomp 2025-01-20 23:39:47 +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 helper/seccomp: separate seccomp package 2025-01-25 12:59:11 +09:00
nixos.nix nix: mount nvidia devices 2025-01-25 18:05:18 +09:00
options.md release: 0.2.12 2025-01-25 13:40:48 +09:00
options.nix nix: expose compat flag in nixos module 2025-01-25 12:42:48 +09:00
package.nix release: 0.2.12 2025-01-25 13:40:48 +09:00
parse.go linux/std: handle fsu exit status 1 2025-01-01 21:34:57 +09:00
print.go fortify: print permissive defaults warning early 2025-01-21 12:05:31 +09:00
README.md migrate to git.gensokyo.uk/security/fortify 2024-12-20 00:20:02 +09:00
test.nix nix: vm test set sway background 2025-01-25 22:28:04 +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;
        };
      }
    ];
  };
}