Create a blueprint on plugin interface in Gitaly
Gitaly is hard coded to call into Rails for access checks. Rails then performs multiple calls back to Gitaly to perform various checks. This has various downsides:
- This is inefficient, as this lead would lead to sending all blobs to Rails for features like secret detection.
- It's a complex flow, with Rails calling into Gitaly, Gitaly calling into Rails and Rails again calling into Gitaly.
- It leaks internal details by requiring us to expose quarantine directories in the API, and providing force-route-to-primary functionality as the quarantine is only available on the primary.
This could be improved by moving to a general plugin interface:
- The plugin would be a binary that Gitaly invokes
- before committing a transaction
- after committing a transaction
- The plugin interface replaces custom repository hooks, and global server-side hooks.
- This allows us to simplify, and focus on a single extension point.
- The plugin interface should allow for doing the same tasks as currently can be achieved with the custom hooks.
- reject transactions prior to committing them
- (maybe drop reference updates as in
update
hook if needed)
- The interface is defined by us, and not dictated by Git's hooks.
- Allows us to cover all write types Gitaly supports, such as repository creations, and not just reference updates as the current hooks.
With the above:
- We can remove the
internal/allowed
calls from Gitaly and custom hooks, and replace both with just the plugin interface.- Initial migration could be to just extract the current
internal/allowed
calling logic from Gitaly into an initial plugin, and start migrating checks there later where it makes sense.
- Initial migration could be to just extract the current
- The above would allow implementing Rails' access checks in the plugin, and run them locally on the Gitaly node.
- No need to send blobs anywhere, or run multitude of loopback RPCs.
- Implementation is entirely up to the team who needs to run logic in the plugin.
- Call into an RPC server vs run the logic in the plugin, language, and so on.
As part of the design, we should consider removing the GitLab specific fields from the Repository
message, and provide a more general interface where the client could send context that gets passed down to the plugin. This could be used to send for example the project's ID, but also policy details such as whether a certain check should run.
Related: &11587 (comment 1589417960)
Edited by Sami Hiltunen