Authentication for networked Gitaly

Off-shoot from #74 (closed).

Edit: I have pushed a new commit and updated the description of this issue. The scheme is simpler now. What I am proposing is standard TLS with client certificates, plus one trick that allows you to collapse everything onto one self-signed certificate while maintaining peer verification.

We have a proof of concept in d76f0619

It is based on TLS with client certificates because that is the only native authentication scheme in gRPC that makes sense for a backend service. (The other option is oauth, which is not a good fit because Gitaly does not know what a user is.)

Instead of full-blown web-style PKI, this proof of concept simplifies TLS to a point where it is comparable with password access to Postgres. We are using a self-signed certificate with peer verification enabled.

  • the administrator generates a single self-signed key pair: key 'K' and certificate 'C' with subject CN=gitaly
  • the gitaly clients use a custom CA pool to verify the gitaly server. Certificate 'C' is in this pool
  • the gitaly servers us a custom CA pool to verify the clients. Certificate 'C' is in this pool
  • the gitaly client identifies itself with K+C
  • the gitaly server identifies itself with K+C
  • the client overrides its TLS settings to expect server name CN=gitaly
  • client config settings: client key, client certificate, list of server CA's, global server name override
  • server config settings: server key, server certificate, list of client CA's

Because the client overrides the server name we can use normal peer verification. A single self-signed certificate can be deployed across the entire cluster. Because we use CA pools, it is possible to roll out new certificates without invalidating the old ones.

What this shows is that we can use standard TLS primitives (server/client certificates, server/client CA pools) and make it work with just one self-signed certificate across a fleet just by adding a 'server name' option on the client side. People who want to use proper TLS+PKI (with DNS etc.) can do so in this scheme (just don't use the server name override); people who do not want to or cannot can use a self-signed certificate and still get reasonable security and convenience.

The proof-of-concept contains a 1-line openssl command that generates the self-signed certificate.

(Caveat: I got this working with Go Gitaly clients but not yet in Ruby)

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information