Git clean / smudge filters для секретов хранилища
Я пытаюсь настроитьчистый / грязный фильтр в Git иметь автоматическое шифрование и дешифрование файлов, содержащих секреты черезанзибль-хранилище команда.
Особенность команды ansible-vault в том, что она не идемпотентна (она создает новый двоичный файл каждый раз, когда она вызывается для одних и тех же данных).
Я начал с реализации, предложенной вэта страница блога, К сожалению, это не сработало правильно, так как всякий раз, когда вызывается smudge (будь то проверка git или просто состояние git), секретные файлы выглядят измененными для git, даже если это не так.
Поэтому я подумал, будет ли git сравнивать двоичный файл, который он имеет в индексе, с текущим файлом с чистой фильтрацией, и я попытался построить этот скрипт следующим образом:
#!/bin/sh -x
# clean filter, it is invoked with %f
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
tmp=`mktemp`
cat > $tmp
# get the plain text from the binary in the index
tmphead=`mktemp`
git show HEAD:$1 > $tmphead
contenthead=`echo "embedded" | ansible-vault view $tmphead --vault-password-file=$HOME/.vault_password`
export PAGER=cat
echo -n "$contenthead" | tee $tmphead
# if current and index plain text version differ
if [ "`md5sum $tmp | cut -d' ' -f1`" != "`md5sum $tmphead | cut -d' ' -f1`" ]; then
tmpcrypt=`mktemp`
cp $tmp $tmpcrypt
# generate a new crypted blob
echo "embedded" | ansible-vault encrypt $tmpcrypt --vault-password-file=$HOME/.vault_password > /dev/null 2>&1
cat "$tmpcrypt"
else
# just return the HEAD version
cat "$tmphead"
fi
rm $tmp $tmphead $tmpcrypt
Разница здесь в том, что он пытается сравнить текущие версии и версии HEAD секретных файлов в виде простого текста (незашифрованные) и только в случае их различия выводит новый двоичный двоичный объект, зашифрованный с помощью ansible-vault.
К сожалению, после этого изменения git продолжает думать, что секретный файл всегда изменяется. Даже послеgit add
Снова запустив файл, чтобы вычислить git blob, git считает, что файл отличается, и пусть изменения вступают в коммит. Обратите внимание, чтоgit diff
вернуть пустые изменения, как и должно быть.
Для справки, это пятно:
#!/bin/sh
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
tmp=`mktemp`
cat > $tmp
export PAGER='cat'
CONTENT="`echo "embedded" | ansible-vault view "$tmp" --vault-password-file=$HOME/.vault_password 2> /dev/null`"
if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
echo "Looks like one file was commited clear text"
echo "Please fix this before continuing !"
exit 1
else
echo -n "$CONTENT"
fi
rm $tmp
и это diff:
#!/bin/sh
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
export PAGER='cat'
CONTENT=`echo "embedded" | ansible-vault view "$1" --vault-password-file=$HOME/.vault_password 2> /dev/null`
if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
cat "$1"
else
echo "$CONTENT"
fi