wiki-vault/Sources/Homelab/2026-05-18-acl-shared-repo-permissions.md

56 lines
2.7 KiB
Markdown

---
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