Skip to content

Recipe: a native game

A game needs more than a CLI tool: a GPU, audio, a display, fonts, and a place to write saves. It also has the most to gain from confinement, because a game is a large binary from a stranger that you run for hours.

Start from the profile

sh
bailey run --profile native-game ~/games/thegame/thegame

The profile grants fonts, icons, /dev/dri, and /dev/snd over the untrusted floor. It does not grant the game's own directory, because that is per-game.

Add the per-game config

toml
# ~/games/thegame/bailey.toml
[filesystem]
read = ["."]
write = ["./saves", "~/.local/share/thegame"]
execute = ["./thegame"]

[resources]
memory = "8GiB"
pids_max = 1024

Then:

sh
bailey run --profile native-game ~/games/thegame/thegame

Share the desktop rules across games

Put the parts that apply to every game one directory up, and let the cascade do the rest:

~/games/
  bailey.toml          # GPU, audio, display socket, fonts
  thegame/
    bailey.toml        # this game's own directory and saves
    thegame
toml
# ~/games/bailey.toml
[filesystem]
read = ["/usr/share/vulkan", "/usr/share/glvnd", "~/.cache/mesa_shader_cache"]
write = ["/run/user/1000"]           # your own runtime dir: Wayland, PipeWire

Replace 1000 with your uid.

NVIDIA

The bundled profile grants /dev/dri, which is what Mesa uses. The proprietary NVIDIA driver needs its own nodes:

toml
[[device]]
path = "/dev/nvidiactl"
access = "rw"

[[device]]
path = "/dev/nvidia0"
access = "rw"

[[device]]
path = "/dev/nvidia-uvm"
access = "rw"

Controllers

toml
[[device]]
path = "/dev/input"
access = "r"

This grants read on all input devices, including your keyboard, which is a keylogging surface. Grant the specific event* node for your controller if you can identify it.

Networking

Most single-player games do not need the network. Leave egress = "deny", which is the default.

For a game that does, allow the port and nothing else:

toml
[network]
egress_allow = [{ host = "*", port = 443 }]
bind_ports = [27015]

Remember that only TCP is restricted today. A game using UDP for multiplayer traffic is not restricted by this at all, in either direction.

Wayland and X11

Prefer Wayland. A Wayland client is confined to its own surfaces by the protocol. X11 has no such boundary: every client can read every other client's input and window contents, so an X11 game is unsandboxable at the display layer no matter what the filesystem policy says.

Audit it once

Games touch a lot. Record a session, then read the output rather than piping it straight into a profile:

sh
bailey audit --save-trace game.json ~/games/thegame/thegame

Anti-cheat systems, telemetry, and launcher integrations all show up here, and they are exactly the accesses worth deciding about deliberately.

Released under the MIT or Apache-2.0 license.