AI Sandboxing on Linux

CLI and GUI

If you have AI Agents and/or Coding Tools running on your local machine, you might have noticed that these things are running a lot of crazy commands and depending on what you do with them, they probably should not have access to your entire machine and filesystem.

My solution was to put it into a bubblewrap sandbox. Of course this is nowhere near secure but it protects against accidentally typing a wrong prompt in a wrong directory and improves privacy since you can hide your home folder and essentail system files. After all these things usually just need to see your GIT Repositories and your code and maybe have access to /tmp

Bubblewrap is a very simple method to keep this things somehwat contained.


You can just put a wrapper command around you AI tool like this for example:

CODEX Sandbox
( ZSH syntax )

codex_safe() {
    local CODEX_REAL_GIT="$HOME/GIT"
    local CODEX_STATE="$HOME/.codex-sandbox"
    local CURRENT_DIR="$PWD"

    if [[ "$CURRENT_DIR" != "$CODEX_REAL_GIT" && "$CURRENT_DIR" != "$CODEX_REAL_GIT/"* ]]; then
        echo "ERROR: Run codex_safe from somewhere inside ~/GIT"
        return 1
    fi

    #mkdir -p "$CODEX_STATE"

    env -i \
        PATH="/usr/local/bin:/usr/bin:/bin" \
        HOME="$HOME" \
        USER="$USER" \
        LOGNAME="$USER" \
        SHELL="/bin/zsh" \
        TERM="${TERM:-xterm-256color}" \
        LANG="${LANG:-C.UTF-8}" \
        bwrap \
            --die-with-parent \
            --new-session \
            --unshare-user \
            --unshare-pid \
            --unshare-ipc \
            --unshare-uts \
            \
            --ro-bind /usr /usr \
            --ro-bind /etc /etc \
            \
            --symlink usr/bin /bin \
            --symlink usr/bin /sbin \
            --symlink usr/lib /lib \
            --symlink usr/lib /lib64 \
            \
            --proc /proc \
            --dev /dev \
            \
            --tmpfs /home \
            --dir $HOME \
            --dir ${HOME}/.codex \
            \
            --bind "$CODEX_REAL_GIT" ${HOME}/GIT \
            --bind "$CODEX_STATE" ${HOME}/.codex \
            --bind /tmp /tmp \
            \
            --chdir "$CURRENT_DIR" \
            \
            /usr/bin/codex "$@"
}

Of course this is just a CLI Tool. IF you want to sandbox a while IDE with graphical user interface, it needs a bit more tuning.

Here is an example of the KIRO IDE with the GUI Version:

KIRO IDE Sandbox
( ZSH Syntax )

kiro_ide_safe() {
    local KIRO_REAL_GIT="$HOME/GIT"
    local KIRO_STATE="$HOME/.kiro"
    local CURRENT_DIR="$PWD"

    if [[ "$CURRENT_DIR" != "$KIRO_REAL_GIT" && "$CURRENT_DIR" != "$KIRO_REAL_GIT/"* ]]; then
        echo "ERROR: Run kiro_ide_safe from somewhere inside ~/GIT"
        return 1
    fi

    #mkdir -p "$KIRO_STATE"
    env -i \
        PATH="/usr/local/bin:/usr/bin:/bin" \
        HOME="${HOME}" \
        USER="${USER}" \
        LOGNAME="${USER}" \
        SHELL="/bin/zsh" \
        TERM="${TERM:-xterm-256color}" \
        LANG="${LANG:-C.UTF-8}" \
        XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
        WAYLAND_DISPLAY="$WAYLAND_DISPLAY" \
        DISPLAY="$DISPLAY" \
        XDG_SESSION_TYPE="$XDG_SESSION_TYPE" \
        DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" \
        bwrap \
            --die-with-parent \
            --unshare-ipc \
            --unshare-uts \
            \
            --ro-bind /usr /usr \
            --ro-bind /etc /etc \
            --dir /opt \
            --ro-bind /opt/Kiro /opt/Kiro \
            \
            --symlink usr/bin /bin \
            --symlink usr/bin /sbin \
            --symlink usr/lib /lib \
            --symlink usr/lib /lib64 \
            \
            --proc /proc \
            --dev /dev \
            \
            --tmpfs /home \
            --dir ${HOME} \
            --dir ${HOME}/.kiro \
            --dir ${HOME}/.config \
            --dir ${HOME}/.cache \
            --dir ${HOME}/.pki \
            --dir ${HOME}/.local \
            --dir ${HOME}/.local/share \
            --dir ${HOME}/.local/state \
            --dir ${HOME}/.aws \
            \
            --bind "$KIRO_REAL_GIT" ${HOME}/GIT \
            --bind "$KIRO_STATE" ${HOME}/.kiro \
            --bind /tmp /tmp \
            --bind /run /run \
            --bind "$XDG_RUNTIME_DIR" "$XDG_RUNTIME_DIR" \
            --bind "$HOME/.config" ${HOME}/.config \
            --bind "$HOME/.cache" ${HOME}/.cache \
            --bind "$HOME/.pki" ${HOME}/.pki \
            --bind "$HOME/.local/share" ${HOME}/.local/share \
            --bind "$HOME/.local/state" ${HOME}/.local/state \
            --bind "$HOME/.aws" ${HOME}/.aws \
            \
            --chdir "$CURRENT_DIR" \
            \
            /usr/bin/kiro --no-sandbox "$@"
}