Linux desktop application sandbox.
Go to file
Ophestra Umiker 57c1b3eda6
system: handle invalid enablement in String method
Invalid enablement is only caused by bad API usage, however panicking on the spot leaves behind messy state that has to be manually cleaned up.

Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
2024-10-17 14:31:13 +09:00
.gitea/workflows workflows: test workflow to run tests every commit 2024-10-17 00:18:20 +09:00
acl acl: define Go type alias for acl_perm_t 2024-09-21 22:25:03 +09:00
dbus dbus: various accessors for dbus.Proxy internal fields 2024-10-16 01:27:49 +09:00
helper helper/bwrap: add fortify permissive default test case 2024-10-15 02:56:13 +09:00
internal system: handle invalid enablement in String method 2024-10-17 14:31:13 +09:00
ldd ldd: separate Parse from Exec and trim space 2024-10-09 23:51:15 +09:00
xcb fortify: clean up config loading 2024-10-12 01:51:06 +09:00
.gitignore rename to fortify and restructure 2024-09-04 01:20:12 +09:00
LICENSE apply MIT license 2024-07-16 20:49:00 +09:00
README.md update README document 2024-10-13 00:07:10 +09:00
config.go system: move enablements from state package 2024-10-16 14:38:57 +09:00
error.go app: port app to use the system package 2024-10-16 01:38:59 +09:00
flake.lock nix: implement nixos module 2024-09-04 17:03:21 +09:00
flake.nix dbus: add tests 2024-09-28 00:06:16 +09:00
go.mod rename to fortify and restructure 2024-09-04 01:20:12 +09:00
license.go license: embed license in executable 2024-07-16 22:07:40 +09:00
main.go fortify: move PR_SET_DUMPABLE to the beginning of main 2024-10-14 02:48:37 +09:00
nixos.nix nix: pass $SHELL for shell interpreter 2024-10-12 23:01:06 +09:00
package.nix release: 0.0.4 2024-10-15 02:56:49 +09:00
state.go state/simple: prefix store path 2024-10-10 11:03:31 +09:00
version.go fortify: move flag handling to separate files 2024-10-12 01:28:22 +09:00

README.md

Fortify

Go Reference

Lets you run graphical applications as another user in an Android-like sandbox environment (WIP) 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 (WIP).

There are a few different things to set up for this to work:

  • A set of users, each for a group of applications that should be allowed access to each other

  • A tool to switch users, currently sudo and machinectl are supported.

  • If you are running NixOS, the module in this repository can take care of launchers and desktop files in the privileged user's environment, as well as packages and extra home-manager configuration for target users.

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

nix run git+https://git.ophivana.moe/cat/fortify -- -h

Module usage

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

To use the module, import it into your configuration with

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

    fortify = {
      url = "git+https://git.ophivana.moe/cat/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;
    user = "nixos";
    stateDir = "/var/lib/persist/module";
    target = {
      chronos = {
        launchers = {
          weechat.method = "sudo";
          claws-mail.capability.pulse = false;

          discord = {
            command = "vesktop --ozone-platform-hint=wayland";
            share = pkgs.vesktop;
          };

          chromium.dbus = {
            configSystem = {
              filter = true;
              talk = [
                "org.bluez"
                "org.freedesktop.Avahi"
                "org.freedesktop.UPower"
              ];
            };
            config = {
              filter = true;
              talk = [
                "org.freedesktop.DBus"
                "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 = {
                "org.freedesktop.portal.*" = "*";
              };
              broadcast = {
                "org.freedesktop.portal.*" = "@/org/freedesktop/portal/*";
              };
            };
          };
        };
        packages = with pkgs; [
          weechat
          claws-mail
          vesktop
          chromium
        ];
        persistence.directories = [
          ".config/weechat"
          ".claws-mail"
          ".config/vesktop"
        ];
        extraConfig = {
          programs.looking-glass-client.enable = true;
        };
      };
    };
  };
}
  • enable determines whether the module should be enabled or not. Useful when sharing configurations between graphical and headless systems. Defaults to false.

  • user specifies the privileged user with access to fortified applications.

  • stateDir is the path to your persistent storage location. It is directly passed through to the impermanence module.

  • target is an attribute set of submodules, where the attribute name is the username of the unprivileged target user.

    The available options are:

    • packages, the list of packages to make available in the target user's environment.

    • persistence, user persistence attribute set passed to impermanence.

    • extraConfig, extra home-manager configuration for the target user.

    • launchers, attribute set where the attribute name is the name of the launcher.

      The available options are:

      • command, the command to run as the target user. Defaults to launcher name.

      • dbus.config, D-Bus proxy custom configuration.

      • dbus.configSystem, D-Bus system bus custom configuration, null to disable.

      • dbus.id, D-Bus application id, has no effect if dbus.config is set.

      • dbus.mpris, whether to enable MPRIS defaults, has no effect if dbus.config is set.

      • capability.wayland, whether to share the Wayland socket.

      • capability.x11, whether to share the X11 socket and allow connection.

      • capability.dbus, whether to proxy D-Bus.

      • capability.pulse, whether to share the PulseAudio socket and cookie.

      • share, package containing desktop/icon files. Defaults to launcher name.

      • method, the launch method for the sandboxed program, can be "fortify", "fortify-sudo", "sudo".