NixOS: Windows Game Sandboxing

By Kitsune

Work notes ·
NixOS Nix Linux Wine Sandboxing
Last updated on

I wanted to run a Windows game without making the rest of my machine part of its workspace.

That sounds straightforward until launchers, Wine drive mappings, mounted disks, and compatibility runtimes all get involved. A game needs access to its files. Its installer may need temporary storage. The launcher needs enough of the environment to start the process. None of that tells me that every mounted volume should be visible.

On NixOS, I worked on a per-game sandbox around Lutris and UMU using bubblewrap. The goal was to make filesystem access explicit and keep the setup reproducible through configuration.

Give the application a deliberate filesystem

The design used a policy file to describe the access intended for a particular game. In the setup I tested, a selected game directory appeared as the Windows D: drive, while broad access through mount locations such as /mnt and /run/media was hidden.

The distinction mattered to me. A convenient drive letter is only part of the experience. I also wanted to control what the process could reach underneath that mapping.

The policy itself needed protection too. If an application can rewrite the rules used for its next launch, those rules are not a dependable boundary.

On June 26, I confirmed that the sandbox arrangement was working as intended in my test. That was a useful milestone: the launcher and compatibility tooling could cooperate with a narrower view of the filesystem.

It was a functional result, rather than an exhaustive security audit. I still need to evaluate any access exposed for display, devices, or other integration separately from filesystem restrictions.

Try the filesystem policy

This model shows the difference between a drive mapping and the access behind it. Toggle access to other volumes, then try making the launch policy writable. The paths are examples; the controls don’t change your machine.

Choose what the game can see

Example access from inside the sandbox
ResourceGame viewAccess
/games/exampleD:Read/write
/mnt/photosOther mounted volumeHidden
/run/media/archiveRemovable volumeHidden
Private temporary directory/tmpRead/write
Launch policyWrapper configurationRead only

The selected game directory is writable; other mounted volumes are hidden and the policy is read only.

The bubblewrap documentation makes the same distinction about scope: the security properties depend on the arguments and resources made available to the sandbox. This example only covers filesystem visibility.

Nix makes the workaround something I can inspect

What appeals to me about putting this work into Nix is having the environment and launch behavior represented as configuration.

When a wrapper or dependency changes, I want that change to be visible. When I revisit the machine later, I want to understand why a package or an argument is there. A working shell command is useful; a setup I can reconstruct is much more useful.

There is still a runtime policy to reason about. Nix doesn’t decide which directories a game should be allowed to see. It gives me a place to express the machinery that applies those decisions consistently.

That is especially valuable when there are several programs between the desktop icon and the actual game process. I want to understand which layer creates the environment and which layer might broaden it again.

Now I can run silly games without giving them access to my whole computer! Yay!

© 2026 Kitsune