git-private
lets you store private data inside a git
repo.
A common use case is protecting files containing API keys et.c.
git-private
encrypts your private files and keeps track of a list of public keys for users that should have access to these files. The complete state (encrypted files and public keys) is kept directly in the git
repo, there are no external dependencies.
Encryption is provided by age, using either age
or ssh
key pairs.
git-private
is a single binary tool, for easy installation and dependency tracking.
- Install
git-private
- In your repo, run
git private init
- Add the key of the first user (most likely you):
git private keys add -keyfile ~/.ssh/id_rsa -pubfile ~/.ssh/id_rsa.pub
- Add your private file:
git private add apikeys.json
- Hide (encrypt) the added file:
git private hide -keyfile ~/.ssh/id_rsa
Now, commit your changes. In this example, the changed files are:
.gitprivate/*
.gitignore
apikeys.json.private
Note that:
- the
keyfile
is used to identify you while thepubfile
is the public key being added- when the first key is added, the keyfile and pubfile belong to the same pair
- the original file,
apikeys.json
is added to.gitignore
automatically and is not commited - the
git-private
state lives in.gitprivate/
- the
hide
command encrypts all files tracked bygit-private
- a user's private key should never be added to the git repo!
To avoid having to specify the private key file on the command line, use one of these environment variables instead:
GIT_PRIVATE_KEY
="private key data"GIT_PRIVATE_KEYFILE
="path to private key file"
Use the add
and remove
commands to update the list of files that should be tracked by git-private
.
Then use the hide
command to encrypt these files.
Hiding encrypts tracked files using the current public key list.
Be default, the original files are kept in place.
Use the -clean
flag to remove them after encryption.
Example:
$ git private hide -keyfile ~/secret.age -clean
Revealing hidden files
Use the reveal
command to decrypt files.
This is needed after cloning a repo or when pulling changes to private files or keys.
If you don't want to reveal all files, you can specify a list of files to reveal.
The keys
command is used to list, add, remove or generate keys.
Note that except for the first key added, you need to be in the git-private
key list to be able to access the key list.
Keys that are added as read-only can only be used to reveal files, which does not require access to the key list.
git-private
supports age
keys as produced by the age-keygen
tool.
Since age
keys do not contain IDs, which is used to reference keys in git-private
, the ID has to be provided using the -id
flag when adding the key.
age
keys can also be generated by the keys generate
command. The tool will prompt for a passphrase, which will be used to protect the generated private key. If no passphrase is entered, the private key will be stored in clear text, just like the age-keygen
tool does.
Do not keep keys in the repo!
To simplify adoption of the tool, you can use existing ssh
keys with git-private
.
Note that ssh-agent
is not supported. Passphrases need to be entered on each encryption operation.
In general, the tool refuses to overwrite existing files without specifying the force
flag.
The tool keeps a hash of the last hidden version of a file, and uses that hash to check if currently revealed files are different.
Use the status
command to check the status of files tracked by git-private
.
The status
command exits with code 0 (success) if all tracked files are in sync.
Get pre-built binaries from github, or install using your local go toolchain:
$ go get github.com/erkkah/git-private
To use git-private
in automated build flows, create a keypair without passphrase using git private keys generate
.
Then add the public key to the key list with read-only access (git private keys add -readonly
...).
Use the secure variables storage feature of your CI/CD system to store the private key, and make sure git-private
can read the key from the GIT_PRIVATE_KEY
environment variable.
Now use the reveal -clean
command to reveal all files needed for the build and remove the .private
files to avoid distributing them with the build.
This project is highly inspired by git-secret, and attempts to provide the same functionality without dependencies to PGP and lots of shell stuff.
https://latacora.micro.blog/2019/07/16/the-pgp-problem.html
All metadata lives in .gitprivate
, file info in files.json
and key info in keys.dat
.
Encrypted files are stored next to the original files as original.private
.