/fugit

_Really_ lightweight git access control

Primary LanguageShell

Rudimentary (as in, really not that advanced) git access control using SSH key
magic and plain text files. If you want more features, use gitolite or
something along those lines. Found a bug? Report it - or even better, fix it
and send a pull request!

Configuring fugit requires experience with configuring ssh, key-based logins,
git and, should something break, bash. It might contain some vulnerabilities
I have not yet found, so check the code for yourself. Still, you probably
should only give SSH access to people you trust in any case.

Setup
-----
Set up a system user.
Clone this repo into the home of the new user and copy fugit to ~/sbin/fugit.
Make sure ~/sbin/fugit is executable.
If you like, change the log destination from the default (fugit.log) on line 4
You can also change the config directory from the default ($HOME/fugit.d/) on
line 6.

Add the keys used to identify users to ~/.ssh/authorized_keys and add a forced
command executing "~/sbin/fugit <user identifier>" (see the demo file in the
repo for an example).

You might also want to add some or all of
	no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-user-rc
to the key options. Alternatively,
	restrict
includes all of the above.

fugit allows you to choose between two methods of access control: 
file-based (default) and directory-based. To select directory-based access 
control, edit the CONF variable (line 7) to point to a directory.


The access control methods have the following structure

File-based:
	Edit the configuration file (default: fugit.conf) to contain exactly 4
	lines of text per repository to be served.
	Those should be, exactly in this order
		REPO <repo-identifier>	//Identifies the remote
		REAL=<path>		//Path to the repo on disk
		PUSH="<list of users>"	//Users allowed to push to the repo
		PULL="<list of users>"	//Users allowed to pull from the repo

Directory-based:
	The configuration for a repository is read from a file, the name of
	which is determined by replacing all forward slashes ('/') in the 
	submitted repo-identifier with underscores, appending ".conf" and
	prepending the CONF variable.

	Example:
		CONF is "fugit.d"

		$ git clone ssh://host/repo/identifier
		=> Repo identifier is "repo/identifier"
		=> Config file is "fugit.d/repo_identifier.conf"

	Config files for repositories should contain these 3 lines
	REAL=<path>			//Path to the repo on disk
	PUSH=<path>			//Path to a users file
	PULL=<path>			//Path to a users file

	The referenced 'users' files should contain one user-identifier
	per line, to be granted the respective permission.

Debugging
---------
First, check the log. It should contain all commands processed by fugit.
In order to see very verbose debug information at run time, uncomment the
	set -x
line in the beginning of the file. You will now be spammed with execution
data upon interacting with repos controlled by fugit.

How it works
------------
git's submodules exchange data via stdin/stdout over ssh. fugit inserts itself
into that channel, distinguishes between push and pull operations and
either allows the channel to continue or simply closes it. It's not exactly
rocket science, but it works.

Why
---
Because I need to restrict git access for one system user serving multiple
key-users to specific repositories without fine-grained control. So, really
only push/pull/nothing. I reviewed some of the existing options and found them
all pretty heavy on instructions, prerequisites and implementation complexity.
So I made my own.