note: on git encryption

This commit is contained in:
Dmitry Zuikov 2023-10-08 05:20:41 +03:00
parent ff9e82b8b6
commit c913518e6b
2 changed files with 108 additions and 0 deletions

View File

@ -0,0 +1,84 @@
NOTE: historial-group-keys-problem
Сделать групповое шифрование репозиториев с добавлением
новых авторов оказалось не так-то просто.
В силу текущей структуры рефлога репозитория, нам нужны
вообще все транзакции. Соответственно, новый участник
должен получить доступ к ним всем. А "старые" транзакции
ничего не знают про нового участника, они иммутабельны.
Можно, конечно, при добавлении нового автора генерировать
новый журнал со всеми объектами гита, но это очень накладно
получается для больших репо и нарушает наш принцип
"тебе надо --- ты и суетись", т.е максимально возможное
перекладывание нагрузки на клиента.
После непродолжительных дебатов (с чатом гпт, с кем еще-то
поговорить в четыре утра по Москве), пришли к следующему
дизайну:
1. Вводятся новые типы транзакций "метаданные", или, возможно,
"keyinfo".
2. Эта транзакция содержит (ссылку на блоб, где) множество
записей вида (GK0, GKi), где GK0 - это исходный групповой
ключ, которым зашифрован журнал (и ссылку на который он
содержит в своих метаданных)
3. При импорте мы сканируем все необработанные транзы и
для каждой типа keyinfo -> добавляем отношение (GK0, GKi)
куда-то к себе в таблицу. GKi -> это групповой ключ из
одного элемента, секрет, зашифрованный известным читателю
публичным ключом.
Далее сканируем все транзы типа "git log" и если она зашифрована,
то там указан GK0 (может каждый раз новый, может, каждый десятый
раз новый, неважно). Для этого GK0 мы ищем соответствующий ему
GKi.
Наверное, кстати, этот самый GKi лучше бы не ссылкой, а прямо
сюда его указывать как значение --- тогда эти ключи GKi не будут
собраны случайно сборщиком мусора. Это даёт нам больший рост
метанных, да и ладно. Проекты, где сотни участников делать
секретными в плане кода малость туповато, всё кто-то в итоге
окажется крысой или раздолбаем, и сольёт данные. Корпоративный
код сливают, да боже мой, корпорации его хранят в гитхабе зачастую
(ахаха).
Но буде таковые проекты нарисуются -- и размер метаданных станет
составлять проблему --- будем её решать по мере поступления.
4. При экспорте мы:
Если надо -- перегененируем GK0. (он из одного участника,
то есть перегенерируем только, если наш (как автора) публичный
ключ поменялся или reuse говорит (больше reuse шифрований этим
ключом было).
Для каждого читателя генерируем GKi, либо же для всех читателей
генерируем один GKi. Он тоже новый, получается. Заметим,
что секрет из GKi == секрету из GK0.
Постим транзакцию keyinfo c новым блобом (GK0, GKi).
Шифруем журнал "git push" GK0, постим его тоже.
Внезапно мы замечаем, что у нас в типе "ссылка" есть тип
ссылки, у которой есть хэш-ссылка на метаданные и эту ссылку
будет уважать сборщик мусора, раз сейчас её уважает
downloader (качает её рекурсивно тоже).
Значит, нам не придется добавлять новые транзы, а можно
изменить тип дерева для существующих, и ссылку на артефакт
(GK0, GKi) добавлять туда.
Тогда всё тоже самое: обходим все транзы, достаём по ссылке
этот блок (нужно название), импортируем оттуда ключи
(свои только, чужие-то нам зачем), потом из этих ключей
достаём GKi по GK0 и им расшифровываем, что нам надо.
Такие дела.

View File

@ -22,4 +22,28 @@ TODO: save-objects-via-new-rpc
TODO: update-ref-via-new-rpc
обновлять ссылку через новый RPC.
TODO: git-group-key
Указывать для ссылки (возможно, для git remote?)
Перегенерировать, если ключ изменился.
Кейс: изменения "в прошлом". Сейчас репо это сумма всех
"логов", каждый "лог" - U(объектов из операции git push + установка ссылки).
Соответственно, перегенерировать ключ **обязательно**, если
авторы удалены из ключа.
Если ключ перегенерировать время от времени, как планировалось,
то возможна ситуация, когда нового автора в **старых** ключах
не будет. И у него не будет доступа к каким-то "старым"
объектам. А, в отличие от других примений, они ему нужны.
Что делать?
Даже если сгенерировать на каждый лог, где этот автор
отсутствовал --- групповой ключ, то ссылка на него не будет
доступна в старых сегмента, и при скачивании блоков,
hbs2-git не будет знать, какой ключ использовать.