From 3669bec8ff3b8ce4a85dd043c10d9f8952d427ab Mon Sep 17 00:00:00 2001 From: Joakim Persson Date: Mon, 20 Apr 2026 22:12:19 +0200 Subject: [PATCH] Stop leaking host GIDs into VM via rsync -a Replace 'rsync -az' with 'rsync -rlptDz' (archive minus owner/group preservation). Running as a non-root user on the VM, rsync can't preserve UID anyway, but it was successfully preserving GID whenever the numeric GID happened to exist on the target. That caused synced dirs (~/.aws, ~/.config/opencode, ~/.config/nvim, ~/.agents/skills, ~/.ssh) to end up with group 1001 on the VM, which was confusing and, for group-writable mode, potentially insecure. With -o and -g dropped, received files get the receiving user's UID:GID (devbox:devbox), which is what you want. --- deploy/sync-to-vm.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/deploy/sync-to-vm.sh b/deploy/sync-to-vm.sh index 5b862c5..4d9f337 100755 --- a/deploy/sync-to-vm.sh +++ b/deploy/sync-to-vm.sh @@ -113,9 +113,13 @@ for entry in "${MOUNT_PATTERNS[@]}"; do ssh_cmd "mkdir -p ${remote_path}" # Sync with rsync (fall back to scp if rsync unavailable) - # Exclude generated/cached content that gets recreated on the remote + # Exclude generated/cached content that gets recreated on the remote. + # Use -rlptD (archive minus -o -g) so ownership on the remote is set + # by the receiving user (devbox). Preserving host UID/GID with -a + # tagged files with the pusher's numeric GID, which leaked through + # whenever the VM happened to have a matching group (see #group-1001). if command -v rsync &>/dev/null; then - rsync -az --progress \ + rsync -rlptDz --progress \ --exclude='node_modules' \ --exclude='__pycache__' \ --exclude='.venv' \