Speed up Git access checks
When a user performs git operations like fetches or pushes, we need to determine whether the user is who he claims to be (authentication) and, if so, whether the user is allowed to perform the operation (authorization). The flow for an (SSH) push typically looks like the following:
1. gitlab-shell accepts the SSH connection and checks whether the user is who he claims to be by doing a POST to Rails' `/allowed` endpoint. This also verifies whether the user is allowed to push at all. If this is successful, it invokes Gitaly's SSHReceivePack endpoint.
2. Gitaly receives all reference updates and new objects. It then executes the pre-receive hook, which does another POST to Rails' `/allowed` endpoint including all references which are about to change.
3. Rails now performs several checks to determine whether the push is allowed, including:
- whether the user is allowed to modify these references in the first place
- whether there are non-fast-forward reference updates and whether they're allowed
- whether pushed objects conform to limits, e.g. no blob is bigger than a given threshold
- LFS pointer checks to verify consistency
- and more
This architecture is slow because checks are done by Rails, where Rails has to perform dozens of RPCs to Gitaly to inspect pushed references and objects. Given that this is unobservable for the user, this can be frustratingly slow because the push is seemingly just hanging without any output.
To improve the situation, it would be beneficial to move git-specific access checks into Gitaly.
# Exit Criteria
- [ ] Working implementation of checks for rewrite in production
- [ ] Git operations like fetches, pushes are faster meaning more responsive to the customer
epic