From: Sam Vilain <sam@vilain.net>
To: "Shawn O. Pearce" <spearce@spearce.org>
Cc: Pierre Habouzit <madcoder@debian.org>, git@vger.kernel.org
Subject: Re: [RFC] Authenticate push via PGP signature, not SSH
Date: Wed, 30 Jan 2008 19:29:55 +1300 [thread overview]
Message-ID: <47A01963.1030703@vilain.net> (raw)
In-Reply-To: <20080129041000.GK24004@spearce.org>
Shawn O. Pearce wrote:
> * New protocol extension to send-pack/receive-pack pair:
>
> If server wants to require (or optionally) accept a signed push
> event it sends a new capability string when it advertises its
> current known heads:
>
> auth-1=[0-9a-f]{40}
[...]
> <auth><pgp_sig>
>
> auth ::= 'auth' ' ' <name> ' ' '<' <email> '>' '\n'
> name ::= like a commit author-name
> email ::= like a commit author-email
> pgp_sig ::= armored signature from PGP
>
> receive-pack expects this new auth pkt-line if the client asked
> to enable the auth-1 capablity in the first command.
>
> If receive-pack was configured (say by config receive.auth)
> to require authentication then it closes the connection if the
> client didn't request the capablity in the first command.
>
> receive-pack can generate the same SHA-1 hash from the commands
> it read from send-pack, and can verify the PGP signature on the
> auth line.
>
> This assures us the command stream wasn't modified, and likely
> originated from the named identity. The rest of the packfile
> data is already well protected by its own SHA-1 footer and the
> individual object SHA-1s, and the roots pointing into that DAG
> (or sub-DAG) mentioned in the commands were verified by the PGP
> signature of them.
Ok - but I think if the client is pushing a signed tag to the tagname
listed in the signed body of the tag, that no extra signature should be
necessary. It's only commits that need the extra information.
And remember, for global replication of the data between untrusted nodes
to be possible, the signatures must be saved somewhere. I have sketched
a simple design below.
> * PGP public key storage:
>
> Use a "hidden" ref called "refs/access-keys" to store a commit.
> The access control change log is a normal Git commit chain.
>
> The tree under this commit stores a file per <email> string.
> Public keys for auth line validation are located by <email>,
> from the tip of this branch.
>
> This branch could be a symlink to another repository (e.g.
> a site-wide "admin" repository) and the ODB for that other
> repository could be an alternate for this repository.
>
>
> * ref/access-keys security:
>
> Probably an update or pre-receive hook could verify pushes
> to this branch by something like this:
>
> - If the only difference between $old_sha1 $new_sha1 is
> a modification of $GIT_PUSHER_EMAIL then allow it
> (user is replacing their own key);
>
> - If the only difference between $old_sha1 $new_sha1 is
> modifications of names other than $GIT_PUSHER_EMAIL but
> the file content differences are only $GIT_PUSHER_EMAIL
> signing those public keys then allow it (the user doing
> the push is publishing some trust);
>
> - If the difference between $old_sha1 $new_sha1 is new
> keys added or existing keys removed then allow it only
> if $GIT_PUSHER_EMAIL is also listed inside of the
> "admin/" subtree and the new key is also signed by
> $GIT_PUSHER_EMAIL's key.
Ok perhaps it is best to wrap all this up in a single state branch, that
has in it:
access-keys/
- tree with one key per e-mail address
access
- maps reference globs to e-mail addresses permitted to change
them - with a "+" if the address may rewind the ref
owners
- maps reference globs to e-mail addresses permitted to add entries
to the "access" map above
signatures/
- stores any detached signatures. only the signatures verifying
updates since the last commit to the access meta-branch need to
be stored
packed-refs
- the new list of references (the refs/access commitid is naturally
absent or the same as the parent), or just the changed
references.
You don't necessarily need a new commit on this for every single push,
just once "every so often", and perhaps for safety once for every change
to the access file.
This branch should then be auditable; replicating tools can go and
verify that there have been no unauthorized changes.
Forks don't necessarily need special treatment; they can exist under
refs/forks/foobar/ - similar to the refs/remotes/ namespace, and have
their own independent ACL branches within.
Allowing "grant" permissions to refspaces would need to be handled
specially; you can't simply grant access to change refs/access; the
actual push to refs/access would need inspecting to see if the changed
"access" file comes within the rights of the user that signed the update.
I think this seems about right for a first cut. Possibly bigger
projects like Debian would like to say that for certain ref spaces,
multiple signatures are required, so that no one PGP key retains
complete control. But I think these things are easily added as features
on top of this basic infrastructure.
Sound like something worth working towards?
Sam.
next prev parent reply other threads:[~2008-01-30 6:30 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-28 4:12 [RFC] Authenticate push via PGP signature, not SSH Sam Vilain
2008-01-28 8:12 ` Shawn O. Pearce
2008-01-28 21:06 ` Jan Hudec
2008-01-28 21:58 ` Sam Vilain
2008-01-29 2:57 ` Shawn O. Pearce
2008-01-29 4:10 ` Shawn O. Pearce
2008-01-29 19:08 ` Pierre Habouzit
2008-01-30 4:22 ` Shawn O. Pearce
2008-01-30 5:55 ` Sam Vilain
2008-01-30 6:16 ` Shawn O. Pearce
2008-01-30 8:35 ` Pierre Habouzit
2008-01-30 20:22 ` Sam Vilain
2008-01-30 8:00 ` Johannes Sixt
2008-01-31 5:43 ` Shawn O. Pearce
2008-01-30 8:33 ` Pierre Habouzit
2008-01-31 4:30 ` Shawn O. Pearce
2008-01-31 9:25 ` Pierre Habouzit
2008-01-30 6:29 ` Sam Vilain [this message]
2008-01-30 7:47 ` Shawn O. Pearce
2008-01-31 1:18 ` Sam Vilain
2008-01-28 8:48 ` Pierre Habouzit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=47A01963.1030703@vilain.net \
--to=sam@vilain.net \
--cc=git@vger.kernel.org \
--cc=madcoder@debian.org \
--cc=spearce@spearce.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).