Bläddra i källkod

feat: add option to set config from env var with toml content (#1662)

* feat: add option to set config from env var with toml content

* Update README.md

Co-authored-by: Richard Gomez <32133502+rgmz@users.noreply.github.com>

* fix: check if config provided by GITLEAKS_CONFIG_TOML can be loaded

* docs: move load configuration section to have it before configuration

---------

Co-authored-by: Richard Gomez <32133502+rgmz@users.noreply.github.com>
Roger Meier 10 månader sedan
förälder
incheckning
a503b583ba
2 ändrade filer med 42 tillägg och 7 borttagningar
  1. 28 2
      README.md
  2. 14 5
      cmd/root.go

+ 28 - 2
README.md

@@ -157,8 +157,9 @@ Flags:
                                       order of precedence:
                                       1. --config/-c
                                       2. env var GITLEAKS_CONFIG
-                                      3. (target path)/.gitleaks.toml
-                                      If none of the three options are used, then gitleaks will use the default config
+                                      3. env var GITLEAKS_CONFIG_TOML with the file content
+                                      4. (target path)/.gitleaks.toml
+                                      If none of the four options are used, then gitleaks will use the default config
       --enable-rule strings           only enable specific rules by id
       --exit-code int                 exit code when leaks have been encountered (default 1)
   -i, --gitleaks-ignore-path string   path to .gitleaksignore file or folder containing one (default ".")
@@ -223,6 +224,31 @@ After running the detect command with the --baseline-path parameter, report outp
 You can run Gitleaks as a pre-commit hook by copying the example `pre-commit.py` script into
 your `.git/hooks/` directory.
 
+## Load Configuration
+
+The order of precedence is:
+
+1. `--config/-c` option:
+  ```bash
+  gitleaks git --config /home/dev/customgitleaks.toml .
+  ```
+1. Environment variable `GITLEAKS_CONFIG` with the file path:
+  ```bash
+  export GITLEAKS_CONFIG="/home/dev/customgitleaks.toml"
+  gitleaks git .
+  ```
+1. Environment variable `GITLEAKS_CONFIG_TOML` with the file content:
+  ```bash
+  export GITLEAKS_CONFIG_TOML=`cat customgitleaks.toml`
+  gitleaks git .
+  ```
+1. A `.gitleaks.toml` file within the target path:
+  ```bash
+  gitleaks git .
+  ```
+
+If none of the four options are used, then gitleaks will use the default config.
+
 ## Configuration
 
 Gitleaks offers a configuration format you can follow to write your own secret detection rules:

+ 14 - 5
cmd/root.go

@@ -1,6 +1,7 @@
 package cmd
 
 import (
+	"bytes"
 	"fmt"
 	"io"
 	"os"
@@ -33,8 +34,9 @@ const configDescription = `config file path
 order of precedence:
 1. --config/-c
 2. env var GITLEAKS_CONFIG
-3. (target path)/.gitleaks.toml
-If none of the three options are used, then gitleaks will use the default config`
+3. env var GITLEAKS_CONFIG_TOML with the file content
+4. (target path)/.gitleaks.toml
+If none of the four options are used, then gitleaks will use the default config`
 
 var rootCmd = &cobra.Command{
 	Use:     "gitleaks",
@@ -104,6 +106,8 @@ func initLog() {
 
 func initConfig(source string) {
 	hideBanner, err := rootCmd.Flags().GetBool("no-banner")
+	viper.SetConfigType("toml")
+
 	if err != nil {
 		logging.Fatal().Msg(err.Error())
 	}
@@ -124,6 +128,13 @@ func initConfig(source string) {
 		envPath := os.Getenv("GITLEAKS_CONFIG")
 		viper.SetConfigFile(envPath)
 		logging.Debug().Msgf("using gitleaks config from GITLEAKS_CONFIG env var: %s", envPath)
+	} else if os.Getenv("GITLEAKS_CONFIG_TOML") != "" {
+		configContent := []byte(os.Getenv("GITLEAKS_CONFIG_TOML"))
+		if err := viper.ReadConfig(bytes.NewBuffer(configContent)); err != nil {
+			logging.Fatal().Msgf("unable to load gitleaks config from GITLEAKS_CONFIG_TOML env var content(%s), err: %s", configContent, err)
+		}
+		logging.Debug().Msgf("using gitleaks config from GITLEAKS_CONFIG_TOML env var content: %s", configContent)
+		return
 	} else {
 		fileInfo, err := os.Stat(source)
 		if err != nil {
@@ -133,7 +144,6 @@ func initConfig(source string) {
 		if !fileInfo.IsDir() {
 			logging.Debug().Msgf("unable to load gitleaks config from %s since --source=%s is a file, using default config",
 				filepath.Join(source, ".gitleaks.toml"), source)
-			viper.SetConfigType("toml")
 			if err = viper.ReadConfig(strings.NewReader(config.DefaultConfig)); err != nil {
 				logging.Fatal().Msgf("err reading toml %s", err.Error())
 			}
@@ -142,7 +152,7 @@ func initConfig(source string) {
 
 		if _, err := os.Stat(filepath.Join(source, ".gitleaks.toml")); os.IsNotExist(err) {
 			logging.Debug().Msgf("no gitleaks config found in path %s, using default gitleaks config", filepath.Join(source, ".gitleaks.toml"))
-			viper.SetConfigType("toml")
+
 			if err = viper.ReadConfig(strings.NewReader(config.DefaultConfig)); err != nil {
 				logging.Fatal().Msgf("err reading default config toml %s", err.Error())
 			}
@@ -153,7 +163,6 @@ func initConfig(source string) {
 
 		viper.AddConfigPath(source)
 		viper.SetConfigName(".gitleaks")
-		viper.SetConfigType("toml")
 	}
 	if err := viper.ReadInConfig(); err != nil {
 		logging.Fatal().Msgf("unable to load gitleaks config, err: %s", err)