How to set up a git repository where different users can only see certain parts? - security

How do you set up a git repository where some users can see certain parts of the source code and other users can see all of it? I've seen lots of guides for only giving certain users commit access, but these assume everyone should have read access. I've also heard of gitosis, but I'm not sure it supports this and it hasn't had any commits in over a year so I think it's dead.

In short: you can't. Git is snapshot based (at conceptual level at least) version control system, not changeset based one. It treats project (repository) as a whole. The history is a history of a project, not a union of single-file histories (it is more than joining of per-file histories).
Using hooks like update-paranoid hook in contrib, or VREFs mechanism of gitolite, you can allow or forbid access to repository, you can allow or forbid access to individual branches. You can even forbid any commits that change things in specified subdirectory. But the project is always treated as a whole.
Well, there is one thing you can do: make a directory you want to restrict access to into submodule, and restrict access to this submodule repository.

The native git protocol doesn't support this; git assumes in many places that everybody has a complete copy of all of the history.
That said, one option may be to use git-subtree to split off part of the repository into its own subset repository, and periodically merge back.

Git doesn't support access control on the repository. You can however, implement access control on the repository yourself, by using hooks, more specifically the update hook.

Jörg has already pointed out that you can use hooks to do this. Exactly which hook(s) you need depends on your setup. If you want the permissions on a repo that gets pushed to, you'll need the update hook like he said. However, if it's on a repo that you're actually working in (committing and merging), you'll also need the pre-commit and post-merge hooks. The githooks manpage (Jörg linked to this too) notes that there's in fact a script in the contrib section demonstrating a way to do this. You can get this by grabbing a git tarball, or pull it out of git's gitweb repo: setgitperms.perl. Even if you're only using the update hook, that might be a useful model.

In general, Git is not intended for this. By now it seems to have out-of-the-box access control only up to the repository level.
But if you need just to hide some part of secret information in your Git repository (which is often the case) you can use git-crypt (https://github.com/AGWA/git-crypt) with encryption keys shared based on users GPG keys (https://gnupg.org/).
Alternatively you can use git submodules (https://git-scm.com/book/en/v2/Git-Tools-Submodules) if you can break your codebase to logical parts. Then all users receive access only to certain repositories which you then integrate into 'large' codebase through sub-modules where you add other code and allow it for only 'privileged' users.

Related

Clearcase multisite vs Gitlab.... anything?

The company I work for uses Clearcase, even though it was EOL'd on the platforms in which we run it years ago. It is ancient and fragile tech, but one thing it does have is a multisite support that allows for the synchronization of air-gapped repos. Because of security issues, we use secure USB sticks to copy packets and take them to the other side, then apply them with scripts.
Developers and DevOps people want to make a business case to migrate to GitLab, but I cannot find any mention of a feature in GitLab that would allow me to do easily do this. There's something about bundles, but the info I have found is years old and it doesn't seem like too many people are using it.
Does GitLab not support this? Simple synchronization of one repo to another over an air gap using some sort of secure media? If so, it's no wonder so many teams are still using ClearCase.
While not exactly easy, air-gap updates of Git repository is possible through the git bundle command.
It produces one file (with all the history, or only the latest commits for an incremental update), that you can:
copy and distribute easily (it is just one file after all)
clone or pull from(!)
This is not tied to GitLab, and can be applied to any Git repository.
From there, I have written before on migration from ClearCase to Git, and I usually:
do not import the full history, only major labels or UCM baselines
split VObs per project, each project being one Git repository
revisit what was versioned in Vobs: some large files/binaries might need to be .gitignore'd in the new Git repository.
You would not "migrate views": they are just workspace (be it static or dynamic). A simple clone of a repository is enough to recreate such a workspace (static here).

How to merge a Git branch using a different identity?

We are using Git for a website project where the develop branch will be the source of the test server, and the master branch will serve as the source for the live, production site. The reason being to keep the git-related steps (switching branches, pushing and pulling) to a minimum for the intended user population. It should be possible for these (not extremely technical) users to run a script that will merge develop into master, after being alerted that this would be pushed to live. master cannot be modified by normal users, only one special user can do the merge.
This is where I'm not sure how to integrate this identity change into my code below:
https://gist.github.com/jfix/9fb7d9e2510d112e83ee49af0fb9e27f
I'm using the simple-git npm library. But more generally, I'm not sure whether what I want to do is actually possible as I can't seem to find information about this anywhere.
My intention would be of course to use a Github personal token instead of a password.
Git itself doesn't do anything about user or permission management. So, the short answer is, don't try to do anything sneaky. Rather, use Github's user accounts they way they were intended.
What I suggest is to give this special user their own Github account, with their own copy of the repo. Let's say the main repo is at https://github.com/yourteam/repo, and the special repo is at https://github.com/special/repo.
The script will pull changes from the team repo's develop branch, and merge this into it's own master branch and push to https://github.com/special/repo.
Then, it will push its changes to the team's master branch. This step can optionally be a forced push, since no one else is supposed to mess with master, anyway. (In case someone does, using a forced push here means they have to fix their local repo to match the team repo later on, rather than having the script fail until someone fixes the team repo.)
At the same time, your CI software will notice that master has changed at https://github.com/special/repo, and will publish as you normally would. This is the linchpin: the CI doesn't pay attention to the team repo, so although your team has permission to change it, those changes don't make it into production.
This special user will need commit access to the team repo, in addition to its own GitHub repo. The easiest way is probably to use an SSH key, and run the git push command from the script, rather than trying to use the GitHub API.

Is there any way to set a Git branch as readonly with Stash?

In our office we are using Stash without server access (maximum access level is create branch) so we need to restrict a particular Git branch from the pushes. So simply, what we need to do is we need to freeze our branch after the release.
Currently what we are doing is we replicate the feature branch and remove that branch from the remote, but that is bit risky.
Are there any other possible solutions?
You should be able to associate to that branch a permission which suits your need.
See "Stash: Using branch permissions".
By limiting write access to a specific owner, for instance, you remove push for all other contributors.
Technically, you could set up a hook that forbids pushing to a certain branch. This is discussed in Is there a way to lock a branch in GIT.
However, your statement
what we need to do is we need to freeze our branch after the release
makes me think that you actually want to use git tag instead of making a branch read-only.

how to set permission in Git?

I am new to Git and after I lots of searching I found that I must have set Linux permissions in my Git server.
But I want to know, is it possible to set permissions in Git?
I am working on a team about six people and I don't like to everyone on the team can access all the project for security reasons.
For example, If somebody in my team works on UI in my Store section I want to he/she have it's own branch but when he/she PULL the project with Git just have access to files and folders I let.
I have to add that I have my own Git server on a local network using Linux Debian and I'm using "SourceTree" as my GUI for Git and I have few experience on Git command line, so I need do it from GUI if possible.
Edited:
Does Git lab support permission like this: I have a repository that uses Laravel framework and I'd like to set permission for UI developers that only access views and PHP developers access some controllers not all the part of the controller in the project.
You can checkout GitLab: https://about.gitlab.com/ for this. Out of the box git does not support what you need/want.
No, Git doesn't manage this directly. Anyone with authentication credentials to the repository has access to the entire repository.
Traditionally, this is managed with third-party solutions, such as Gitolite, GitHub private repositories, and other systems.
In addition to other answers: if you want only certain parts of project to be accessible to each developer, you can use git submodules.
This is also preferable if project has logically and functionally separate parts. (Like front-end and back-end. )

Possible to have multiple git users logged in as root?

Is it possible to have multiple git users logged as the same Linux user?
What I would like is that multiple admins can login as root, make a git pull to a directory assigned to them, and then git push, but so we still can see who made which changes in the git log?
Each one of your users can clone the repo for his own. That repository would have his config.user and config.email according to the person using it, and they all pull and push to the same "central" repo.
Anyway, they are all root, so there's not much to do about preventing one of this admins to commit as another one. But if they aren't evil, you can do this.
gitosis can surely help to access control the repository, too, if needed.
Personally I would say that the correct mechanism to make sure that you can track changes in this sort of case would be not to have root as a permitted username for your repository. They would all have to commit with their individual user names by logging in as themselves.
In general nobody should be logged in as root other than very briefly while performing a specific task such as installing a new package - not all of the time while developing so anything you do to make such practices unrewarding is good.
It would be safer to manage that kind of access control with an authorization layer like gitolite, instead of relying on system account.
That way, you are controlling who can pull what.
Although that wouldn't control the "where" part (where the users would pull those repos to)

Resources