FreeBSD Git Server Granular User Permissions using File System Access Control Lists (ACLs)

Previously I wrote about how to create a multi user git server on FreeBSD using standard UNIX file permissions, allowing users that belong to the same group to read and write from and to the same repository. But what happens when some users outside the group, should only read, while others should also write? Standard file permissions are limited, and do not provide sufficient user permission granularity. To workaround this issue, you can use the FreeBSD File System Access Control Lists (ACLs). 

FreeBSD File System Access Control Lists provide an extension to the standard UNIX permission model, allowing administrators to fine-grain access to specified files and directories for individual users. Assuming your kernel is already configured for ACLs, this article shows how to make use of them to provide better control access to a git repository.

  1. Configure default permissions per repository, for a user:
    Prior to adding ACL user permissions, you must configure directory permission inheritance. Permissions for 'group' (g:), 'user' (u:) and 'others' (o:) should be the same as those configured using standard permissions. The last bit (,u:alice:rwx) sets defaults for user 'alice' to read, write and execute:

    find ./example.git -type d -exec setfacl -d -m u::rw-,g::r--,o::---,u:alice:rwx {} \;

    This enables new directories to inherit settings from the parent directory.
    NOTE: 'setfacl' does not support a recursive option, hence the use of 'find'.

  2. Allow the user to read:
    To allow a particular user to read from the repository, run the previous command, with the default directory permission to read (',u:alice:rx-'); followed below by the commands to set permissions to read against files, and read and execute against existing directories:

    find ./example.git -type f -exec setfacl -m u:alice:r-- {} \;
    find ./example.git -type d -exec setfacl -m u:alice:rx- {} \;
  3. Allow the user to read and write (preceded by step 1):
    find ./example.git -type f -exec setfacl -m u:alice:rw- {} \;
    find ./example.git -type d -exec setfacl -m u:alice:rwx {} \;
  4. Revoke all permissions:
    find ./example.git -exec setfacl -b {} \;


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.