If a user has read access to a repository, you should assume that they can access anything in that repository. From gitnamespaces(7)
:
The fetch and push protocols are not designed to prevent one side from stealing data from the other repository that was not intended to be shared. If you have private data that you need to protect from a malicious peer, your best option is to store it in another repository. This applies to both clients and servers. In particular, namespaces on a server are not effective for read access control; you should only grant read access to a namespace to clients that you would trust with read access to the entire repository.
All of that applies regardless of whether namespaces are used or not. Note also that anyone who can clone the repository can modify it arbitrarily on their own system.
If you're okay with those users having read access, but simply want to prevent them from modifying those files and then merging them into certain branches, there are a couple ways to go about that.
The first way, if you're using your own custom Git server, is a pre-receive
hook, which can check to see if the data being pushed meets some criteria, and if so can accept it or reject it.
For most major forges, pre-receive
hooks are not available, and you instead will want to force all changes to those branches to go through a pull request process. You can then require approval from a specific team for files being modified (GitHub calls this CODEOWNERS
) or you can use a CI job to reject files from being modified based on whatever criteria you like. If that CI job is required to merge, users will not be able to bypass it, and you can implement an effective control.