a cli tool to manage and deploy configurations and secrets across multiple environments all stored inside your repository.
git secrets is built to automate local tasks like setting up the project or deploying secrets manually.
- Store secrets and configurations all in one place in your git repository
- Render secrets and configurations to custom files (like .env, config or k8s files) using the go templating language (just like helm)
- Manage multiple environments and inherit values from a default environment
- Automatically scan your repository for leaked passwords using a git hook
- Automatic configuration initialization and management using the CLI
- Built for CI/CD (Docker / Github Actions)
- For each Project / Context you can use a Encoder Secret which is stored at
~/.git-secrets.yaml
- The Encoder Secret is used to encode your passwords which are then stored inside your git repositories
.git-secrets.json
- The encrypted secrets are then decoded and rendered using Go Web Templates like Helm for example. (https://gowebexamples.com/templates/)
- Each project can have multiple contexts for example
default
andprod
- Every custom context inherits from the
default
context, so you don't have to define values twice - You can use a different Encoder Secret in each context so the engineer can only access the secrets he should need
- Encoding / Decoding: with-binary-example
- Kubernetes Secrets: render-kubernetes-secret
- Github Actions .github/workflows/docker-release.yml
Git-Secrets
is available on Linux, macOS and Windows platforms.
-
Binaries for Linux, Windows and Mac are available as tarballs in the release page.
-
Via Curl for Linux and Mac (uses https://github.com/jpillora/installer)
# without sudo curl https://i.jpillora.com/benammann/git-secrets! | bash # using sudo (if mv fails) curl https://i.jpillora.com/benammann/git-secrets!! | bash
-
Via Homebrew for macOS or LinuxBrew for Linux
brew install benammann/tap/git-secrets
-
Via a GO install
# NOTE: The dev version will be in effect! go install github.com/benammann/git-secrets@latest
The configuration is made in a json file called .git-secrets.json
you can also specify a custom path using -f <path-to-custom-file>
# Create a new global encoder secret (which you can later share with your team)
git secrets set global-secret mySecret --value $(pwgen -c 32 -n -s -y)
# Get the value of the global encryption secret
git secrets get global-secret mySecret
# Create a new .git-secrets.json
git secrets init
# Get the initial information of the config file
git secrets info
# Get the CLI's current version
git secrets version
Git-Secrets allows you to store encrypted Secrets
and plain Configs
both are stored in .git-secrets.json
# Encode a value (uses interactive input)
git secrets set secret databasePassword
# Write the value to a custom context
# Add Context: git secrets add context dev
git secrets set secret databasePassword -c dev
# Add a new config value
git secrets set config databaseHost db-host.svc.local
# Write the config value to a custom context
# Add Context: git secrets add context dev
git secrets set config databaseHost db-host.my-dev-db.svc -c dev
# Get the decoded value
git secrets get secret databasePassword
# Get the value stored in databaseHost
git secrets get config databaseHost
Git-Secrets allows you to render files using the Secret
and Config
values on the fly using gotemplates, just like Helm. For a syntax reference head over to https://gowebexamples.com/templates/
DATABASE_HOST={{.Configs.databaseHost}}
DATABASE_PASSWORD={{.Secrets.databasePassword}}
You can have custom renderTargets to render files. For example env
or k8s
. You can than add multiple files to a renderTargets.
# always render empty.dist to .env
# uses the targetName: env
git secrets add file empty.dist .env -t env
# now execute the rendering process
# this renders the empty.dist file to .env and fills out all variables using the default context
# targetName: env
git secrets render env
# prints all available variables
git secrets render env --debug
# prints the rendered files to the console without actually writing the file
git secrets render env --dry-run
# renders the files using the prod context
git secrets render env -c prod
Git-Secrets
provides a simple command to scan for plain secrets in the project files.
# scan all files added to git
git secrets scan -a
# scan staged files only
git secrets scan
# hint: add -v to show all the scanned file names
You should use this command to setup a pre-commit git-hook in your project. You can use Husky (https://typicode.github.io/husky/#/) to automatically install and setup the hook.
Git Secrets extends the GoLang Templating engine by some useful functions
The Base64Encode function takes the first argument and encodes it as Base64. This allows you to render Kubernetes Secrets
# Created by git-secrets
apiVersion: v1
data:
apiPassword: "{{ Base64Encode .Secrets.applicationAPassword }}"
kind: Secret
metadata:
name: api-application-a
namespace: {{.Configs.namespace}}
type: Opaque
GitConfig allows you to resolve git config values. For example if you want to render files individually to the developer
GIT_NAME={{GitConfig "user.name"}}
GIT_EMAIL={{GitConfig "user.email"}}
There is a github-action available to easily decode secrets in your CI/CD Pipeline: https://github.com/marketplace/actions/decrypt-secret
Example Usage
- name: Decrypt Secret Value
id: test_secret
uses: benammann/git-secrets-get-secret-action@v1
with:
name: testSecret
decryptSecretName: getsecretactionpublic
decryptSecretValue: ${{ secrets.GET_SECRET_ACTION_PUBLIC_SECRET }}
- name: Echo the output
run: echo "${{ steps.test_secret.outputs.value }}"
There is also a Docker Image available: benammann/git-secrets
.
Since git-secrets normally depends on a global .git-secrets.yaml
you need to use the --secret
parameter to pass the encryption secret using cli.
You also need to mount the project's .git-secrets.json
file using docker volume mounts.
# just execute the help command
docker run benamnann/git-secrets help
# get all the information about the .git-secrets.json file
docker run \
# mount .git-secrets.json to /git-secrets/.git-secrets.json
-v $PWD/.git-secrets.json:/git-secrets/.git-secrets.json \
# use the official docker image
benammann/git-secrets \
# execute the info command
info
docker run \
# mount .git-secrets.json to /git-secrets/.git-secrets.json
-v $PWD/.git-secrets.json:/git-secrets/.git-secrets.json \
# use the official docker image
benammann/git-secrets \
# pass the encryption secret 'gitsecretspublic' including it's value from an local Environment variable to docker
--secret gitsecretspublic=${SECRET_VALUE} \
# decrypt the secret crToken
get secret crToken
Git-Secrets uses AES-256 to encrypt / decrypt the secrets. Read more about it here Advanced Encryption Standard.
The encryption key is stored outside your git repository and can be referenced using multiple methods
The implementation can be found here engine_aes.go.
Named secrets are stored in ~/.git-secrets.yaml
and have a name. You can than reference it using the context.decryptSecret.fromName
key.
"decryptSecret": {
"fromName": "withbinaryexample"
},
You can define a decryptSecret
in each context to for example encrypt the production secrets using a different encryption key. This can be useful to not let your developers know the CI/CD Secrets.
The CLI provides multiple ways how to configure and manage your global secrets.
# Generate via pwgen and read from stdin
git secrets set global-secret mySecret --value $(pwgen -c 32 -n -s -y)
# Set manually using interactive input
git secrets set global-secret mySecret
# Get the written secret
git secrets get global-secret mySecret
# Get all global secret names
git secrets get global-secrets
In case you don't want to store the secrets globally and on the disk you can also use the following cli args to inject the secrets at runtime
# Uses the secret passed via --secret (insecure)
git secrets get secret mySecret --secret secretName=$(SECRET_VALUE) --secret secretName1=$(SECRET_VALUE_1)
The scripts and documentation in this project are released under the MIT License