Dealing with file permission on Linux

May 28, 2026

For 2 days, I had to deal with a repository in one of my jobs. It was a production repo that, over time of poor maintenance, had been in the ownership of root user. This is not ideal because you don't want a folder used by webserver to be owned by root. It's a security nightmare, and it is hard to pull code with git. I constantly had to use sudo.

Solving with ACL

When dealing with this problem on the production server, I had a different development server, set up to closely match the deployment of the production. As I navigated through the difference between the two servers' repos to determine the cause of the problem, I found that:

  • They both are owned by root:root. But the dev one could be updated with git pull while the prod one I had to sudo git pull
  • The dev one has a hidden ACL list. Normally, a folder when typed in getfacl shows this:
user::rwx
group::r-x
other::--x

while the dev repo showed:

user::rwx
group::r-x
group:padmins:rwx
mask::rwx
other::r-x

Notice padmins. My user was part of that group, which explained why I could pull the code from the remote repo. I tried setting ACL rules on the prod's repo but failed. It said that it couldn't run setfacl successfully. Turns out, the web was served from a network drive, so most likely the protocol didn't support ACL.

Solving with user:group

I tried a different approach. I changed specific folders that tend to have changes instead of all the repo because I didn't want to cause a fuss. I learned a couple of lessons:

  • Getting git to show verbose logs can be done via GIT_TRACE=1 GIT_TRACE_PERFORMANCE=1 git <command>.
  • You need to change ownership of .git if you want any command of git to work. I was trying to stash a change, and it kept denying. Not only that, the uncommitted files and folders containing them need to have permissions to be unlinked, too. So those containing folders need their permission set to either 644 (rw-r--r--), 664 (rw-rw-r) or 775 (rwxrwxr-x) and with your user:group ownership. You need write permission on the directory containing it, not on the file itself.
  • Be cautious when changing permission relating to your user. The table below shows what git records when you commit a change. You can verify what git thinks with git ls-files -s <file>. This command shows what's in git's index. git doesn't care about ownership, which is the angle I used to change the repo so I could easily pull changes without sudo.
Github ModeActual ModeMeaning
1006446xxNon-executable file
1007557xxExecutable file
120000Symbolic link
  • Even if I set the folder's permission, I kept losing the group write bit. I discovered that umask was set to 0022, which always unset the group write bit. I have to set it back to umask 0002. What each umask bit represents:
    • First Digit (0): Special permissions like SUID, SGID, or the sticky bit. In most umask contexts, this is simply a leading zero and has no effect on standard creation.
    • Second Digit (0): Permissions for the User (Owner). 0 means no permissions are removed (the owner keeps full access).
    • Third Digit (2): Permissions for the Group. 2 means write access is removed.
    • Fourth Digit (2): Permissions for Others. 2 means write access is removed.
  • You actually need execution permission bit (x) for a directory in order to enter or cd it. The system treats this bit as search permission. Best to set the permission as 775 (normal permission for most users).