Path-Based Authorization in SVN
What exactly *is* path-based authorization, anyway? In short, its a way to restrict who can see or change the content in SVN based on the location of the content inside the SVN repository. It uses a set of rules (stored in a text file), and those rules are applied every time a read or write operation is made against the repository.
I'll illustrate by way of an example. Here is what my repository looks like on disk:
/svn
/repos <--REPOSITORY #1
/repos2
/ecit <--REPOSITORY #2
/repos_ast <--REPOSITORY #3
/repos3 <--REPOSITORY #4
Each of the repositories contains all the directories used by SVN[^1]. But the /repos2
folder isn't a repository itself. Instead, it contains 2 separate repositories: /ecit
and /repos_ast
. Those were copied to this machine by a previous administrator and I don't want to modify them.
Unfortunately, I cant expose the root directory (/svn
) because it isn't a repository. Instead, I need to expose each of the main repositories: /repos
, /ecit
, /repos_ast
, and /repos3
. Luckily, there is some magic I can do with the /repos2
folder to simplify things.
The setup for this arrangement has two parts
- telling Apache what URI to associate with each repository, and preparing it to use SVN, and
- setting up the proper SVN authorizations so that people have access to the repositories and projects they need
Apache Configuration
The Apache configuration is really what holds the system together. It brings the authentications system (i.e. the Windows domain) together with its own authorization system (a config file) to determine who gets access to what. It sounds complicated, but its not. I'll explain each repository's configuration separately.
Repository #1
The first repository (/repos
) is fairly straightforward. Here is an excerpt from the Apache httpd.conf
file. The SVNPath
line declares the disk location of the repository, and the AuthzSVNAccessFile line declares where the authorization rules are stored.
<Location /svn/repos>
DAV svn
SVNPath C:\svn\repos
AuthName "SVN Server"
AuthType SSPI
SSPIAuth On
SSPIAuthoritative On
SSPIDomain NA
SSPIOfferBasic On
SSPIBasicPreferred On
Require valid-user
AuthzSVNAccessFile C:\svn\svnaccess.conf
</Location>
Here is the relevant section from my svnaccess.conf
file:
[groups]
team1 = na\cfreyer, na\rsmith, .....
team2 = na\joe, na\bill, ...
admins = na\cfreyer, ...
[/]
@admins = rw
@team1 = r
@team2 = r
[/Project1]
@team1 = rw
@team2 = r
[/Project2]
@team2 = rw
[/SecretProject]
na\cfreyer = rw
You can see that the people are grouped by team into. admins
group has read-write access to the entire repository (for creating new project directories), but other uses have read-only access. In Project1
, team1 can write to the project but team2 can only read. In Project2
, only team2 can see it, and they can also write. And in SecretProject
, only one person can read or write to it. This is a very flexible arrangement.
Repository #2
Repository #2 (the directory on disk) contains 2 SVN repositories: ecit
and repos_ast
. I decided to manage these two together (meaning they share a single authorization file). The Apache setup is almost the same as for repository one. Notice that I specified a different location for the AuthzSVNAccessFile
though.
<Location /svn/repos2>
DAV svn
SVNParentPath C:\svn\repos2
AuthName "SVN Repos 2"
AuthType SSPI
SSPIAuth On
SSPIAuthoritative On
SSPIDomain NA
SSPIOfferBasic on
SSPIBasicPreferred On
Require valid-user
AuthzSVNAccessFile C:\svn\repos2\svnaccess.conf
</Location>
That forces users to access the repository with a /repos2
prefix, so they know they are in a different repository just by looking at the SVN URL. Here is a section of the AuthzSVNAccessFile
:
[groups]
...similar definitions as above...
[ecit:/MyProject]
@myteam = rw
[repos_ast:/OtherProject]
@otherteam = rw
You can see that each location is prefixed with the name of the repository and a colon (i.e. ecit:
or repos_ast:
). The user won't type the repository name when they access the SVN repository. Instead, the URL will be something likehttp://hostname/repos2/MyProject
. This is simple and easy to follow for the user, and it hides the fact that the projects are actually stored in different repositories.
Technically, I could have done all my repositories with this kind of setup. The only drawback is that I have to ensure that projects in the different repositories aren't named the same. I can't have "ecit:/MyProject" and a repos_ast:/MyProject
. One of them would be hidden. If this situation is likely for you, then don't combine your repositories like I did.
Repository #3
<Location /svn/repos3>
DAV svn
SVNPath C:\svn\repos3
AuthName "SVN Repos 3"
AuthType SSPI
SSPIAuth On
SSPIAuthoritative On
SSPIDomain NA
SSPIOfferBasic On
SSPIBasicPreferred On
Require valid-user
AuthzSVNAccessFile C:\svn\svnaccess.conf
</Location>
[^1] it contains the /conf
, /dav
, /db
, /hooks
, and /locks
folders