When dealing with confidential information (such as passwords, tokens, key files, etc.), the following issues are worth considering:
Security is very important, but high security often comes with a high degree of inconvenience.
In a team, sharing some keys sometimes cannot be avoided (therefore, we now need to consider the secure methods of distributing and updating keys among multiple people).
The specific keys usually depend on the environment.
There are many mature key management products on the market, such as HashiCorp Vault, AWS Secrets Manager, and GCP Secret Manager. Since these products require integration and maintenance services, introducing them into the project will increase certain costs and expenses. Read this article, and it will guide you on how to set upgit-secret
andgpg
.
This article will discuss the following points:
Identify the files containing the key
Ensure that the key is added to
.gitignore
Through
git-secret
Perform encryptionCommit the encrypted file to the repository
Finally, we will be able to call:
make secret-decrypt
This will expose the keys in the codebase, modify them if necessary, and then run:
make secret-encrypt
You need to re-encrypt the key to commit (and push) it to the remote repository. To see the actual effect, please run the following command:
# Checkout the branch
git checkout part-6-git-secret-encrypt-repository-docker
# Build and start the Docker setup
make make-init
make docker-build
make docker-up
# "create" the secret key - the file "secret.gpg.example" would usually NOT live in the repo!
cp secret.gpg.example secret.gpg
# initialize gpg
make gpg-init
# ensure that the decrypted secret file does not exist
ls passwords.txt
# decrypt the secret file
make secret-decrypt
# show the content of the secret file
cat passwords.txt
Tooling
We use PHPbase
are set in the imagegpg
andgit-secret
so that these tools are available in all other containers. All commands below areapplication
is executed in the container.
Please note thatgit-secret
When using the folder shared between the host system and the docker container, it should be noted. It will be called "git-secret
Directories andgpg-agent
The part of "socket" explains this in more detail.
gpg
gpg stands for The GNU Privacy Guard, which is an open-source implementation of the OpenPGP standard. In short, GNU allows us to create a personal key file pair (similar to SSH keys), which contains a private key and a public key that can be shared with others to decrypt their messages.
gpg installation
Regarding installation, we can simply run:apk add gnupg
and update accordingly.docker/images/php/base/Dockerfile
:
# File: .docker/images/php/base/DockerfileRUN apk add --update --no-cache \
bash \
gnupg \
make \
#...
Create gpg key pair
We need to create through the following method:gpg
Key Pair (Key Pair):
name="Pascal Landau"
email="pascal.landau@example.com"
gpg --batch --gen-key <<EOF
Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: $name
Name-Email: $email
Expire-Date: 0
%no-protection
EOF
%no-protection
Create a key without a password.
Output:
$ name="Pascal Landau"
$ email="pascal.landau@example.com"
$ gpg --batch --gen-key <<EOF
> Key-Type: 1
> Key-Length: 2048
> Subkey-Type: 1
> Subkey-Length: 2048
> Name-Real: $name
> Name-Email: $email
> Expire-Date: 0
> %no-protection
> EOF
gpg: key E1E734E00B611C26 marked as ultimately trusted
gpg: revocation certificate stored as '/root/.gnupg/opengpg-revocs.d/74082D81525723F5BF5B2099E1E734E00B611C26.rev'
Also without--batch
flags to interactively guide the entire processgpg --gen-key
and then export, list, and import privategpg
The key can be exported in the following ways:
email="pascal.landau@example.com"
path="secret.gpg"
gpg --output "$path" --armor --export-secret-key "$email"
Remember not to share this key.
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQOYBF7VVBwBCADo9un+SySu/InHSkPDpFVKuZXg/s4BbZmqFtYjvUUSoRAeSejv
G21nwttQGut+F+GdpDJL6W4pmLS31Kxpt6LCAxhID+PRYiJQ4k3inJfeUx7Ws339
XDPO3Rys+CmnZchcEgnbOfQlEqo51DMj6mRF2Ra/6svh7lqhrixGx1BaKn6VlHkC
...
ncIcHxNZt7eK644nWDn7j52HsRi+wcWsZ9mjkUgZLtyMPJNB5qlKQ18QgVdEAhuZ
xT3SieoBPd+tZikhu3BqyIifmLnxOJOjOIhbQrgFiblvzU1iOUOTOcSIB+7A
=YmRm
-----END PGP PRIVATE KEY BLOCK-----
All keys can be listed in the following ways:
gpg --list-secret-keys
Output:
$ gpg --list-secret-keys
/root/.gnupg/pubring.kbx
------------------------
sec rsa2048 2022-03-27 [SCEA]
74082D81525723F5BF5B2099E1E734E00B611C26
uid [ultimate] Pascal Landau <pascal.landau@example.com>
ssb rsa2048 2022-03-27 [SEA]
Private keys can be imported in the following way:
path="secret.gpg"
gpg --import "$path"
The following output is obtained:
$ path="secret.gpg"
$ gpg --import "$path"
gpg: key E1E734E00B611C26: "Pascal Landau <pascal.landau@example.com>" not changed
gpg: key E1E734E00B611C26: secret key imported
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys unchanged: 1
Note: If the secret key requires a password, a prompt will be displayed here. We can use the following method to bypass the prompt--batch --yes --pinentry-mode loopback
:
path="secret.gpg"
gpg --import --batch --yes --pinentry-mode loopback "$path"
Password is not required at the moment, but it will be needed later when trying to decrypt files.
Export, list, and importgpg
Public key, which can be exported in the following waypublic.gpg
:
email="pascal.landau@example.com"
path="public.gpg"
gpg --armor --export "$email" > "$path"
Export as follows:
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBF7VVBwBCADo9un+SySu/InHSkPDpFVKuZXg/s4BbZmqFtYjvUUSoRAeSejv
G21nwttQGut+F+GdpDJL6W4pmLS31Kxpt6LCAxhID+PRYiJQ4k3inJfeUx7Ws339
...
3LLbK7Qxz0cV12K7B+n2ei466QAYXo03a7WlsPWn0JTFCsHoCOphjaVsncIcHxNZ
t7eK644nWDn7j52HsRi+wcWsZ9mjkUgZLtyMPJNB5qlKQ18QgVdEAhuZxT3SieoB
Pd+tZikhu3BqyIifmLnxOJOjOIhbQrgFiblvzU1iOUOTOcSIB+7A
=g0hF
-----END PGP PUBLIC KEY BLOCK-----
List all public keys in the following way:
gpg --list-keys
Output:
$ gpg --list-keys
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048 2022-03-27 [SCEA]
74082D81525723F5BF5B2099E1E734E00B611C26
uid [ultimate] Pascal Landau <pascal.landau@example.com>
sub rsa2048 2022-03-27 [SEA]
Public keys can be imported in the same way as private keys through the following method:
path="public.gpg"
gpg --import "$path"
For example:
$ gpg --import /var/www/app/public.gpg
gpg: key E1E734E00B611C26: "Pascal Landau <pascal.landau@example.com>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
git-secret
The official website of git-secret can be found for detailed information about this tool. git-secret allows certain files to be declared as "secret" andgpg
Encryption. Then the encrypted files can be stored securely in the Git repository and decrypted when needed. This document usesgit-secret v0.4.0
:
$ git secret --version
0.4.0
git-secret installation
The installation instructions for Alpine are as follows:
sh -c "echo 'https://gitsecret.jfrog.io/artifactory/git-secret-apk/all/main'" >> /etc/apk/repositories
wget -O /etc/apk/keys/git-secret-apk.rsa.pub 'https://gitsecret.jfrog.io/artifactory/api/security/keypair/public/repositories/git-secret-apk'
apk add --update --no-cache git-secret
.docker/images/php/base/Dockerfile
Perform the update:
# File: .docker/images/php/base/Dockerfile
# install git-secret
# @see https://git-secret.io/installation#alpine
ADD https://gitsecret.jfrog.io/artifactory/api/security/keypair/public/repositories/git-secret-apk /etc/apk/keys/git-secret-apk.rsa.pub
RUN echo "https://gitsecret.jfrog.io/artifactory/git-secret-apk/all/main" >> /etc/apk/repositories && \
apk add --update --no-cache \
bash \
git-secret \
gnupg \
make \
#...
Usage of git-secret
Initialize git-secret
git-secret
Initialize with the following command run in the root directory of the Git repository.
git secret init$ git secret init
git-secret: init created: '/var/www/app/.gitsecret/'
Perform this operation only once, and later the folder will be committed to Git, including the following files:
$ git status | grep ".gitsecret"
new file: .gitsecret/keys/pubring.kbx
new file: .gitsecret/keys/pubring.kbx~
new file: .gitsecret/keys/trustdb.gpg
new file: .gitsecret/paths/mapping.cfg
Thepubring.kbx~
file (with a tilde~
)is just a temporary file and can be safely ignored by git.
git-secret Directory and gpg-agent Socket
Togit-secret
The directory shared between the host system and Docker requires the following command to be run:
tee .gitsecret/keys/S.gpg-agent <<EOF
%Assuan%
socket=/tmp/S.gpg-agent
EOF
tee .gitsecret/keys/S.gpg-agent.ssh <<EOF
%Assuan%
socket=/tmp/S.gpg-agent.ssh
EOF
tee .gitsecret/keys/gpg-agent.conf <<EOF
extra-socket /tmp/S.gpg-agent.extra
browser-socket /tmp/S.gpg-agent.browser
EOF
This step is necessary becausegit-secret
between the host system and Docker container when sharing the code repository, as follows:
gpg
Usinggpg-agent
to execute its tasks, these two tools have issues when used in the configuration ofpgp-agent
of--home-directory
sockets created inproxy through
git-secret
usedgpg
implicitly started by the command, using.gitsecret/keys
directory being--home-directory
.Due to
--home-directory
location is shared with the host system, so the socket creation will fail.
The corresponding error message is:
gpg: can't connect to the agent: IPC connect call failed
gpg-agent: error binding socket to '/var/www/app/.gitsecret/keys/S.gpg-agent': I/O error
To solve this problem, you can place other gpg configuration files in.gitsecret/keys
In the directory, thegpg
Configure to use different locations for sockets:
S.gpg-agent
%Assuan%
socket=/tmp/S.gpg-agent
s.gpg-agent.ssh
%Assuan%
socket=/tmp/S.gpg-agent
gpg-agent.conf
extra-socket /tmp/S.gpg-agent.extra
browser-socket /tmp/S.gpg-agent.browser
Add, list, and delete users
To add a new user, you must first import their public gpg key. Then run:
email="pascal.landau@example.com"
git secret tell "$email"
In this case, the userpascal.landau@example.com
Now you will be able to decrypt these keys. To display users, please run:
git secret whoknows$ git secret whoknows
pascal.landau@example.com
To delete a user, please run:
email="pascal@example.com"
git secret killperson "$email"
This command is executed at this timegit-secret >= 0.5.0
has been renamed toremoveperson
$ git secret killperson pascal.landau@example.com
git-secret: removed keys.
git-secret: now [pascal.landau@example.com] do not have access to the repository.
git-secret: make sure to hide the existing secrets again.
User pascal@example.com will no longer be able to decrypt these keys.
Note that after deleting the user, you need to re-encrypt the secrets and rotate the encryption keys.
Add, list, and delete files for encryption
Rungit secret add [filenames...]
to encrypt the file:
git secret add .env
If.env
has not been added to.gitignore
,git-secret
A warning will be displayed and they will be added automatically.
git-secret: these files are not in .gitignore: .env
git-secret: automatically adding them to .env
git-secret: 1 item(s) added.
If it has been added, no warning will be issued when adding the file.
$ git secret add .env
git-secret: 1 item(s) added.
You only need to add the file once. Then store them in.gitsecret/paths/mapping.cfg
:
$ cat .gitsecret/paths/mapping.cfg
.env:505070fc20233cb426eac6a3414399d0f466710c993198b1088e897fdfbbb2d5
You can also display the added files in the following way:
git-secret list$ git secret list
.env
It is important to note that at this time the file is not encrypted, and if you want to remove a file from encryption, please run:
git-secret list$ git secret list
.env
Output:
$ git secret remove .env
git-secret: removed from index.
git-secret: ensure that files: [.env] are now not ignored.
Encrypt files
To encrypt files, please run:
git secret hide
Output:
$ git secret hide
git-secret: done. 1 of 1 files are hidden.
All throughgit secret tell
The users added can decrypt these encrypted files, which also means that every time a new user is added, you need to run this command again.
Decrypt files
Files can be decrypted in the following way:
git secret reveal
Output:
$ git secret reveal
File '/var/www/app/.env' exists. Overwrite? (y/N) y
git-secret: done. 1 of 1 files are revealed.
the file is decrypted and will overwrite the current unencrypted file.
Using
-f
the option to force overwrite and run non-interactively.If you only want to check the content of the encrypted file, you can use
git secret cat $filename
For example,git secret cat. env
.
Whengpg
When the key is protected by a password, it needs to be passed through-p
The option passes the password. Here is an example of a password123456
:
git secret reveal -p 123456
Display changes between encrypted and decrypted files
One problem with encrypting files is that encrypted files cannot be reviewed during the code review of remote tools. To understand what changes have been made, displaying the changes between the encrypted and decrypted files can help solve this problem. This can be done in the following way:
git secret changes
Output:
$ echo "foo" >> .env
$ git secret changes
git-secret: changes in /var/www/app/.env:
--- /dev/fd/63
+++ /var/www/app/.env
@@ -34,3 +34,4 @@
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
+foo
Note the bottom+foo
. It is through the first lineecho "foo">>>.env
is added.
This article is the first part of the usage of git-secret, in the next part we will introduce the initial settings of git-secret, Makefile adjustments, and more. Stay tuned~

评论已关闭