diff --git a/cmd/add.go b/cmd/add.go index 6da9445..03ef28d 100644 --- a/cmd/add.go +++ b/cmd/add.go @@ -8,7 +8,7 @@ import ( // addCmd represents the add command var addCmd = &cobra.Command{ Use: "add", - Short: "allows you to set resources in your projects or global config file", + Short: "Add resources like context or file", Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, @@ -17,7 +17,7 @@ var addCmd = &cobra.Command{ // addContextCmd represents the addContext command var addContextCmd = &cobra.Command{ Use: "context", - Short: "adds a context to the existing config file", + Short: "Add a context to the config file", Example: "git-secrets add context ", PersistentPreRun: func(cmd *cobra.Command, args []string) { cobra.CheckErr(projectCfgError) @@ -38,7 +38,7 @@ var addContextCmd = &cobra.Command{ // addFileCmd represents the addFile command var addFileCmd = &cobra.Command{ Use: "file", - Short: "adds a file to render to the git-secrets file", + Short: "Add a file to the rendering engine", Example: ` git-secrets add file git-secrets add file -c prod @@ -64,5 +64,5 @@ func init() { rootCmd.AddCommand(addCmd) addCmd.AddCommand(addContextCmd) addCmd.AddCommand(addFileCmd) - addFileCmd.Flags().StringP(FlagTarget, "t", "", "sets the target: --target ") + addFileCmd.Flags().StringP(FlagTarget, "t", "", "Specifies the render target name: -t , example -t k8s") } diff --git a/cmd/get.go b/cmd/get.go index f1682d6..f8261b1 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -8,7 +8,7 @@ import ( // getCmd represents the get command var getCmd = &cobra.Command{ Use: "get", - Short: "allows you to get resources from the config", + Short: "Get resources like config, secret or global-secret", Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, @@ -17,7 +17,7 @@ var getCmd = &cobra.Command{ // getConfigCmd represents the getConfig command var getConfigCmd = &cobra.Command{ Use: "config", - Short: "resolves a config from the config file", + Short: "Get a config entry from the config file", Example: ` git-secrets get config git-secrets get config -c prod @@ -39,7 +39,7 @@ git-secrets get config -c prod // getSecretCmd represents the getSecret command var getSecretCmd = &cobra.Command{ Use: "secret", - Short: "resolves and decodes a secret", + Short: "Get and decode a secret entry from the config file", Example: ` git-secrets get secret git-secrets get secret -c prod diff --git a/cmd/global_secrets.go b/cmd/global_secrets.go index a4159ec..d96208c 100644 --- a/cmd/global_secrets.go +++ b/cmd/global_secrets.go @@ -1,18 +1,3 @@ -/* -Copyright © 2022 NAME HERE - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ package cmd import ( @@ -29,7 +14,7 @@ import ( // getGlobalSecretsCmd represents the globalSecrets command var getGlobalSecretsCmd = &cobra.Command{ Use: "global-secret", - Short: "allows to get the global secrets from ~/.git-secrets.yaml using the cli", + Short: "Get or list a secret from the global configuration", Example: ` git-secrets get global-secrets: get all global secret keys git-secrets get global-secret : prints the global secret value @@ -63,7 +48,7 @@ git-secrets get global-secret : prints the global secret value // setGlobalSecretsCmd represents the globalSecrets command var setGlobalSecretsCmd = &cobra.Command{ Use: "global-secret", - Short: "allows to set the global secrets from ~/.git-secrets.yaml using the cli", + Short: "Write a secret to the global configuration", Example: ` git-secrets set global-secret : sets the global secret from terminal input git-secrets set global-secret --value $MY_SECRET_VALUE_STORED_IN_ENV: sets the global secret value from --value parameter (insecure) @@ -112,8 +97,8 @@ func init() { getCmd.AddCommand(getGlobalSecretsCmd) setCmd.AddCommand(setGlobalSecretsCmd) - setGlobalSecretsCmd.Flags().Bool(FlagForce, false, "allows to overwrite secrets") - setGlobalSecretsCmd.Flags().String(FlagValue, "", "allows to pass the secret to write using a parameter") + setGlobalSecretsCmd.Flags().Bool(FlagForce, false, "Force overwrite existing secret: You may loose your master password!") + setGlobalSecretsCmd.Flags().String(FlagValue, "", "Pass the secret's value as parameter instead of password input") // Here you will define your flags and configuration settings. diff --git a/cmd/info.go b/cmd/info.go index 51bae29..a64b09f 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -14,7 +14,7 @@ const InfoCmdFlagDecode = "decode" // infoCmd represents the info command var infoCmd = &cobra.Command{ Use: "info", - Short: "prints the current configuration", + Short: "Get detailed information about the current configuration", Example: ` git-secrets info git-secrets info -d: Also decodes all secrets @@ -103,8 +103,6 @@ git-secrets info -d -c prod: Decodes all secrets from the prod context func init() { rootCmd.AddCommand(infoCmd) - - rootCmd.Flags().BoolP(InfoCmdFlagDecode, "d", false, "Adds the decoded secrets to the info table") infoCmd.Flags().BoolP(InfoCmdFlagDecode, "d", false, "Adds the decoded secrets to the info table") // Here you will define your flags and configuration settings. diff --git a/cmd/init.go b/cmd/init.go index 915c200..2078772 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -15,7 +15,7 @@ import ( // initCmd represents the init command var initCmd = &cobra.Command{ Use: "init", - Short: "initializes a new git-secrets project", + Short: "Initializes a new .git-secrets.json Project", Example: ` git-secrets init `, @@ -35,7 +35,7 @@ git-secrets init } if len(secretKeys) < 0 { - cobra.CheckErr(fmt.Errorf("please create a global secret before: git-secrets global-secrets ")) + cobra.CheckErr(fmt.Errorf("please create a global secret before: git secrets set global-secret ")) } var outputFileQuestions = []*survey.Question{ diff --git a/cmd/render.go b/cmd/render.go index 398657b..bc9513c 100644 --- a/cmd/render.go +++ b/cmd/render.go @@ -18,7 +18,7 @@ type RenderFileData struct { // renderCmd represents the render command var renderCmd = &cobra.Command{ Use: "render", - Short: "render files feature", + Short: "Render files using the go templating engine", Example: ` git-secrets render : Render from configuration git-secrets render ,,...: Renders multiple targets at once @@ -67,7 +67,8 @@ git-secrets render --debug: Render and write the rendering target } if len(filesToRender) == 0 { - cobra.CheckErr(fmt.Errorf("could not resolve any files to render. Use --file-in to render a custom file using this context")) + fmt.Println("could not resolve any files to render. Use git secrets render -c to render a file manually") + cobra.CheckErr(fmt.Errorf("you can also add a file using git secrets add file -t ")) } } else { diff --git a/cmd/root.go b/cmd/root.go index bc601e8..10220aa 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -35,6 +35,7 @@ const FlagDryRun = "dry-run" const FlagTarget = "target" const FlagAll = "all" const FlagVerbose = "verbose" +const FlagShort = "short" // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ @@ -70,13 +71,14 @@ func init() { // Cobra supports persistent flags, which, if defined here, // will be global for your application. // will be global for your application. - rootCmd.PersistentFlags().StringVar(&globalCfgFile, "global-config", "", "global config file (default is $HOME/.git-secrets.yaml)") - rootCmd.PersistentFlags().StringVarP(&projectCfgFile, "project-config", "f", ".git-secrets.json", "project config file (default is .git-secrets.json)") - rootCmd.PersistentFlags().StringVarP(&contextName, "context-name", "c", "", "context name (default is 'default')") - rootCmd.PersistentFlags().StringArrayVar(&overwrittenSecrets, "secret", []string{}, "--secret secretA=$(SECRET_A_VALUE) --secret secretB=$(SECRET_B_VALUE): Pass 1-n secret names. Make sure to use environment variables to fill them!") + rootCmd.PersistentFlags().StringVar(&globalCfgFile, "global-config", "", "Path to the global config file: ~/.git-secrets.yaml") + rootCmd.PersistentFlags().StringVarP(&projectCfgFile, "config", "f", ".git-secrets.json", "Path to the projects config file: .git-secrets.json") + rootCmd.PersistentFlags().StringVarP(&contextName, "context", "c", "", "Which context to use: default") + rootCmd.PersistentFlags().StringArrayVar(&overwrittenSecrets, "secret", []string{}, "Pass global secrets directly: --secret secretKey=secretValue") // Cobra also supports local flags, which will only run // when this action is called directly. - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + + rootCmd.CompletionOptions.HiddenDefaultCmd = true } // initGlobalConfig reads in config file and ENV variables if set. diff --git a/cmd/scan.go b/cmd/scan.go index 7d260c0..4c0261e 100644 --- a/cmd/scan.go +++ b/cmd/scan.go @@ -1,18 +1,3 @@ -/* -Copyright © 2022 NAME HERE - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ package cmd import ( @@ -41,7 +26,7 @@ var scanCmd = &cobra.Command{ PersistentPreRun: func(cmd *cobra.Command, args []string) { cobra.CheckErr(projectCfgError) }, - Short: "A brief description of your command", + Short: "Searches project files for leaked secrets", Run: func(cmd *cobra.Command, args []string) { start := time.Now() @@ -186,8 +171,8 @@ var scanCmd = &cobra.Command{ func init() { rootCmd.AddCommand(scanCmd) - scanCmd.Flags().BoolP(FlagAll, "a", false, "--all or -a: scan all files that are contained in the git repo") - scanCmd.Flags().BoolP(FlagVerbose, "v", false, "--verbose or -v: list the scanned files") + scanCmd.Flags().BoolP(FlagAll, "a", false, "Scan all files that are contained in the git repo") + scanCmd.Flags().BoolP(FlagVerbose, "v", false, "List the scanned files") // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command diff --git a/cmd/set.go b/cmd/set.go index 3857e82..d6ddbb4 100644 --- a/cmd/set.go +++ b/cmd/set.go @@ -9,7 +9,7 @@ import ( // setCmd represents the set command var setCmd = &cobra.Command{ Use: "set", - Short: "allows you to set resources in your projects or global config file", + Short: "Set resources like config, secret or global-secret", Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, @@ -18,7 +18,7 @@ var setCmd = &cobra.Command{ // setConfigCmd represents the setConfig command var setConfigCmd = &cobra.Command{ Use: "config", - Short: "adds a config entry to the git-secrets file", + Short: "Set a config entry", Example: ` git-secrets set config git-secrets set config -c prod @@ -41,7 +41,7 @@ git-secrets set config -c prod // setSecretCmd represents the setSecret command var setSecretCmd = &cobra.Command{ Use: "secret", - Short: "encodes a secret and sets it in the git-secrets file", + Short: "Encode and write a secret to the config file", Example: ` git-secrets set secret : Encodes the secret using interactive ui and adds it to the git-secrets file git-secrets set secret --value : INSECURE: Uses the value directly from the --value parameter diff --git a/cmd/version.go b/cmd/version.go index 4d8d6ff..f667b4f 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -1,45 +1,39 @@ -/* -Copyright © 2022 NAME HERE - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ package cmd import ( "fmt" + "github.com/fatih/color" "github.com/spf13/cobra" ) // versionCmd represents the version command var versionCmd = &cobra.Command{ Use: "version", - Short: "prints the version", + Short: "Prints the version", Run: func(cmd *cobra.Command, args []string) { - fmt.Println(` + + isShort, _ := cmd.Flags().GetBool(FlagShort) + + if isShort == false { + color.Blue(` ________.__ __ _________ __ / _____/|__|/ |_ / _____/ ____ ___________ _____/ |_ ______ / \ ___| \ __\ \_____ \_/ __ \_/ ___\_ __ \_/ __ \ __\/ ___/ \ \_\ \ || | / \ ___/\ \___| | \/\ ___/| | \___ \ \______ /__||__| /_______ /\___ >\___ >__| \___ >__| /____ > \/ \/ \/ \/ \/ \/`) - fmt.Println("") - fmt.Println("https://github.com/benammann/git-secrets", "v"+version, "rev:"+commit, date) + fmt.Println("") + } + fmt.Println("Version ", version) + fmt.Println("Commit ", commit) + fmt.Println("Date ", date) + }, } func init() { rootCmd.AddCommand(versionCmd) - + versionCmd.Flags().BoolP(FlagShort, "s", false, "Print version info in short format") // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command diff --git a/readme.md b/readme.md index 4421d58..05cf069 100644 --- a/readme.md +++ b/readme.md @@ -1,12 +1,46 @@ -## encryption and rendering engine for git repositories - -![Tag](https://img.shields.io/github/v/release/benammann/git-secrets?label=release) -![Docker Image Version](https://img.shields.io/docker/v/benammann/git-secrets?label=image) -![Release Badge](https://github.com/benammann/git-secrets/actions/workflows/goreleaser.yml/badge.svg) -![Test Badge](https://github.com/benammann/git-secrets/actions/workflows/docker-release.yml/badge.svg) -![License](https://img.shields.io/github/license/benammann/git-secrets?123) - -Git Secrets encrypts your passwords and configurations for multiple environments and allows you to check them into a git repository. Using the GoLang templating engine, you can then decrypt them and write them to env files or Kubernetes deployment files. +
+

Git Secrets

+

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.

+ + + + + +
+
+
+ + + +* [Features](#features) +* [How does it work](#how-does-it-work) +* [Demo](#demo) +* [Examples](#examples) +* [Installation](#installation) +- [Getting started](#getting-started) + * [Initialize the project](#initialize-the-project) + * [Encode a secret and add a config entry](#encode-a-secret-and-add-a-config-entry) + * [Decode the secrets and get the config entry](#decode-the-secrets-and-get-the-config-entry) + * [Create a `.env.dist` file](#create-a-envdist-file) + * [Scan for plain secrets](#scan-for-plain-secrets) + * [Custom Template Functions](#custom-template-functions) + + [Base64Encode](#base64encode) + + [GitConfig](#gitconfig) + * [Using Github-Actions](#using-github-actions) + * [Using Docker](#using-docker) +- [Documentation](#documentation) + * [How the encryption is done](#how-the-encryption-is-done) + + [Named Secrets](#named-secrets) + + [Overwrite using CLI Args](#overwrite-using-cli-args) +* [License](#license) + +### Features +- 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) ### How does it work @@ -67,6 +101,9 @@ The configuration is made in a json file called `.git-secrets.json` you can also # 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 @@ -277,4 +314,8 @@ In case you don't want to store the secrets globally and on the disk you can als ```bash # Uses the secret passed via --secret (insecure) git secrets get secret mySecret --secret secretName=$(SECRET_VALUE) --secret secretName1=$(SECRET_VALUE_1) -``` \ No newline at end of file +``` + +# License + +The scripts and documentation in this project are released under the [MIT License](LICENSE) \ No newline at end of file