mcp: session-notes — ACL fix for shared git repos under /opt/projects
This commit is contained in:
parent
16af944861
commit
ec93dd28dc
56
Sources/Homelab/2026-05-18-acl-shared-repo-permissions.md
Normal file
56
Sources/Homelab/2026-05-18-acl-shared-repo-permissions.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue
Block a user