Push Certificates: Privacy Concerns Regarding the "pushee" Header
From: Lorenz Leutgeb <hidden>
Date: 2026-02-15 21:58:45
Dear recipients, I am working on an application built on top of Git, which wants to ingest push certificates in order to keep (something similar to) a transparency log (see <https://people.kernel.org/monsieuricon/signed-git-pushes>). For reasons that I will only go into detail upon request, in the context of the application, logical "pushes to the network" are split into two parts: The *first part* is always local (from one repository in one directory on the filesystem, to another). Bundled with the application is a daemon. The daemon process then takes over the *second part* of the push, for further propagation of over the network in a peer-to-peer manner. However, one desires the *first* part already to be certified. This would result in push certificates of the following form (hashes abbreviated, signature omitted): certificate version 0.1 pusher SHA256:xX6bp…T0 1771188983 +0100 pushee /home/lorenz/.example/storage/foo nonce 1771188983-345389c 0000000 ccae4e0 refs/heads/main As you can see, this push certificate leaks a path on the application users' filesystem. Here it is quite obviously my home directory, but actually the "storage path", is user-configurable at the application level, and considered private. I do realize that the leak is in part due to the weird application architecture. Who would have guessed that I want to certify a push *on my own filesystem*? I am convinced the main motivation for this feature were pushes (directly) over the network. However, I also believe that it could be of more general interest to allow the Git user to control which/whether the pushee header is emitted. Handling of the pushee header was introduced to `send-pack.c` in 9be89160e7382a88e56a02bcf38f4694dd6542d6, over 11 years ago, and was not touched since. Remarking on the current implementation, I do realize that `transport_anonymize_url` is used to sanitize, in order not to leak usernames, passwords, etc., which is appreciated. However, file paths are not removed. This makes a great deal of sense as the same function is used in other places where indeed the path on the filesystem is expected. I think the current implementation is sensible. However, allowing the Git user to ultimately control which URL is used allows for the greatest flexibility. Note that the receiving end might inspect the push certificate in their `pre-receive` handler, and reject to receive if the pushee is malformed. I would like to provide a patch that adds an option `git send-pack`, which allows the Git user to specify the pushee or indicate that the header should not be emitted. My proposal is as follows. Because of the connection to signed pushes, and therefore to the the already existing `--[no-]-signed=…` option, I would add `--signed-pushee=<string>` as well as `--no-signed-pushee`. One edge case that I would like to get clarification on is how the empty string should be handled. I would consider `--signed-pushee=""` invalid, making it impossible to specify the empty string as pushee, erroring out and potentially hinting at `--no-signed-pushee`. Before I do so, I would like to ask for your feedback. Would you accept such patch if implemented cleanly? What do you think, how should the option be named and interpreted? Further, if this option is added to `git send-pack`, one natural question is whether `git push` should also "inherit" it, as is the case with `--signed`? Kind regards, Lorenz Leutgeb