git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Locked down (but still shared) repositories

From
Shawn Pearce <spearce@spearce.org>
Date
Dec 7, 2006, 11:35 UTC
Message-ID
<20061207113539.GA10781@spearce.org>

I have a number of repositories that I want to share across a number of users on the same UNIX system.

For various auditing reasons the repositories need to be tightly controlled. That is the following cannot be permitted:

  * delete or overwrite a loose object;
  * delete or overwrite a pack file;
  * delete or overwrite a ref, except see below;
  * change the config;
  * change the description;
  * change HEAD;

The only changes that are permissible can be made through git-receive-pack, which limits the user to only the following:

 * upload (possibly new) objects;
 * create/update/force-update a ref;
 * delete a ref;

And the latter two are controlled by a very strict update hook. The update hook checks the ref name and real user id against an ACL file (info/allowed-users) and checks to see if the user can perform the requested operation against that ref, with four operations being recognized:

  * A == the ref is being created;
  * U == the ref is being fast-forwarded;
  * R == the ref is being rewound/reset;
  * D == the ref is being deleted;
The update hook also requires that all lines returned by:
  git-rev-list --pretty=raw $3 --not --all | egrep ^committer

correspond to a name/email address combination registered in another table for the real user id (info/allowed-committers). Which means we can actually trust the committer field of all commits which are referenced by refs, as the UNIX system authenticated them. The tagger field is also checked for every tag, but its slightly more involved than the simple line above as it peels back the tag layers as needed. :)

So the update hook is update-hook-example.txt, but suffering from extreme paranoia and has been put on steriods. I'm considering sending it in for Documentation/howto, or contrib.

Which brings me to the following problem:

I can't create the repository with --shared, as the UNIX users all have normal shell access to the system. (/bin/rm would work wonders to let a user violate a number of the items above.)

I also cannot create secondary git-only UNIX accounts for each user, using git-shell in the git-only account. (For example "spearce" and "spearce-git", with the latter using git-shell and being in a group which does have repository access, while the former doesn't.)

The workaround that I have come up with is the following:

The repositories are all owned by a single user, and were created without --shared, so only the owner can modify the repository. The repositories are however readable by a specific group, and all permitted users of that repository are members of that group. So they can read the repository files directory, which works very well with objects/info/alternates. :-)

git-receive-pack on this system is owned by the same repository owner, and is also marked setuid. Consequently when a user pushes into a repository the effective uid is that of the repository owner, objects can be written, refs can be changed, the update hook runs setuid, and it enforces everything.

The problem now is what happens when users try to use Git as a distributed tool and push changes between their own two repositories? Even if the two specific users can agree on using --shared (because maybe they actually read the Git manual and want to use that feature), git-receive-pack runs setuid as the blessed repository user. Any update hook installed within one of these 'user private' repositories is untrusted, but will be running with enough permissions to run /bin/rm and destroy data. See above about how I can't have that...

So I've patched git-receive-pack to refuse to run if its running setuid and the hook's owner isn't the effective uid, or the hook is group/world writable. This seems to close the last hole, but it also makes hooks/update and hooks/post-update useless in user private repositories on this system.

I'm sending this to try and solicit better ideas from the mailing list. We have a lot of UNIX guru types, and a lot of Git guru types, and they are all smarter than I... ;-)

Next: Martin Waitz
Message 1 of 8 in “Locked down (but still shared) repositories”
  1. Shawn PearceDec 7, 2006
  2. Martin WaitzDec 7, 2006
  3. Johannes SchindelinDec 7, 2006
  4. Shawn PearceDec 7, 2006
  5. Rogan DawesDec 7, 2006
  6. Shawn PearceDec 7, 2006
  7. Randal L. SchwartzDec 7, 2006
  8. Rogan DawesDec 7, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.