threads / discuss / 27365

ACLs for GIT

Subject: ACLs for GIT

## tl;dr

15 messages between May 15, 2011 and May 17, 2011.

replies: 14people: 9as markdown or json

Martin L Resnick· May 15, 2011, 19:24 UTC · lore
Is anyone working on adding access control to GIT ?

I'm looking for the Subversion equivalent of mod_authz_svn. I need to restrict read access of ITAR documents that are scattered throughout the source tree. This restriction would need to deny fetch of the ITAR documents yet allow fetch of any other files.

Looking through the source code it would seem that putting a hook call in the fetch-pack code would do it.

Thanks
Magnus Bäck· May 15, 2011, 20:15 UTC · re: Martin L Resnick · lore

Re: ACLs for GIT

On Sunday, May 15, 2011 at 21:24 CEST,
     Martin L Resnick <mresnick@bbn.com> wrote:
Show 10 quoted lines
> Is anyone working on adding access control to GIT ?
>
> I'm looking for the Subversion equivalent of mod_authz_svn.
> I need to restrict read access of ITAR documents that are
> scattered throughout the source tree.
> This restriction would need to deny fetch of the ITAR
> documents yet allow fetch of any other files.
>
> Looking through the source code it would seem that
> putting a hook call in the fetch-pack code would do it.

I doubt it would make sense to put per-file permissions in Git as it doesn't version files but the complete state of a workspace. Even if you manage to hack the pack code to not include certain blobs when certain users ask for them, what would those users do when they want to create new commits based on commits where blobs are missing? Or would you send the protected blobs but replace their contents? Then Git would complain about that.

However, both Gerrit Code Review and Gitolite offer per-branch permissions, so if it would be possible to put these files on branches of their own these tools would help.

-- 
Magnus Bäck                   Opinions are my own and do not necessarily
SW Configuration Manager      represent the ones of my employer, etc.
Sony Ericsson
Martin L Resnick· May 16, 2011, 13:22 UTC · re: Magnus Bäck · lore

Re: ACLs for GIT

Thanks Mangus.

You pointed out some hurdles I'll have to think about (blocked files not matching the SHA and so can't be committed).

As to why I want to do this consider NSA non-export rules. Our application would be built with NSA encryption but we have foreign nationals working on the code and so they are not permitted to see that part. The makefiles look to see if the NSA encryption code file is there and link it in. If not a stub is used.

On 05/15/2011 04:15 PM, Magnus Bäck wrote:
Show 26 quoted lines
> On Sunday, May 15, 2011 at 21:24 CEST,
>       Martin L Resnick<mresnick@bbn.com>  wrote:
>
>> Is anyone working on adding access control to GIT ?
>>
>> I'm looking for the Subversion equivalent of mod_authz_svn.
>> I need to restrict read access of ITAR documents that are
>> scattered throughout the source tree.
>> This restriction would need to deny fetch of the ITAR
>> documents yet allow fetch of any other files.
>>
>> Looking through the source code it would seem that
>> putting a hook call in the fetch-pack code would do it.
>
> I doubt it would make sense to put per-file permissions in Git
> as it doesn't version files but the complete state of a workspace.
> Even if you manage to hack the pack code to not include certain
> blobs when certain users ask for them, what would those users
> do when they want to create new commits based on commits where
> blobs are missing? Or would you send the protected blobs but
> replace their contents? Then Git would complain about that.
>
> However, both Gerrit Code Review and Gitolite offer per-branch
> permissions, so if it would be possible to put these files on
> branches of their own these tools would help.
>
Richard Peterson· May 16, 2011, 15:26 UTC · re: Martin L Resnick · lore

Re: ACLs for GIT

On Mon, May 16, 2011 at 9:22 AM, Martin L Resnick <mresnick@bbn.com> wrote:
Show 11 quoted lines
> Thanks Mangus.
>
> You pointed out some hurdles I'll have to think about
> (blocked files not matching the SHA and so can't be committed).
>
> As to why I want to do this consider NSA non-export rules.
> Our application would be built with NSA encryption
> but we have foreign nationals working on the code
> and so they are not permitted to see that part.
> The makefiles look to see if the NSA encryption code file
> is there and link it in. If not a stub is used.
I bet you could use a submodule.
-Richard
Phil Hord· May 16, 2011, 15:33 UTC · re: Martin L Resnick · lore

Re: ACLs for GIT

On 05/16/2011 09:22 AM, Martin L Resnick wrote:
Show 11 quoted lines
> Thanks Mangus.
>
> You pointed out some hurdles I'll have to think about
> (blocked files not matching the SHA and so can't be committed).
>
> As to why I want to do this consider NSA non-export rules.
> Our application would be built with NSA encryption
> but we have foreign nationals working on the code
> and so they are not permitted to see that part.
> The makefiles look to see if the NSA encryption code file
> is there and link it in. If not a stub is used.

We use submodules for this same need here. If the submodule is loaded, the code is used from that. If not, pre-built binaries are used instead. These could be stubs.

When we share code with outside partners, we give them access only to the modules they need.

We further guard the code in the submodule by PGP-encrypting the source files and storing them in the repository (as binaries). This practice lets us be more free with the repository and not worry so much that it may be cloned well out of our control. Storing code as shrouded binaries negates much of git's power, but only for this one submodule. Our other submodules are still quite git-friendly.

Phil
Martin L Resnick· May 16, 2011, 15:36 UTC · re: Phil Hord · lore

Re: ACLs for GIT

Wonderful. Thanks a lot.
That's a great idea to use submodules WITH encrypting the source.
I like it! I'm going to propose we use it.
Thanks for the suggestion.
On 05/16/2011 11:33 AM, Phil Hord wrote:
Show 30 quoted lines
> On 05/16/2011 09:22 AM, Martin L Resnick wrote:
>> Thanks Mangus.
>>
>> You pointed out some hurdles I'll have to think about
>> (blocked files not matching the SHA and so can't be committed).
>>
>> As to why I want to do this consider NSA non-export rules.
>> Our application would be built with NSA encryption
>> but we have foreign nationals working on the code
>> and so they are not permitted to see that part.
>> The makefiles look to see if the NSA encryption code file
>> is there and link it in. If not a stub is used.
>
> We use submodules for this same need here.  If the submodule is loaded,
> the code is used from that.  If not, pre-built binaries are used
> instead.  These could be stubs.
>
> When we share code with outside partners, we give them access only to
> the modules they need.
>
> We further guard the code in the submodule by PGP-encrypting the source
> files and storing them in the repository (as binaries).  This practice
> lets us be more free with the repository and not worry so much that it
> may be cloned well out of our control.  Storing code as shrouded
> binaries negates much of git's power, but only for this one submodule.
> Our other submodules are still quite git-friendly.
>
> Phil
>
>
Jakub Narebski· May 16, 2011, 16:28 UTC · re: Martin L Resnick · lore

Re: ACLs for GIT

Martin L Resnick <mresnick@bbn.com> writes:
Show 36 quoted lines
> On 05/15/2011 04:15 PM, Magnus Bäck wrote:
>> On Sunday, May 15, 2011 at 21:24 CEST,
>>       Martin L Resnick<mresnick@bbn.com>  wrote:
>>
>>> Is anyone working on adding access control to GIT ?
>>>
>>> I'm looking for the Subversion equivalent of mod_authz_svn.
>>> I need to restrict read access of ITAR documents that are
>>> scattered throughout the source tree.
>>> This restriction would need to deny fetch of the ITAR
>>> documents yet allow fetch of any other files.
>>>
>>> Looking through the source code it would seem that
>>> putting a hook call in the fetch-pack code would do it.
>>
>> I doubt it would make sense to put per-file permissions in Git
>> as it doesn't version files but the complete state of a workspace.
>> Even if you manage to hack the pack code to not include certain
>> blobs when certain users ask for them, what would those users
>> do when they want to create new commits based on commits where
>> blobs are missing? Or would you send the protected blobs but
>> replace their contents? Then Git would complain about that.
>>
>> However, both Gerrit Code Review and Gitolite offer per-branch
>> permissions, so if it would be possible to put these files on
>> branches of their own these tools would help.
>
> You pointed out some hurdles I'll have to think about
> (blocked files not matching the SHA and so can't be committed).
> 
> As to why I want to do this consider NSA non-export rules.
> Our application would be built with NSA encryption
> but we have foreign nationals working on the code
> and so they are not permitted to see that part.
> The makefiles look to see if the NSA encryption code file
> is there and link it in. If not a stub is used.

You have to remember that with exception of submodules, which can be fetched or not, all operations between repositories operate on whole tree basis. The commit in Git (i.e. a single revision) always contain _all_ the files in repository (with exception of submodules).

ACL in e.g. Gitolite allow to refuse push if there are changes to specified paths (per-file access control), but it wouldn't and couldn't preent from viewing such "restricted" files.

1. What you can do is manage two unrelated branches (without common
ancestor one orphan to the other), "private" and "public".  You do
public work on branches starting on public branch, and merge both to
public and private, and you do private work on branches starting at
private branch, and merge only to private.  The public publishing
repository (e.g. on GitHub or repo.or.cz) would have only "public"
branch, while private clone (e.g. on intranet, or on private
repository on GitHub) would have both branches.
2. Another solution that could work is to have stubs for "restricted"
files, and in private repository use git-replace mechanism to replace
those stubs with "restricted" contents.  Again in public publishing
repository you woldn't have refs/replace published, while in private
one you would have refs/replace and git would show "restricted"
contents replacing stubs.  NOT TESTED!.
3. As other wrote, you can have yet another solution: use submodules.
You would put "restricted" contents in submodule, and just not make
repository that makes submodule public.  What would be visible would
be only SHA-1 of contents in supermodule.  This assumes that you can
disentanle files into submodules (loose connection)...
-- 
Jakub Narebski
Poland
ShadeHawk on #git
R. Tyler Croy· May 15, 2011, 20:16 UTC · re: Martin L Resnick · lore

Re: ACLs for GIT

On Sun, 15 May 2011, Martin L Resnick wrote:
Show 10 quoted lines
> Is anyone working on adding access control to GIT ?
> 
> I'm looking for the Subversion equivalent of mod_authz_svn.
> I need to restrict read access of ITAR documents that are
> scattered throughout the source tree.
> This restriction would need to deny fetch of the ITAR
> documents yet allow fetch of any other files.
> 
> Looking through the source code it would seem that
> putting a hook call in the fetch-pack code would do it.

It sounds like 'gitolite' might be what you're looking for: <https://github.com/sitaramc/gitolite>

- R. Tyler Croy
--------------------------------------
    Code: http://github.com/rtyler
 Chatter: http://identi.ca/agentdero
          http://twitter.com/agentdero
Martin L Resnick· May 16, 2011, 13:22 UTC · re: R. Tyler Croy · lore

Re: ACLs for GIT

Thanks for the reply.

But gitolite would only work to deny reads on a repository or ref basis not a pathname level.

On 05/15/2011 04:16 PM, R. Tyler Croy wrote:
Show 22 quoted lines
>
> On Sun, 15 May 2011, Martin L Resnick wrote:
>
>> Is anyone working on adding access control to GIT ?
>>
>> I'm looking for the Subversion equivalent of mod_authz_svn.
>> I need to restrict read access of ITAR documents that are
>> scattered throughout the source tree.
>> This restriction would need to deny fetch of the ITAR
>> documents yet allow fetch of any other files.
>>
>> Looking through the source code it would seem that
>> putting a hook call in the fetch-pack code would do it.
>
> It sounds like 'gitolite' might be what you're looking for:
> <https://github.com/sitaramc/gitolite>
>
> - R. Tyler Croy
> --------------------------------------
>      Code: http://github.com/rtyler
>   Chatter: http://identi.ca/agentdero
>            http://twitter.com/agentdero
Sitaram Chamarty· May 17, 2011, 01:32 UTC · re: Martin L Resnick · lore

Re: ACLs for GIT

On Mon, May 16, 2011 at 6:52 PM, Martin L Resnick <mresnick@bbn.com> wrote:
> Thanks for the reply.
>
> But gitolite would only work to deny reads on a repository or ref basis
> not a pathname level.

I notice the original question has been answered, so this email is just for the record.

Gitolite does not do any access control on *read* access (fetch, clone). It can only do that on *write*s (push).

Gerrit does that because they've reimplemented git itself and have coded that into their git engine somehow. I believe they had to implement a callback from jgit to gerrit for the fetch, and deal with evil clients that might try to read an object by pushing a supposed change on top of a SHA that they know but don't actually have. (Or something like that; I'm not real clear on this...).

regards
sitaram
PS: Gitolite does have unreleased code to do this but it's a hack with
several limitations.  Gitolite makes a temp "clone -l", deletes all
refs from it that the user has no access to, then redirects the
git-upload-pack to that repo instead ;-)
Shawn Pearce· May 17, 2011, 01:49 UTC · re: Sitaram Chamarty · lore

Re: ACLs for GIT

On Mon, May 16, 2011 at 18:32, Sitaram Chamarty <sitaramc@gmail.com> wrote:
Show 15 quoted lines
> On Mon, May 16, 2011 at 6:52 PM, Martin L Resnick <mresnick@bbn.com> wrote:
>> Thanks for the reply.
>>
>> But gitolite would only work to deny reads on a repository or ref basis
>> not a pathname level.
>
> I notice the original question has been answered, so this email is
> just for the record.
>
> Gitolite does not do any access control on *read* access (fetch,
> clone).  It can only do that on *write*s (push).
>
> Gerrit does that because they've reimplemented git itself and have
> coded that into their git engine somehow.  I believe they had to
> implement a callback from jgit to gerrit for the fetch,
Yes, we do.
> and deal with
> evil clients that might try to read an object by pushing a supposed
> change on top of a SHA that they know but don't actually have. (Or
> something like that; I'm not real clear on this...).

Yes, we also have protections for this. Users cannot push objects that reference objects they are not allowed to read. This check needs to be done for delta bases as well as commit tree/parent pointers, and tree entries. Its not difficult, but its not as simple as just limiting the branch names shown to upload-pack.

> PS: Gitolite does have unreleased code to do this but it's a hack with
> several limitations.  Gitolite makes a temp "clone -l", deletes all
> refs from it that the user has no access to, then redirects the
> git-upload-pack to that repo instead ;-)

Cute hack. Doesn't prevent the evil client from making an indirect reference to something you shouldn't have. :-)

-- 
Shawn.
Sitaram Chamarty· May 17, 2011, 12:08 UTC · re: Shawn Pearce · lore

Re: ACLs for GIT

On Tue, May 17, 2011 at 7:19 AM, Shawn Pearce <spearce@spearce.org> wrote:
> On Mon, May 16, 2011 at 18:32, Sitaram Chamarty <sitaramc@gmail.com> wrote:
Show 7 quoted lines
>> PS: Gitolite does have unreleased code to do this but it's a hack with
>> several limitations.  Gitolite makes a temp "clone -l", deletes all
>> refs from it that the user has no access to, then redirects the
>> git-upload-pack to that repo instead ;-)
>
> Cute hack. Doesn't prevent the evil client from making an indirect
> reference to something you shouldn't have. :-)

You mean he constructs a commit that references a SHA he should not be having, pushes that to the branch he is allowed to read/write, then pulls it down again to now really get that commit?

Yeah, I started writing a hook that looks at `rev-list oldsha..newsha`, and for each commit run `git branch --contains SHA` and make sure it either (a) is totally new to the repo, ie no ref contains this commit or (b) at least one of the refs that contains this commit is allowed for this user.

I haven't had time to do that though. Also, if there has been a rewind/force-push and the attacker knows the now unreachable SHA, this would not catch it (it'd look like a totally new commit). That's a hard one.

Having two repos is still the best plan ;-)
Shawn Pearce· May 17, 2011, 14:06 UTC · re: Sitaram Chamarty · lore

Re: ACLs for GIT

On Tue, May 17, 2011 at 05:08, Sitaram Chamarty <sitaramc@gmail.com> wrote:
Show 14 quoted lines
> On Tue, May 17, 2011 at 7:19 AM, Shawn Pearce <spearce@spearce.org> wrote:
>> On Mon, May 16, 2011 at 18:32, Sitaram Chamarty <sitaramc@gmail.com> wrote:
>
>>> PS: Gitolite does have unreleased code to do this but it's a hack with
>>> several limitations.  Gitolite makes a temp "clone -l", deletes all
>>> refs from it that the user has no access to, then redirects the
>>> git-upload-pack to that repo instead ;-)
>>
>> Cute hack. Doesn't prevent the evil client from making an indirect
>> reference to something you shouldn't have. :-)
>
> You mean he constructs a commit that references a SHA he should not be
> having, pushes that to the branch he is allowed to read/write, then
> pulls it down again to now really get that commit?

Yes. Or, he has a SHA-1 he suspects is a tree or blob and lists that in a tree he pushes to a branch he can write to. Now he can fetch that branch back, and obtain that object whose SHA-1 he has but whose contents he does not have.

There is another attack that is incredibly improbable, but that JGit tries to protect against here as well. An evil user could try to push an object that uses the REF_DELTA format and specifies a SHA-1 base that he wants to see at least some of the content of. The delta copy instructions copy some of the base, and then insert content the attacker knows. In theory the attacker cannot predict the SHA-1 of the resulting object and thus cannot reference it in a tree or commit in order to make a link and fetch it back. However if there is a weakness in SHA-1 that has not been discovered yet an attacker may be able to craft the text he knows and supplied as delta insert commands in such a way that the text of the object he is trying to copy has little to no impact on the resulting SHA-1. Now he can predict the SHA-1 this delta creates, and if he can make a link to it, he can fetch it back and acquire at least part of the remote object. Its paranoid to check the REF_DELTA bases for visibility before applying the delta, but we do it in JGit because its better to be slightly paranoid than to assume this theoretical attack is too improbable to succeed. (And it is given what we know about SHA-1 today.)

Show 5 quoted lines
> Yeah, I started writing a hook that looks at `rev-list
> oldsha..newsha`, and for each commit run `git branch --contains SHA`
> and make sure it either (a) is totally new to the repo, ie no ref
> contains this commit or (b) at least one of the refs that contains
> this commit is allowed for this user.
Yea, that isn't sufficient because of the tree/blob link issue. (See above.)
> I haven't had time to do that though.  Also, if there has been a
> rewind/force-push and the attacker knows the now unreachable SHA, this
> would not catch it (it'd look like a totally new commit).  That's a
> hard one.

Yes. This the branch --contains test is insufficient because you need to verify the "new" object actually was transmitted by the client in this exchange, and wasn't just already present on disk. This is hard because in C Git unpack-objects will not write the object if the object already exists, and then there is no list of objects the client sent. Again this is another area where JGit is paranoid. It keeps track of every object actually sent by the user. The only "new" objects permitted are those that were sent by the user, any other "new" objects are attempts to access something the client shouldn't have access to, or is a broken pack file created by a broken client (i.e. it did not send all objects it should have sent).

> Having two repos is still the best plan ;-)

Yes, but tell that to Gerrit Code Review users. They really use the branch ACL features. :-)

-- 
Shawn.
Sitaram Chamarty· May 17, 2011, 15:41 UTC · re: Shawn Pearce · lore

Re: ACLs for GIT

On Tue, May 17, 2011 at 7:36 PM, Shawn Pearce <spearce@spearce.org> wrote:
> On Tue, May 17, 2011 at 05:08, Sitaram Chamarty <sitaramc@gmail.com> wrote:
> Yes. Or, he has a SHA-1 he suspects is a tree or blob and lists that
> in a tree he pushes to a branch he can write to. Now he can fetch that
> branch back, and obtain that object whose SHA-1 he has but whose
> contents he does not have.
Good point.  Not too hard too I guess, unlike this one:
> There is another attack that is incredibly improbable, but that JGit
[snipped lots of complicated stuff]
> assume this theoretical attack is too improbable to succeed. (And it
> is given what we know about SHA-1 today.)

IMO most of the theoretical attacks are just that. They advance the state of the art but I've not heard of any of them actually being used in a real life scenario. The sad fact is there are much weaker links to be found if you look around and you don't need all this.

>> Having two repos is still the best plan ;-)
>
> Yes, but tell that to Gerrit Code Review users. They really use the
> branch ACL features. :-)

Interesting. I do a fair amount of git consulting and training (inhouse) and this has only come up once so far. I haven't seen it as being that common at all.

Marc Weber· May 15, 2011, 20:28 UTC · re: Martin L Resnick · lore

Re: ACLs for GIT

Excerpts from Martin L Resnick's message of Sun May 15 21:24:38 +0200 2011:
> Is anyone working on adding access control to GIT ?

I don't know git internals very well. But my very basic understanding is that each commit hash is based on *all* file contents and path names and its history.

If you drop some paths (eg by denying access) there is no way to verify or recalculate the hashes ?

So even if you can deny access to some path I'd expect the result to be unusable because all kinds of tools such as gitk will start telling you about missing paths.

Alternative ideas:
- github supports SVN access to git repos. Maybe you can ask them to
  provide what you're looking for?
- clone the repo and strip off the files. Then allow access to those
  cloned striped repos only.

I don't think there is a simple solution to your request. But others may know better than I do.

Marc Weber

← back to recent threads