Tag: Linux Sandbox

  • Securing AI Coding Tools – How to Sandbox Devin Desktop with Bubblewrap

    Allowing an AI coding assistant or autonomous developer agent (like Devin Desktop) to run local Bash scripts, use CLI tools, and access your local development environment comes with inherent security risks. By default, these applications run with your user permissions, meaning they have unrestricted access to your private SSH keys (~/.ssh), cloud credentials (~/.aws), GPG keys (~/.gnupg), chat histories, and sensitive private documents.

    To mitigate this risk without crippling the app’s capability to code, test, and interact with your development sites, we can isolate it using Bubblewrap (bwrap)—the same lightweight containerization utility that powers Flatpak.

    Below is the production-ready sandboxing script, a detailed breakdown of its configuration items, and the exact diagnostic toolkit used to troubleshoot and lock it down.

    Tested Oct 2026 in Linux Mint 21.2 Cinnamon, Linux Kernel 6.8.0-138-generic on Devin Desktop Version: 3.10.67, VS Code OSS Version: 1.126.0, Electron: 42.2.0

    The Complete devin-sandboxed.sh Script

    save as ~/bin/devin-sandboxed.sh and then make it executable and change the System Menu (the Magic or Windows or Clover key opens it)

    # save as ~/bin/devin-sandboxed.sh
    # chmod +x ~/bin/devin-sandboxed.sh
    # In Menu, right-click Edit Menu, select Devin (in Programming), click Properties, in Command put
    #   /home/YOURNAME/bin/devin-sandboxed.sh %F
    #   NOTE: do not use ~ instead of /home/YOURNAME 
    #   /home/YOURNAME/bin/devin-sandboxed.sh %F
    #   NOTE: can not use ~ instead of /home/YOURNAME
    # To capture errors
    #   strace -f -e trace=connect,accept,socket -o ~/Documents/devin_failures.txt ~/bin/devin-sandboxed.sh
    

    The full contents of the script:

    #!/bin/bash
    
    # To capture errors for troubleshooting:
    #   strace -f -e trace=connect,accept,socket -o ~/Documents/devin_failures.txt ~/bin/devin-sandboxed.sh
    
    # Configuration: Define paths using explicit variables
    ALLOWED_SITE_DIR="$HOME/sites"
    CONFIG_DIR="$HOME/.config/devin-desktop"
    DEVIN_PROPER_CONFIG="$HOME/.config/Devin"
    LOCAL_SHARE="$HOME/.local/share/devin-desktop"
    DEVIN_HOME_CONFIG="$HOME/.devin"
    CACHE_DIR="$HOME/.cache/devin-desktop"
    
    # Additional required tool/UI paths
    VSCODE_DIR="$HOME/.vscode"
    WINDSURF_DIR="$HOME/.windsurf"
    CODEIUM_DIR="$HOME/.codeium"
    AGENTS_DIR="$HOME/.agents"
    LANDO_BIN="$HOME/.lando"
    NPM_GLOBAL="$HOME/.npm-global"
    FONT_CACHE="$HOME/.cache/fontconfig"
    THEMES_DIR="$HOME/.themes"
    
    # Ensure config/share dirs exist so they can be mounted writable
    mkdir -p "$CONFIG_DIR" "$DEVIN_PROPER_CONFIG" "$LOCAL_SHARE" "$DEVIN_HOME_CONFIG" "$CACHE_DIR" "$VSCODE_DIR" "$WINDSURF_DIR" "$CODEIUM_DIR" "$AGENTS_DIR" "$ALLOWED_SITE_DIR"
    
    # Build BWRAP flags array safely
    BWRAP_ARGS=(
        --unshare-user
        --share-net
        --uid 1000
        --gid 1000
        --clearenv
    
        # Environment Setup for Display and User
        --setenv HOME "$HOME"
        --setenv USER "$USER"
        --setenv DISPLAY "$DISPLAY"
        --setenv WAYLAND_DISPLAY "$WAYLAND_DISPLAY"
        --setenv XDG_RUNTIME_DIR "$XDG_RUNTIME_DIR"
        --setenv DBUS_SESSION_BUS_ADDRESS "$DBUS_SESSION_BUS_ADDRESS"
        --ro-bind-try "$HOME/.Xauthority" "$HOME/.Xauthority"
        --bind-try "${XDG_RUNTIME_DIR}" "${XDG_RUNTIME_DIR}"
    
        # System core read-only binds
        --ro-bind /usr /usr
        --ro-bind /lib /lib
        --ro-bind /lib64 /lib64
        --ro-bind /etc /etc
        --ro-bind /sys /sys
        --bind /dev/shm /dev/shm
        --bind-try /dev/dri /dev/dri
        --symlink usr/bin /bin
        --proc /proc
        --dev /dev
        --tmpfs /tmp
    
        # Enable machine identity for D-Bus / keyring integration
        --ro-bind-try /var/lib/dbus /var/lib/dbus
    
        # Recreate a clean home directory structure inside the sandbox
        --dir "$HOME"
    
        # Explicitly bind your allowed site directory and app configurations
        --bind "$ALLOWED_SITE_DIR" "$ALLOWED_SITE_DIR"
        --bind "$CONFIG_DIR" "$CONFIG_DIR"
        --bind "$DEVIN_PROPER_CONFIG" "$DEVIN_PROPER_CONFIG"
        --bind "$LOCAL_SHARE" "$LOCAL_SHARE"
        --bind "$DEVIN_HOME_CONFIG" "$DEVIN_HOME_CONFIG"
        --bind "$CACHE_DIR" "$CACHE_DIR"
        --bind "$VSCODE_DIR" "$VSCODE_DIR"
        --bind "$WINDSURF_DIR" "$WINDSURF_DIR"
        --bind "$CODEIUM_DIR" "$CODEIUM_DIR"
        --bind "$AGENTS_DIR" "$AGENTS_DIR"
    
        # Bind Development Tools & System UI (Read-Only where appropriate)
        --bind "$LANDO_BIN" "$LANDO_BIN"
        --bind "$NPM_GLOBAL" "$NPM_GLOBAL"
        --ro-bind-try "$HOME/.config/git/config" "$HOME/.config/git/config"
        --ro-bind-try "$FONT_CACHE" "$FONT_CACHE"
        --ro-bind-try "$THEMES_DIR" "$THEMES_DIR"
    
        # Explicitly block/hide sensitive folders by turning them into empty tmpfs mounts
        --tmpfs "$HOME/.ssh"
        --tmpfs "$HOME/Documents"
        --tmpfs "$HOME/.gnupg"
        --tmpfs "$HOME/.aws"
        --tmpfs "$HOME/.claude"
        --tmpfs "$HOME/.bash_history"
    
        # GUI / X11 / Wayland socket access
        --ro-bind /tmp/.X11-unix /tmp/.X11-unix
        --bind-try "${XDG_RUNTIME_DIR}" "${XDG_RUNTIME_DIR}"
    )
    
    exec bwrap "${BWRAP_ARGS[@]}" /usr/bin/devin-desktop "$@"

    Line-by-Line Breakdown: What Each Item Does and Fixes

    1. Namespace & Core Isolation Flags

    • --unshare-user & --uid 1000 --gid 1000: Maps your current user into an unprivileged container namespace so it cannot escalate privileges or affect the host system.
    • --share-net: Essential for Electron-based apps and deep-link handlers. Without network sharing, local TCP loopback communication breaks, and OAuth callback redirection fails to reach the app.
    • --clearenv: Wipes out inherited host environment variables to ensure a pristine, controlled launch environment.

    2. Graphics Rendering & Performance (/dev/shm, /dev/dri)

    • --bind /dev/shm /dev/shm: Chromium and Electron applications rely heavily on shared memory (/dev/shm) for inter-process communication (IPC) and rendering buffers. Without this, the UI renderer starves, resulting in blank or frozen “not responding” windows.
    • --bind-try /dev/dri /dev/dri: Passes through Direct Rendering Infrastructure nodes to enable hardware-accelerated GPU graphics pipelines.

    3. Data Privacy & Hard Blocking (--tmpfs)

    • --tmpfs "$HOME/.ssh", --tmpfs "$HOME/.aws", etc.: Instead of just restricting permissions, these directives create empty, isolated RAM-backed filesystem views (tmpfs) over your private directories. To the application, these folders appear completely empty or non-existent, shielding your credentials from exposure.

    4. Authentication & Keyring Integration (/var/lib/dbus)

    • --ro-bind-try /var/lib/dbus /var/lib/dbus: Electron and VS Code-based apps look for /var/lib/dbus/machine-id to identify the machine context. Binding this allows the app to cleanly initialize state tracking and fall back gracefully to local file-based credential storage when a full desktop secret service daemon is unavailable.

    Troubleshooting Toolkit: How We Diagnosed and Fixed It

    When building strict application sandboxes, things inevitably break on the first try. Here are the exact diagnostic utilities and grep filters used to track down hidden dependencies:

    Capturing File Access Failures (strace)

    To see every file path, library, or socket the application tried to open or touch during startup:

    strace -f -e trace=openat,access -o ~/Documents/devin_failures.txt ~/bin/devin-sandboxed.sh

    Filtering D-Bus, Sockets, and Machine IDs

    To diagnose why desktop integration or authentication handlers were failing, we filtered the strace log using grep:

    grep -i -E "dbus|bus|socket" ~/Documents/devin_failures.txt

    What it revealed: Missing access to /var/lib/dbus/machine-id, which caused authentication modules to lock up until the read-only bind was added.

  • Why Your Computer’s Apps Can See Your Secrets (And an Easy Way to Fix It)

    As a creator, coach, or entrepreneur, your computer is your digital office. It holds everything: client notes, financial records, passwords, and private SSH keys.

    For years, we operated under a comforting assumption: If I trust the company that made this app, I trust the app completely.

    Unfortunately, modern software has changed. Today, applications aren’t written by a single team—they are assembled from thousands of third-party pieces built by anonymous developers. And a new category of tools—autonomous AI coding assistants—can write and execute their own terminal commands on the fly.

    If an AI tool gets confused, or if a background component is compromised, standard computer permissions allow it to look at any file your user account owns.

    The Good News: You Don’t Need a Computer Science Degree to Stay Safe

    You don’t need to write complex security rules or stress over system files. You can protect your workspace using two effortless strategies:

    Strategy 1: Stick to Sandboxed App Stores (Flatpaks & Snaps)

    When installing desktop software on Linux Mint or Ubuntu, check if the app is available as a Flatpak or Snap in your software center.

    • Why it helps: These formats automatically place apps inside an invisible “sandbox”. A sandboxed text editor or media player literally cannot see your private documents or keys because the operating system hides them.

    Strategy 2: Use a Simple Startup Shield for Autonomous AI Tools

    For advanced AI coding software that needs to look at your project folders but nothing else, you can wrap its launch command in a tiny security script (often called a sandbox wrapper).

    Instead of letting an AI tool roam free across your entire home directory, a simple launcher script restricts it to a single designated folder (like ~/sites/) while cutting off access to sensitive areas like your .ssh or Documents folders.

    By taking these small steps, you keep your digital workspace secure without getting bogged down by technical headaches!

    How You Can Make a Sandbox Wrapper for Your Software That Needs A Startup Shield

    Here is a copy-and-paste prompt you can give to an assistant, a tech-savvy employee, or use yourself with Gemini.

    This prompt instructs Gemini to act as a Linux security guide, ask a few quick questions about your specific setup, and then output a ready-to-run Bubblewrap (bwrap) script tailored precisely to your computer.

    Act as a Linux security expert and systems administrator. I want to create a secure Bubblewrap (bwrap) sandbox script for a desktop application on Linux (such as an AI coding tool) to restrict it from accessing sensitive folders like ~/.ssh, ~/Documents, or ~/.aws, while allowing it to access a specific project folder, and its settings folder.
    
    To help me write the exact custom Bash script I need, please ask me the following 4 questions:
    1. What is the exact command or name of the application I want to sandbox (e.g., devin-desktop)?
    2. What specific folder(s) does the application need permission to read and write to (e.g., ~/sites/, and its own settings)?
    3. What is my Linux username?
    4. Are there any other specific folders I want to completely hide or block from this app?
    
    Once I answer those questions, write a complete, copy-pasteable Bash script using bwrap that I can save into my ~/bin/ folder, make executable, and run safely.