Webtatic.com

Just another technical blog

Locked down authoritative versioned code repositories

Posted 12th September 2009 by Andy | No Comments

Centralised versioning systems are inherently authoritative, but when dealing with decentralised systems, either patches are made and applied to the maintainer’s repository, or one repository should be defined as the authoritative one.

If the authoritative repository requires commit access, it should be locked down as much as possible, requiring authentication, encryption, and push access without opening up raw file write access. If raw file write access is given, either intentionally or unintentionally, any user with access could corrupt or delete the repository.

Here are the protocols and methods used by Subversion(svn), Git and Mercurial(hg) along with their capabilities:

name authentication encryption push raw file write
svnserve Y N Y N
git-daemon N N Y1 N
hg serve N N Y1 N
svn+ssh Y5 Y Y1 Y2
git ssh Y5 Y Y Y2
hg ssh Y5 Y Y Y2
mod_dav_svn4 Y Y Y N
git over httpd4 Y Y Y3 Y3
hgweb4 Y Y Y N
  1. disabled by default
  2. the login shell can be changed to a shell wrapper to allow only api commands e.g. git-shell
  3. with mod_dav file provider
  4. with a mod_auth_* module, and mod_ssl
  5. achieved by file ownership and permissions

Git clone of a Subversion repository

An alternative, if you require git access, is to have a locked down Subversion repository cloned to a read-only git repository, with a svn post-commit hook running git svn fetch on the git repository.

Clone the Subversion repository via its publicly accessible url:

git svn clone -s https://example.com/svnrepo/ .

Create /path/to/svnrepo/hooks/post-commit with content:

#!/bin/sh
git --git-dir=/path/to/gitrepo/.git svn fetch

The suggested way (in “man git-svn”) of then cloning the git repository and initialising the svn metadata is a bit complicated, but you could instead rsync the git repository and use that instead, otherwise:

git init
git remote add origin url/to/gitrepo
git config --add remote.origin.fetch '+refs/remotes/*:refs/remotes/*'
git fetch
git checkout -b master FETCH_HEAD
git svn init -s https://example.com/svnrepo/
git svn rebase

Conclusion

The capabilities needed by a locked down repository (authentication, encryption, no raw file write access), mean that several methods aren’t viable, and only two with push capabilities (mod_dav_svn, and hgweb). The ssh methods can, as mentioned, be limited to api access only using wrappers, but require local users and those users can’t be used for regular activities, so if your users have ssh access as well, they’ll need two accounts

Public repositories can forgoe these capabilities, so any of these are suitable if anonymous read-only access is required.

Related Posts

Leave a Reply