Developing Programmers .com

Local Search:



This site is optimized for standards so you can use any standards compliant browser:

Valid XHTML 1.0 Transitional
Valid CSS!
(RSS) RSS Feed

Web Search:
Google


Wednesday, 13 August, 2008

Subversion ACL Permissions Explained  

I recently did some digging in the Subversion source code to find out answers to precedence questions that remained after re-reading the documentation for Subversion’s per-directory permission files (popularly referred to as ACLs). At work, this helped us a lot with ensuring our new graphical UI for permissions (an excellent tool developed by Mark George) would exactly match the meanings of these files. In this article I’ll provide a short summary of the docs to catch people up, and then explain what I had to find by digging.

Subversion has a “per directory access control” file format, used by mod_authz_svn. It is documented in full here, so I’ll just give crash-course coverage to refresh a few memories.

Basically it’s an “ini” format file, where the sections specify paths and the data within each section specify which users or groups have what access to that path. For example:

[/]
*=

[repos1:/trunk]
@developers = rw
sarah = r
*=

[repos2: /branches/foo]
@reviewers = rw
@developers=r
*=

This starts by saying the root directory in all repositories is off limits to everyone. It’s a simple blanket rule to cover whatever we don’t spell out in further rules. The next section says that for repository 1, the developers group has read & write access to /trunk, sarah has read access, and anyone else has no access. Finally, in repository 2, only reviewers can write to /branches/foo, but developers can look in to see if their code was cleaned up or to merge changes back.

Now for what this article is really about: The ambiguities inherent in this format. For the most part, ambiguities are easily avoided. Especially if you read the highlighted note in the documentation:

The thing to remember is that the most specific path always matches first. The server tries to match the path itself, and then the parent of the path, then the parent of that, and so on. The net effect is that mentioning a specific path in the access file will always override any permissions inherited from parent directories.

OK; this tells us that permissions given in [/foo/bar] can be taken away again in [/foo/bar/restricted]. But what if the permission is in [repos1:/foo/bar] and the other just in [/foo/bar]? And, what if a user is effectively (via groups) or explicitly (by name) mentioned twice in the same path section, or if there is no “*” rule? The documentation leaves enough said that you can avoid these ambiguities, but when the going gets tough or when you’re writing an interpreter to match Subversion’s reading of this file, more detail is needed.

This chart, which I came up with for my work at cvsdude, covers these edge cases:

Access Control Diagram

(Image Copyright 2008 CVSDude; used with permission)

As you can see, Subversion starts by finding the most specific config section that mentions the user in question or the anonymous user.more-specific paths coming first does extend to [repos:/foo] coming before [/foo]. However, [/foo/bar] trumps [repos:/foo] because its first priority is longest matching path. And of course a more-specific section is only relevant if it includes the user, a group they’re in, or has a *= clause.

Once the right section is found, subversion then checks what permissions are granted to the user by this section. The result is an OR of permissions granted by each line; so if the user is in two groups, and one group is given R (read) permission in the relevant section, and the other given no permission, the user ends up with read permission.

Posted by sarah at 10:23 am in: Documentation , Tools (12220 views)

0 Comments

Please use the DP Forums for further discussion of this topic.