--- created: '2026-05-18' path: Sources/Homelab project: herbys-dev-setup tags: - git - ssh - automation type: session-notes --- ## Outcome Resolved a recurring permissions issue where `herbyadmin` (Claude Code / Lovebug operating account) couldn't write to git repo files under `/opt/projects` after `travadmin` (GitHub SSH push/pull account) ran `git pull`. Applied POSIX default ACLs to `/opt/projects` so both users get explicit `rwX` on everything in the tree — current and future. ## Topics Covered - Shared git repo across two users (`herbyadmin` + `travadmin`) under `/opt/projects` - Why setgid on directories wasn't enough — `git pull` uses atomic rename, which bypasses setgid inheritance - `core.sharedRepository = group` vs. file ownership — separate concerns - POSIX ACLs (`setfacl` / `getfacl`) as the durable fix - Access ACL vs. default ACL — default propagates to anything newly created ## Key Learnings - **Setgid alone doesn't survive `git pull`.** Git creates pack files in a temp location and renames them in. `mv` preserves the original group; it doesn't re-apply the parent directory's setgid. Result: files land with the pulling user's primary group, not the project group. - **`core.sharedRepository = group` is necessary but not sufficient.** It makes git write group-writable files (mode bits), but doesn't control which group owns them. - **Default ACLs are the right tool for shared trees.** They sit alongside traditional ownership, grant access independently, and propagate automatically to new files regardless of which user, umask, or rename trick created them. - **`rwX` (capital X) means "execute on directories only."** Cleaner than `rwx` for ACL templates — files don't get a stray execute bit, directories still get traversal. ## The Pattern Applied once to `/opt/projects`: ``` sudo setfacl -R -m u:herbyadmin:rwX,u:travadmin:rwX,g:devprojects:rwX \ -m d:u:herbyadmin:rwX,d:u:travadmin:rwX,d:g:devprojects:rwX \ /opt/projects ``` - `-R` — recursive over existing files - `-m` — modify (add ACL entries) - `d:` prefix — default ACL, inherited by new files/dirs - Both users + the group get explicit access, so any ownership combination still works To add a future user/service account: ``` sudo setfacl -R -m u:newuser:rwX -m d:u:newuser:rwX /opt/projects ``` ## Follow-ons - [ ] Verify the ACL pattern survives a few real `git pull` / `git commit` cycles from both users - [ ] Consider adding `setfacl` step to the Ansible role for `herbys-dev-setup` so any new dev VM gets the same shared-repo permissions baked in - [ ] If a third agent account (e.g., a CI runner) ever needs repo access, extend the ACL rather than juggling group memberships