ソースを参照

Standardize/alphabetize rules, add cmd/generate/config package (#840)

Zachary Rice 3 年 前
コミット
606bb1a13b
62 ファイル変更2763 行追加446 行削除
  1. 3 0
      .gitignore
  2. 122 0
      cmd/generate/config/main.go
  3. 40 0
      cmd/generate/config/rules/adobe.go
  4. 23 0
      cmd/generate/config/rules/age.go
  5. 42 0
      cmd/generate/config/rules/alibaba.go
  6. 38 0
      cmd/generate/config/rules/asana.go
  7. 22 0
      cmd/generate/config/rules/atlassian.go
  8. 31 0
      cmd/generate/config/rules/aws.go
  9. 23 0
      cmd/generate/config/rules/beamer.go
  10. 39 0
      cmd/generate/config/rules/bitbucket.go
  11. 23 0
      cmd/generate/config/rules/clojars.go
  12. 45 0
      cmd/generate/config/rules/config.tmpl
  13. 23 0
      cmd/generate/config/rules/contentful.go
  14. 23 0
      cmd/generate/config/rules/databricks.go
  15. 56 0
      cmd/generate/config/rules/discord.go
  16. 26 0
      cmd/generate/config/rules/doppler.go
  17. 48 0
      cmd/generate/config/rules/dropbox.go
  18. 23 0
      cmd/generate/config/rules/duffel.go
  19. 23 0
      cmd/generate/config/rules/dynatrace.go
  20. 39 0
      cmd/generate/config/rules/easypost.go
  21. 21 0
      cmd/generate/config/rules/facebook.go
  22. 22 0
      cmd/generate/config/rules/fastly.go
  23. 50 0
      cmd/generate/config/rules/finicity.go
  24. 55 0
      cmd/generate/config/rules/flutterwave.go
  25. 23 0
      cmd/generate/config/rules/frameio.go
  26. 24 0
      cmd/generate/config/rules/gcp.go
  27. 41 0
      cmd/generate/config/rules/generic.go
  28. 63 0
      cmd/generate/config/rules/github.go
  29. 21 0
      cmd/generate/config/rules/gitlab.go
  30. 24 0
      cmd/generate/config/rules/gocardless.go
  31. 23 0
      cmd/generate/config/rules/hashicorp.go
  32. 23 0
      cmd/generate/config/rules/heroku.go
  33. 23 0
      cmd/generate/config/rules/hubspot.go
  34. 22 0
      cmd/generate/config/rules/intercom.go
  35. 39 0
      cmd/generate/config/rules/linear.go
  36. 51 0
      cmd/generate/config/rules/linkedin.go
  37. 44 0
      cmd/generate/config/rules/lob.go
  38. 24 0
      cmd/generate/config/rules/mailchimp.go
  39. 81 0
      cmd/generate/config/rules/mailgun.go
  40. 22 0
      cmd/generate/config/rules/mapbox.go
  41. 57 0
      cmd/generate/config/rules/messagebird.go
  42. 76 0
      cmd/generate/config/rules/newrelic.go
  43. 24 0
      cmd/generate/config/rules/npm.go
  44. 43 0
      cmd/generate/config/rules/planetscale.go
  45. 24 0
      cmd/generate/config/rules/postman.go
  46. 23 0
      cmd/generate/config/rules/privatekey.go
  47. 24 0
      cmd/generate/config/rules/pulumi.go
  48. 36 0
      cmd/generate/config/rules/pypi.go
  49. 24 0
      cmd/generate/config/rules/rubygems.go
  50. 133 0
      cmd/generate/config/rules/rule.go
  51. 24 0
      cmd/generate/config/rules/sendgrid.go
  52. 24 0
      cmd/generate/config/rules/sendinblue.go
  53. 25 0
      cmd/generate/config/rules/shippo.go
  54. 98 0
      cmd/generate/config/rules/shopify.go
  55. 49 0
      cmd/generate/config/rules/slack.go
  56. 37 0
      cmd/generate/config/rules/stripe.go
  57. 34 0
      cmd/generate/config/rules/twilio.go
  58. 24 0
      cmd/generate/config/rules/twitch.go
  59. 35 0
      cmd/generate/config/rules/twitter.go
  60. 25 0
      cmd/generate/config/rules/typeform.go
  61. 514 443
      config/gitleaks.toml
  62. 2 3
      detect/detect.go

+ 3 - 0
.gitignore

@@ -9,7 +9,10 @@
 *.got
 gitleaks
 build
+
+# configs
 .gitleaks.toml
+cmd/generate/config/gitleaks.toml
 
 # Test binary
 *.out

+ 122 - 0
cmd/generate/config/main.go

@@ -0,0 +1,122 @@
+package main
+
+import (
+	"os"
+	"text/template"
+
+	"github.com/rs/zerolog/log"
+
+	"github.com/zricethezav/gitleaks/v8/cmd/generate/config/rules"
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+const (
+	templatePath = "rules/config.tmpl"
+)
+
+func main() {
+	configRules := []*config.Rule{}
+	configRules = append(configRules, rules.AgeSecretKey())
+	configRules = append(configRules, rules.AdobeClientID())
+	configRules = append(configRules, rules.AdobeClientSecret())
+	configRules = append(configRules, rules.AlibabaAccessKey())
+	configRules = append(configRules, rules.AlibabaSecretKey())
+	configRules = append(configRules, rules.AsanaClientID())
+	configRules = append(configRules, rules.AsanaClientSecret())
+	configRules = append(configRules, rules.Atlassian())
+	configRules = append(configRules, rules.AWS())
+	configRules = append(configRules, rules.BitBucketClientID())
+	configRules = append(configRules, rules.BitBucketClientSecret())
+	configRules = append(configRules, rules.Beamer())
+	configRules = append(configRules, rules.Clojars())
+	configRules = append(configRules, rules.Contentful())
+	configRules = append(configRules, rules.Databricks())
+	configRules = append(configRules, rules.DiscordAPIToken())
+	configRules = append(configRules, rules.DiscordClientID())
+	configRules = append(configRules, rules.DiscordClientSecret())
+	configRules = append(configRules, rules.DropBoxAPISecret())
+	configRules = append(configRules, rules.DropBoxLongLivedAPIToken())
+	configRules = append(configRules, rules.DropBoxShortLivedAPIToken())
+	configRules = append(configRules, rules.Doppler())
+	configRules = append(configRules, rules.Duffel())
+	configRules = append(configRules, rules.Dynatrace())
+	configRules = append(configRules, rules.EasyPost())
+	configRules = append(configRules, rules.EasyPostTestAPI())
+	configRules = append(configRules, rules.Facebook())
+	configRules = append(configRules, rules.FastlyAPIToken())
+	configRules = append(configRules, rules.FinicityClientSecret())
+	configRules = append(configRules, rules.FinicityAPIToken())
+	configRules = append(configRules, rules.FlutterwavePublicKey())
+	configRules = append(configRules, rules.FlutterwaveSecretKey())
+	configRules = append(configRules, rules.FlutterwaveSecretKey())
+	configRules = append(configRules, rules.FrameIO())
+	configRules = append(configRules, rules.GenericCredential())
+	configRules = append(configRules, rules.GoCardless())
+	// TODO figure out what makes sense for GCP
+	// configRules = append(configRules, rules.GCPServiceAccount())
+	configRules = append(configRules, rules.GitHubPat())
+	configRules = append(configRules, rules.GitHubOauth())
+	configRules = append(configRules, rules.GitHubApp())
+	configRules = append(configRules, rules.GitHubRefresh())
+	configRules = append(configRules, rules.Gitlab())
+	configRules = append(configRules, rules.Hashicorp())
+	configRules = append(configRules, rules.Heroku())
+	configRules = append(configRules, rules.HubSpot())
+	configRules = append(configRules, rules.Intercom())
+	configRules = append(configRules, rules.LinearAPIToken())
+	configRules = append(configRules, rules.LinearClientSecret())
+	configRules = append(configRules, rules.LinkedinClientID())
+	configRules = append(configRules, rules.LinkedinClientSecret())
+	configRules = append(configRules, rules.LobAPIToken())
+	configRules = append(configRules, rules.LobPubAPIToken())
+	configRules = append(configRules, rules.MailChimp())
+	configRules = append(configRules, rules.MailGunPubAPIToken())
+	configRules = append(configRules, rules.MailGunPrivateAPIToken())
+	configRules = append(configRules, rules.MailGunSigningKey())
+	configRules = append(configRules, rules.MapBox())
+	configRules = append(configRules, rules.MessageBirdAPIToken())
+	configRules = append(configRules, rules.MessageBirdClientID())
+	configRules = append(configRules, rules.NewRelicUserID())
+	configRules = append(configRules, rules.NewRelicUserKey())
+	configRules = append(configRules, rules.NewRelicBrowserAPIKey())
+	configRules = append(configRules, rules.NPM())
+	configRules = append(configRules, rules.PlanetScalePassword())
+	configRules = append(configRules, rules.PlanetScaleToken())
+	configRules = append(configRules, rules.PostManAPI())
+	configRules = append(configRules, rules.PrivateKey())
+	configRules = append(configRules, rules.PulumiAPIToken())
+	configRules = append(configRules, rules.PyPiUploadToken())
+	configRules = append(configRules, rules.RubyGemsAPIToken())
+	configRules = append(configRules, rules.SendGridAPIToken())
+	configRules = append(configRules, rules.SendInBlueAPIToken())
+	configRules = append(configRules, rules.ShippoAPIToken())
+	configRules = append(configRules, rules.ShopifyAccessToken())
+	configRules = append(configRules, rules.ShopifyCustomAccessToken())
+	configRules = append(configRules, rules.ShopifyPrivateAppAccessToken())
+	configRules = append(configRules, rules.ShopifySharedSecret())
+	configRules = append(configRules, rules.SlackAccessToken())
+	configRules = append(configRules, rules.SlackWebHook())
+	configRules = append(configRules, rules.StripeAccessToken())
+	configRules = append(configRules, rules.Twilio())
+	configRules = append(configRules, rules.TwitchAPIToken())
+	configRules = append(configRules, rules.Twitter())
+	configRules = append(configRules, rules.Typeform())
+
+	config := config.Config{
+		Rules: configRules,
+	}
+	tmpl, err := template.ParseFiles(templatePath)
+	if err != nil {
+		log.Fatal().Err(err).Msg("Failed to parse template")
+	}
+
+	f, err := os.Create("gitleaks.toml")
+	if err != nil {
+		log.Fatal().Err(err).Msg("Failed to create rules.toml")
+	}
+	tmpl.Execute(f, config)
+
+}
+
+// TODO introduce skiplists:
+// https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/wordlist-skipfish.fuzz.txt

+ 40 - 0
cmd/generate/config/rules/adobe.go

@@ -0,0 +1,40 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func AdobeClientID() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Adobe Client ID (Oauth Web)",
+		RuleID:      "adobe-client-id",
+		Regex:       generateSemiGenericRegex([]string{"adobe"}, hex32),
+		SecretGroup: 1,
+		Keywords:    []string{"adobe"},
+	}
+
+	// validate
+	tps := []string{
+		"adobeClient := \"" + sampleHex32Token + "\"",
+	}
+	return validate(r, tps)
+}
+
+func AdobeClientSecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Adobe Client Secret",
+		RuleID:      "adobe-client-secret",
+		Regex:       regexp.MustCompile(`(p8e-)(?i)[a-z0-9]{32}`),
+		Keywords:    []string{"p8e-"},
+	}
+
+	// validate
+	tps := []string{
+		"adobeClient := \"p8e-" + sampleHex32Token + "\"",
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/age.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func AgeSecretKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Age secret key",
+		RuleID:      "age secret key",
+		Regex:       regexp.MustCompile(`AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}`),
+		Keywords:    []string{"AGE-SECRET-KEY-1"},
+	}
+
+	// validate
+	tps := []string{
+		`apiKey := "AGE-SECRET-KEY-1QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ`, // gitleaks:allow
+	}
+	return validate(r, tps)
+}

+ 42 - 0
cmd/generate/config/rules/alibaba.go

@@ -0,0 +1,42 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func AlibabaAccessKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Alibaba AccessKey ID",
+		RuleID:      "alibaba-access-key-id",
+		Regex:       regexp.MustCompile(`(LTAI)(?i)[a-z0-9]{20}`),
+		Keywords:    []string{"LTAI"},
+	}
+
+	// validate
+	tps := []string{
+		"alibabaKey := \"LTAI" + sampleHex20Token + "\"",
+	}
+	return validate(r, tps)
+}
+
+// TODO
+func AlibabaSecretKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Alibaba Secret Key",
+		RuleID:      "alibaba-secret-key",
+		Regex: generateSemiGenericRegex([]string{"alibaba"},
+			alphaNumeric30),
+		SecretGroup: 1,
+		Keywords:    []string{"alibaba"},
+	}
+
+	// validate
+	tps := []string{
+		"alibabaSecret Key:= \"" + sampleAlphaNumeric30Token + "\"",
+	}
+	return validate(r, tps)
+}

+ 38 - 0
cmd/generate/config/rules/asana.go

@@ -0,0 +1,38 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func AsanaClientID() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Asana Client ID",
+		RuleID:      "asana-client-id",
+		Regex:       generateSemiGenericRegex([]string{"asana"}, numeric16),
+		SecretGroup: 1,
+		Keywords:    []string{"asana"},
+	}
+
+	// validate
+	tps := []string{
+		"asanaKey := \"" + sampleNumeric16 + "\"",
+	}
+	return validate(r, tps)
+}
+
+func AsanaClientSecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Asana Client Secret",
+		RuleID:      "asana-client-secret",
+		Regex:       generateSemiGenericRegex([]string{"asana"}, alphaNumeric32),
+		Keywords:    []string{"asana"},
+	}
+
+	// validate
+	tps := []string{
+		"asanaKey := \"" + sampleAlphaNumeric32Token + "\"",
+	}
+	return validate(r, tps)
+}

+ 22 - 0
cmd/generate/config/rules/atlassian.go

@@ -0,0 +1,22 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Atlassian() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Atlassian API token",
+		RuleID:      "atlassian-api-token",
+		Regex:       generateSemiGenericRegex([]string{"atlassian"}, alphaNumeric24),
+		SecretGroup: 1,
+		Keywords:    []string{"atlassian"},
+	}
+
+	// validate
+	tps := []string{
+		"atlassian:= \"" + sampleAlphaNumeric24Token + "\"",
+	}
+	return validate(r, tps)
+}

+ 31 - 0
cmd/generate/config/rules/aws.go

@@ -0,0 +1,31 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func AWS() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "AWS",
+		RuleID:      "aws-access-token",
+		Regex: regexp.MustCompile(
+			"(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"),
+		Keywords: []string{
+			"AKIA",
+			"AGPA",
+			"AIDA",
+			"AROA",
+			"AIPA",
+			"ANPA",
+			"ANVA",
+			"ASIA",
+		},
+	}
+
+	// validate
+	tps := []string{"AWSToken := \"" + "AKIALALEMEL33243OLIB" + "\""} // gitleaks:allow
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/beamer.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Beamer() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Beamer API token",
+		RuleID:      "beamer-api-token",
+		SecretGroup: 1,
+		Regex: generateSemiGenericRegex([]string{"beamer"},
+			`b_[a-z0-9=_\-]{44}`),
+		Keywords: []string{"beamer"},
+	}
+
+	// validate
+	tps := []string{
+		"beamer := \"b_" + sampleAlphaNumeric32Token + "-_=_xxxxxxxx\"",
+	}
+	return validate(r, tps)
+}

+ 39 - 0
cmd/generate/config/rules/bitbucket.go

@@ -0,0 +1,39 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func BitBucketClientID() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "BitBucket Client ID",
+		RuleID:      "bitbucket-client-id",
+		Regex:       generateSemiGenericRegex([]string{"bitbucket"}, alphaNumeric32),
+		SecretGroup: 1,
+		Keywords:    []string{"bitbucket"},
+	}
+
+	// validate
+	tps := []string{
+		"bitbucket := \"" + sampleAlphaNumeric32Token + "\"",
+	}
+	return validate(r, tps)
+}
+
+func BitBucketClientSecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "BitBucket Client Secret",
+		RuleID:      "bitbucket-client-secret",
+		Regex:       generateSemiGenericRegex([]string{"bitbucket"}, extendedAlphaNumeric64),
+		SecretGroup: 1,
+		Keywords:    []string{"bitbucket"},
+	}
+
+	// validate
+	tps := []string{
+		"bitbucket := \"" + sampleExtendedAlphaNumeric64Token + "\"",
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/clojars.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Clojars() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Clojars API token",
+		RuleID:      "clojars-api-token",
+		Regex:       regexp.MustCompile(`(CLOJARS_)(?i)[a-z0-9]{60}`),
+		Keywords:    []string{"clojars"},
+	}
+
+	// validate
+	tps := []string{
+		"clojarsAPIToken := \"CLOJARS_" + sampleAlphaNumeric60Token + "\"",
+	}
+	return validate(r, tps)
+}

+ 45 - 0
cmd/generate/config/rules/config.tmpl

@@ -0,0 +1,45 @@
+# This is the default gitleaks configuration file.
+# Rules and allowlists are defined within this file.
+# Rules instruct gitleaks on what should be considered a secret.
+# Allowlists instruct gitleaks on what is allowed, i.e. not a secret.
+title = "gitleaks config"
+
+[allowlist]
+description = "global allow lists"
+regexes = [
+    '''219-09-9999''',
+    '''078-05-1120''',
+    '''(9[0-9]{2}|666)-\d{2}-\d{4}''',
+    ]
+paths = [
+    '''gitleaks.toml''',
+    '''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''',
+    '''(go.mod|go.sum)$'''
+]
+
+{{ range $i, $rule := .Rules }}[[rules]]
+{{ if and $rule.SecretGroup $rule.Entropy }}description = "{{$rule.Description}}"
+id = "{{$rule.RuleID}}"
+regex = '''{{$rule.Regex}}'''
+secretGroup = {{ $rule.SecretGroup }}
+entropy = {{ $rule.Entropy}}
+keywords = [
+    {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}}
+]
+
+{{ else if $rule.SecretGroup }}description = "{{$rule.Description}}"
+id = "{{$rule.RuleID}}"
+regex = '''{{$rule.Regex}}'''
+secretGroup = {{ $rule.SecretGroup }}
+keywords = [
+    {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}}
+]
+
+{{ else }}description = "{{$rule.Description}}"
+id = "{{$rule.RuleID}}"
+regex = '''{{$rule.Regex}}'''
+keywords = [
+    {{ range $j, $keyword := $rule.Keywords }}"{{$keyword}}",{{end}}
+]
+
+{{end}}{{end}}

+ 23 - 0
cmd/generate/config/rules/contentful.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Contentful() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Contentful delivery API token",
+		RuleID:      "contentful-delivery-api-token",
+		Regex: generateSemiGenericRegex([]string{"contentful"},
+			`[a-z0-9\-=_]{43}`),
+		SecretGroup: 1,
+		Keywords:    []string{"contentful"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("contentful", sampleExtendedAlphaNumeric43Token),
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/databricks.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Databricks() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Databricks API token",
+		RuleID:      "databricks-api-token",
+		Regex:       regexp.MustCompile(`dapi[a-h0-9]{32}`),
+		Keywords:    []string{"dapi"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("databricks", "dapi"+sampleHex32Token),
+	}
+	return validate(r, tps)
+}

+ 56 - 0
cmd/generate/config/rules/discord.go

@@ -0,0 +1,56 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func DiscordAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Discord API key",
+		RuleID:      "discord-api-token",
+		Regex:       generateSemiGenericRegex([]string{"discord"}, hex64),
+		SecretGroup: 1,
+		Keywords:    []string{"discord"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("discord", sampleHex64Token),
+	}
+	return validate(r, tps)
+}
+
+func DiscordClientID() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Discord client ID",
+		RuleID:      "discord-client-id",
+		Regex:       generateSemiGenericRegex([]string{"discord"}, numeric18),
+		SecretGroup: 1,
+		Keywords:    []string{"discord"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("discord", sampleNumeric18),
+	}
+	return validate(r, tps)
+}
+
+func DiscordClientSecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Discord client secret",
+		RuleID:      "discord-client-secret",
+		Regex:       generateSemiGenericRegex([]string{"discord"}, extendedAlphaNumeric32),
+		SecretGroup: 1,
+		Keywords:    []string{"discord"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("discord", sampleExtendedAlphaNumeric32Token),
+	}
+	return validate(r, tps)
+}

+ 26 - 0
cmd/generate/config/rules/doppler.go

@@ -0,0 +1,26 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Doppler() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Doppler API token",
+		RuleID:      "doppler-api-token",
+		Regex:       regexp.MustCompile(`(dp\.pt\.)(?i)[a-z0-9]{43}`),
+		Keywords:    []string{"doppler"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("doppler", "dp.pt."+sampleAlphaNumeric43Token),
+	}
+	return validate(r, tps)
+}
+
+// TODO add additional doppler formats:
+// https://docs.doppler.com/reference/auth-token-formats

+ 48 - 0
cmd/generate/config/rules/dropbox.go

@@ -0,0 +1,48 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func DropBoxAPISecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Dropbox API secret",
+		RuleID:      "doppler-api-token",
+		Regex:       generateSemiGenericRegex([]string{"dropbox"}, alphaNumeric15),
+		SecretGroup: 1,
+		Keywords:    []string{"dropbox"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("dropbox", sampleAlphaNumeric15Token),
+	}
+	return validate(r, tps)
+}
+
+func DropBoxShortLivedAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "dropbox-short-lived-api-token",
+		Description: "Dropbox short lived API token",
+		Regex:       generateSemiGenericRegex([]string{"dropbox"}, `sl\.[a-z0-9\-=_]{135}`),
+		Keywords:    []string{"dropbox"},
+	}
+
+	// validate TODO
+	return &r
+}
+
+func DropBoxLongLivedAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "dropbox-long-lived-api-token",
+		Description: "Dropbox long lived API token",
+		Regex:       generateSemiGenericRegex([]string{"dropbox"}, `[a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43}`),
+		Keywords:    []string{"dropbox"},
+	}
+
+	// validate TODO
+	return &r
+}

+ 23 - 0
cmd/generate/config/rules/duffel.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Duffel() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "duffel-api-token",
+		Description: "Duffel API token",
+		Regex:       regexp.MustCompile(`duffel_(test|live)_(?i)[a-z0-9_\-=]{43}`),
+		Keywords:    []string{"duffel"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("duffel", "duffel_test_"+sampleExtendedAlphaNumeric43Token),
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/dynatrace.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Dynatrace() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Dynatrace API token",
+		RuleID:      "dynatrace-api-token",
+		Regex:       regexp.MustCompile(`dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}`),
+		Keywords:    []string{"dynatrace"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("dynatrace", "dt0c01."+sampleAlphaNumeric24Token+"."+sampleAlphaNumeric64Token),
+	}
+	return validate(r, tps)
+}

+ 39 - 0
cmd/generate/config/rules/easypost.go

@@ -0,0 +1,39 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func EasyPost() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "EasyPost API token",
+		RuleID:      "easypost-api-token",
+		Regex:       regexp.MustCompile(`EZAK(?i)[a-z0-9]{54}`),
+		Keywords:    []string{"EZAK"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("EZAK", "EZAK"+sampleAlphaNumeric54Token),
+	}
+	return validate(r, tps)
+}
+
+func EasyPostTestAPI() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "EasyPost test API token",
+		RuleID:      "easypost-test-api-token",
+		Regex:       regexp.MustCompile(`EZTK(?i)[a-z0-9]{54}`),
+		Keywords:    []string{"EZTK"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("EZTK", "EZTK"+sampleAlphaNumeric54Token),
+	}
+	return validate(r, tps)
+}

+ 21 - 0
cmd/generate/config/rules/facebook.go

@@ -0,0 +1,21 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Facebook() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "facebook",
+		RuleID:      "facebook",
+		Regex: generateSemiGenericRegex([]string{"facebook"},
+			hex32),
+		SecretGroup: 1,
+		Keywords:    []string{"facebook"},
+	}
+
+	// validate
+	tps := []string{"facebookToken := \"" + sampleHex32Token + "\""}
+	return validate(r, tps)
+}

+ 22 - 0
cmd/generate/config/rules/fastly.go

@@ -0,0 +1,22 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func FastlyAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Fastly API key",
+		RuleID:      "fastly-api-token",
+		Regex:       generateSemiGenericRegex([]string{"fastly"}, extendedAlphaNumeric32),
+		SecretGroup: 1,
+		Keywords:    []string{"fastly"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("fastly", sampleExtendedAlphaNumeric32Token),
+	}
+	return validate(r, tps)
+}

+ 50 - 0
cmd/generate/config/rules/finicity.go

@@ -0,0 +1,50 @@
+package rules
+
+import (
+	"github.com/rs/zerolog/log"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+	"github.com/zricethezav/gitleaks/v8/detect"
+)
+
+func FinicityClientSecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Finicity Client Secret",
+		RuleID:      "finicity-client-secret",
+		Regex:       generateSemiGenericRegex([]string{"finicity"}, alphaNumeric20),
+		SecretGroup: 1,
+		Keywords:    []string{"finicity"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("finicity", sampleAlphaNumeric20Token),
+	}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate finicity-client-secret")
+		}
+	}
+	return &r
+}
+
+func FinicityAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Finicity API token",
+		RuleID:      "finicity-api-token",
+		Regex:       generateSemiGenericRegex([]string{"finicity"}, hex32),
+		SecretGroup: 1,
+		Keywords:    []string{"finicity"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("finicity", sampleHex32Token),
+	}
+	return validate(r, tps)
+}

+ 55 - 0
cmd/generate/config/rules/flutterwave.go

@@ -0,0 +1,55 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func FlutterwavePublicKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Finicity Public Key",
+		RuleID:      "flutterwave-public-key",
+		Regex:       regexp.MustCompile(`FLWPUBK_TEST-(?i)[a-h0-9]{32}-X`),
+		Keywords:    []string{"FLWPUBK_TEST"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("flutterwavePubKey", "FLWPUBK_TEST-"+sampleHex32Token+"-X"),
+	}
+	return validate(r, tps)
+}
+
+func FlutterwaveSecretKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Finicity Secret Key",
+		RuleID:      "flutterwave-public-key",
+		Regex:       regexp.MustCompile(`FLWSECK_TEST-(?i)[a-h0-9]{32}-X`),
+		Keywords:    []string{"FLWSECK_TEST"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("flutterwavePubKey", "FLWSECK_TEST-"+sampleHex32Token+"-X"),
+	}
+	return validate(r, tps)
+}
+
+func FlutterwaveEncKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Finicity Secret Key",
+		RuleID:      "flutterwave-public-key",
+		Regex:       regexp.MustCompile(`FLWSECK_TEST-(?i)[a-h0-9]{12}`),
+		Keywords:    []string{"FLWSECK_TEST"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("flutterwavePubKey", "FLWSECK_TEST-"+sampleHex12Token),
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/frameio.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func FrameIO() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Frame.io API token",
+		RuleID:      "frameio-api-token",
+		Regex:       regexp.MustCompile(`fio-u-(?i)[a-z0-9\-_=]{64}`),
+		Keywords:    []string{"fio-u-"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("frameio", "fio-u-"+sampleExtendedAlphaNumeric64Token),
+	}
+	return validate(r, tps)
+}

+ 24 - 0
cmd/generate/config/rules/gcp.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+// TODO this one could probably use some work
+func GCPServiceAccount() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Google (GCP) Service-account",
+		RuleID:      "gcp-service-account",
+		Regex:       regexp.MustCompile(`\"type\": \"service_account\"`),
+		Keywords:    []string{`\"type\": \"service_account\"`},
+	}
+
+	// validate
+	tps := []string{
+		`"type": "service_account"`,
+	}
+	return validate(r, tps)
+}

+ 41 - 0
cmd/generate/config/rules/generic.go

@@ -0,0 +1,41 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func GenericCredential() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "generic-api-key",
+		Description: "Generic API Key",
+		Regex: generateSemiGenericRegex([]string{
+			"key",
+			"api[^Version]",
+			"token",
+			"pat",
+			"secret",
+			"client",
+			"password",
+			"auth",
+		}, `[0-9a-z\-_.=]{10,150}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"key",
+			"api",
+			"token",
+			"secret",
+			"client",
+			"pat",
+			"password",
+			"auth",
+		},
+		Entropy: 3.7,
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("generic", "8dyfuiRyq=vVc3RRr_edRk-fK__JItpZ"),
+	}
+	return validate(r, tps)
+}

+ 63 - 0
cmd/generate/config/rules/github.go

@@ -0,0 +1,63 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func GitHubPat() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "GitHub Personal Access Token",
+		RuleID:      "github-pat",
+		Regex:       regexp.MustCompile(`ghp_[0-9a-zA-Z]{36}`),
+		Keywords:    []string{"ghp_"},
+	}
+
+	// validate
+	tps := []string{"gihubPAT := \"ghp_" + sampleAlphaNumeric36Token + "\""}
+	return validate(r, tps)
+}
+
+func GitHubOauth() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "GitHub OAuth Access Token",
+		RuleID:      "github-oauth",
+		Regex:       regexp.MustCompile(`gho_[0-9a-zA-Z]{36}`),
+		Keywords:    []string{"gho_"},
+	}
+
+	// validate
+	tps := []string{"gihubAuth := \"gho_" + sampleAlphaNumeric36Token + "\""}
+	return validate(r, tps)
+}
+
+func GitHubApp() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "GitHub App Token",
+		RuleID:      "github-app-token",
+		Regex:       regexp.MustCompile(`(ghu|ghs)_[0-9a-zA-Z]{36}`),
+		Keywords:    []string{"ghu_", "ghs_"},
+	}
+
+	// validate
+	tps := []string{"gihubAuth := \"ghs_" + sampleAlphaNumeric36Token + "\""}
+	return validate(r, tps)
+}
+
+func GitHubRefresh() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "GitHub Refresh Token",
+		RuleID:      "github-refresh-token",
+		Regex:       regexp.MustCompile(`ghr_[0-9a-zA-Z]{36}`),
+		Keywords:    []string{"ghr_"},
+	}
+
+	// validate
+	tps := []string{"gihubAuth := \"ghr_" + sampleAlphaNumeric36Token + "\""}
+	return validate(r, tps)
+}

+ 21 - 0
cmd/generate/config/rules/gitlab.go

@@ -0,0 +1,21 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Gitlab() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Gitlab Personal Access Token",
+		RuleID:      "gitlab-pat",
+		Regex:       regexp.MustCompile(`glpat-[0-9a-zA-Z\-\_]{20}`),
+		Keywords:    []string{"glpat-"},
+	}
+
+	// validate
+	tps := []string{"gitlabPAT := \"glpat-" + sampleAlphaNumeric20Token + "\""}
+	return validate(r, tps)
+}

+ 24 - 0
cmd/generate/config/rules/gocardless.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func GoCardless() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "gocardless-api-token",
+		Description: "GoCardless API token",
+		Regex:       generateSemiGenericRegex([]string{"gocardless"}, `live_(?i)[a-z0-9\-_=]{40}`),
+		Keywords: []string{
+			"live_",
+			"gocardless",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("gocardless", "live_"+sampleExtendedAlphaNumeric40Token),
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/hashicorp.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Hashicorp() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "HashiCorp Terraform user/org API token",
+		RuleID:      "hashicorp-tf-api-token",
+		Regex:       regexp.MustCompile(`(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}`),
+		Keywords:    []string{"atlasv1"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("hashicorpToken", sampleHex14Token+".atlasv1."+sampleExtendedAlphaNumeric64Token),
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/heroku.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Heroku() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Heroku API Key",
+		RuleID:      "heroku-api-key",
+		Regex: generateSemiGenericRegex([]string{"heroku"},
+			`[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}`),
+		SecretGroup: 1,
+		Keywords:    []string{"heroku"},
+	}
+
+	// validate
+	tps := []string{
+		`const HEROKU_KEY = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/hubspot.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func HubSpot() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "HubSpot API Token",
+		RuleID:      "hubspot-api-key",
+		Regex: generateSemiGenericRegex([]string{"hubspot"},
+			`[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}`),
+		SecretGroup: 1,
+		Keywords:    []string{"hubspot"},
+	}
+
+	// validate
+	tps := []string{
+		`const hubspotKey = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow
+	}
+	return validate(r, tps)
+}

+ 22 - 0
cmd/generate/config/rules/intercom.go

@@ -0,0 +1,22 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Intercom() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Intercom API Token",
+		RuleID:      "intercom-api-key",
+		Regex:       generateSemiGenericRegex([]string{"intercom"}, extendedAlphaNumeric60),
+		SecretGroup: 1,
+		Keywords:    []string{"intercom"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("intercom", sampleExtendedAlphaNumeric60Token),
+	}
+	return validate(r, tps)
+}

+ 39 - 0
cmd/generate/config/rules/linear.go

@@ -0,0 +1,39 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func LinearAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Linear API Token",
+		RuleID:      "linear-api-key",
+		Regex:       regexp.MustCompile(`lin_api_(?i)[a-z0-9]{40}`),
+		Keywords:    []string{"lin_api_"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("linear", "lin_api_"+sampleAlphaNumeric40Token),
+	}
+	return validate(r, tps)
+}
+
+func LinearClientSecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Linear Client Secret",
+		RuleID:      "linear-client-secret",
+		Regex:       generateSemiGenericRegex([]string{"linear"}, hex32),
+		Keywords:    []string{"linear"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("linear", sampleHex32Token),
+	}
+	return validate(r, tps)
+}

+ 51 - 0
cmd/generate/config/rules/linkedin.go

@@ -0,0 +1,51 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func LinkedinClientSecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "linkedin-client-secret",
+		Description: "LinkedIn Client secret",
+		Regex: generateSemiGenericRegex([]string{
+			"linkedin",
+			"linked-in",
+		}, alphaNumeric16),
+		SecretGroup: 1,
+		Keywords: []string{
+			"linkedin",
+			"linked-in",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("linkedin", sampleAlphaNumeric16Token),
+	}
+	return validate(r, tps)
+}
+
+func LinkedinClientID() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "linkedin-client-id",
+		Description: "LinkedIn Client ID",
+		Regex: generateSemiGenericRegex([]string{
+			"linkedin",
+			"linked-in",
+		}, alphaNumeric14),
+		SecretGroup: 1,
+		Keywords: []string{
+			"linkedin",
+			"linked-in",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("linkedin", sampleAlphaNumeric14Token),
+	}
+	return validate(r, tps)
+}

+ 44 - 0
cmd/generate/config/rules/lob.go

@@ -0,0 +1,44 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func LobPubAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Lob Publishable API Key",
+		RuleID:      "lob-pub-api-key",
+		Regex:       generateSemiGenericRegex([]string{"lob"}, `(test|live)_pub_[a-f0-9]{31}`),
+		Keywords: []string{
+			"test_pub",
+			"live_pub",
+			"_pub",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("lob", "test_pub_"+sampleHex31Token),
+	}
+	return validate(r, tps)
+}
+
+func LobAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Lob API Key",
+		RuleID:      "lob-api-key",
+		Regex:       generateSemiGenericRegex([]string{"lob"}, `(live|test)_[a-f0-9]{35}`),
+		Keywords: []string{
+			"test_",
+			"live_",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("lob", "test_"+sampleHex35Token),
+	}
+	return validate(r, tps)
+}

+ 24 - 0
cmd/generate/config/rules/mailchimp.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func MailChimp() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "mailchimp-api-key",
+		Description: "Mailchimp API key",
+		Regex:       generateSemiGenericRegex([]string{"mailchimp"}, `[a-f0-9]{32}-us20`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"mailchimp",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("mailchimp", sampleHex32Token+"-us20"),
+	}
+	return validate(r, tps)
+}

+ 81 - 0
cmd/generate/config/rules/mailgun.go

@@ -0,0 +1,81 @@
+package rules
+
+import (
+	"github.com/rs/zerolog/log"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+	"github.com/zricethezav/gitleaks/v8/detect"
+)
+
+func MailGunPrivateAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "mailgun-private-api-token",
+		Description: "Mailgun private API token",
+		Regex:       generateSemiGenericRegex([]string{"mailgun"}, `key-[a-f0-9]{32}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"mailgun",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("mailgun", "key-"+sampleHex32Token),
+	}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate mailgun-private-api-token")
+		}
+	}
+	return &r
+}
+
+func MailGunPubAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "mailgun-pub-key",
+		Description: "Mailgun public validation key",
+		Regex:       generateSemiGenericRegex([]string{"mailgun"}, `pubkey-[a-f0-9]{32}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"mailgun",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("mailgun", "pubkey-"+sampleHex32Token),
+	}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate mailgun-pub-key")
+		}
+	}
+	return &r
+}
+
+func MailGunSigningKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "mailgun-signing-key",
+		Description: "Mailgun webhook signing key",
+		Regex:       generateSemiGenericRegex([]string{"mailgun"}, `[a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"mailgun",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("mailgun", sampleHex32Token+"-00001111-22223333"),
+	}
+	return validate(r, tps)
+}

+ 22 - 0
cmd/generate/config/rules/mapbox.go

@@ -0,0 +1,22 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func MapBox() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "MapBox API token",
+		RuleID:      "mapbox-api-token",
+		Regex:       generateSemiGenericRegex([]string{"mapbox"}, `pk\.[a-z0-9]{60}\.[a-z0-9]{22}`),
+		SecretGroup: 1,
+		Keywords:    []string{"mapbox"},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("mapbox", "pk."+sampleAlphaNumeric60Token+"."+sampleAlphaNumeric22Token),
+	}
+	return validate(r, tps)
+}

+ 57 - 0
cmd/generate/config/rules/messagebird.go

@@ -0,0 +1,57 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func MessageBirdAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "MessageBird API token",
+		RuleID:      "messagebird-api-token",
+		Regex: generateSemiGenericRegex([]string{
+			"messagebird",
+			"message-bird",
+			"message_bird",
+		}, alphaNumeric25),
+		SecretGroup: 1,
+		Keywords: []string{
+			"messagebird",
+			"message-bird",
+			"message_bird",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("messagebird", sampleAlphaNumeric25Token),
+		generateSampleSecret("message-bird", sampleAlphaNumeric25Token),
+		generateSampleSecret("message_bird", sampleAlphaNumeric25Token),
+	}
+	return validate(r, tps)
+}
+
+func MessageBirdClientID() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "MessageBird client ID",
+		RuleID:      "messagebird-client-id",
+		Regex: generateSemiGenericRegex([]string{
+			"messagebird",
+			"message-bird",
+			"message_bird",
+		}, `[a-h0-9]{8}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{12}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"messagebird",
+			"message-bird",
+			"message_bird",
+		},
+	}
+
+	// validate
+	tps := []string{
+		`const MessageBirdClientID = "12345678-ABCD-ABCD-ABCD-1234567890AB"`, // gitleaks:allow
+	}
+	return validate(r, tps)
+}

+ 76 - 0
cmd/generate/config/rules/newrelic.go

@@ -0,0 +1,76 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func NewRelicUserID() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "new-relic-user-api-key",
+		Description: "New Relic user API Key",
+		Regex: generateSemiGenericRegex([]string{
+			"new-relic",
+			"newrelic",
+			"new_relic",
+		}, `NRAK-[a-z0-9]{27}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"NRAK",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("new-relic", "NRAK-"+sampleAlphaNumeric27Token),
+	}
+	return validate(r, tps)
+}
+
+func NewRelicUserKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "new-relic-user-api-id",
+		Description: "New Relic user API ID",
+		Regex: generateSemiGenericRegex([]string{
+			"new-relic",
+			"newrelic",
+			"new_relic",
+		}, alphaNumeric64),
+		SecretGroup: 1,
+		Keywords: []string{
+			"new-relic",
+			"newrelic",
+			"new_relic",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("new-relic", sampleAlphaNumeric64Token),
+	}
+	return validate(r, tps)
+}
+
+func NewRelicBrowserAPIKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "new-relic-browser-api-token",
+		Description: "New Relic ingest browser API token",
+		Regex: generateSemiGenericRegex([]string{
+			"new-relic",
+			"newrelic",
+			"new_relic",
+		}, `NRJS-[a-f0-9]{19}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"NRJS-",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("new-relic", "NRJS-"+sampleHex19Token),
+	}
+	return validate(r, tps)
+}

+ 24 - 0
cmd/generate/config/rules/npm.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func NPM() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "npm-access-token",
+		Description: "npm access token",
+		Regex:       generateUniqueTokenRegex(`npm_[a-z0-9]{36}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"npm_",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("npmAccessToken", "npm_"+sampleAlphaNumeric36Token),
+	}
+	return validate(r, tps)
+}

+ 43 - 0
cmd/generate/config/rules/planetscale.go

@@ -0,0 +1,43 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func PlanetScalePassword() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "planetscale-password",
+		Description: "PlanetScale password",
+		Regex:       generateUniqueTokenRegex(`pscale_pw_(?i)[a-z0-9=\-_\.]{43}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"pscale_pw_",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("planetScalePassword", "pscale_pw_"+sampleExtendedAlphaNumeric43Token),
+	}
+	return validate(r, tps)
+}
+
+func PlanetScaleToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "planetscale-api-token",
+		Description: "PlanetScale API token",
+		Regex:       generateUniqueTokenRegex(`pscale_tkn_(?i)[a-z0-9=\-_\.]{43}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"pscale_tkn_",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("planetScalePassword", "pscale_tkn_"+sampleExtendedAlphaNumeric43Token),
+	}
+	return validate(r, tps)
+}

+ 24 - 0
cmd/generate/config/rules/postman.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func PostManAPI() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "postman-api-token",
+		Description: "Postman API token",
+		Regex:       generateUniqueTokenRegex(`PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"PMAK-",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("postmanAPItoken", "PMAK-"+sampleHex24Token+"-"+sampleHex34Token),
+	}
+	return validate(r, tps)
+}

+ 23 - 0
cmd/generate/config/rules/privatekey.go

@@ -0,0 +1,23 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func PrivateKey() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Private Key",
+		RuleID:      "private-key",
+		Regex:       regexp.MustCompile(`(?i)-----\s*?BEGIN[ A-Z0-9_-]*?PRIVATE KEY\s*?-----[\s\S]*?----\s*?END[ A-Z0-9_-]*? PRIVATE KEY\s*?-----`),
+		Keywords:    []string{"-----BEGIN PRIVATE"},
+	}
+
+	// validate
+	tps := []string{`-----BEGIN PRIVATE KEY-----
+anything
+-----END PRIVATE KEY-----`} // gitleaks:allow
+	return validate(r, tps)
+}

+ 24 - 0
cmd/generate/config/rules/pulumi.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func PulumiAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "pulumi-api-token",
+		Description: "Pulumi API token",
+		Regex:       generateUniqueTokenRegex(`pul-[a-f0-9]{40}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"pul-",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("pulumi-api-token", "pul-"+sampleHex40Token),
+	}
+	return validate(r, tps)
+}

+ 36 - 0
cmd/generate/config/rules/pypi.go

@@ -0,0 +1,36 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/rs/zerolog/log"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+	"github.com/zricethezav/gitleaks/v8/detect"
+)
+
+func PyPiUploadToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "PyPI upload token",
+		RuleID:      "pypi-upload-token",
+		Regex: regexp.MustCompile(
+			`pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}`),
+		Keywords: []string{
+			"pypi-AgEIcHlwaS5vcmc",
+		},
+	}
+
+	// validate
+	tps := []string{"pypiToken := \"pypi-AgEIcHlwaS5vcmc" + sampleHex32Token +
+		sampleHex32Token + "\""}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate pypi-upload-token")
+		}
+	}
+	return &r
+}

+ 24 - 0
cmd/generate/config/rules/rubygems.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func RubyGemsAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "rubygems-api-token",
+		Description: "Rubygem API token",
+		Regex:       generateUniqueTokenRegex(`rubygems_[a-f0-9]{48}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"rubygems_",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("rubygemsAPIToken", "rubygems_"+sampleHex48Token),
+	}
+	return validate(r, tps)
+}

+ 133 - 0
cmd/generate/config/rules/rule.go

@@ -0,0 +1,133 @@
+package rules
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+
+	"github.com/rs/zerolog/log"
+	"github.com/zricethezav/gitleaks/v8/config"
+	"github.com/zricethezav/gitleaks/v8/detect"
+)
+
+const (
+	// case insensitive prefix
+	caseInsensitive = `(?i)`
+
+	// identifier prefix (just an ignore group)
+	identifierPrefix = `(?:`
+	identifierSuffix = `)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}`
+
+	// commonly used assignment operators or function call
+	operator = `(?:=|>|:=|\|\|:|<=|=>|:)`
+
+	// boundaries for the secret
+	// \x60 = `
+	secretPrefixUnique = `\b(`
+	secretPrefix       = `(?:'|\"|\s|=|\x60){0,5}(`
+	secretSuffix       = `)['|\"|\n|\r|\s|\x60]`
+
+	// secret regexes
+	hex   = `[a-f0-9]`
+	hex32 = `[a-f0-9]{32}`
+	hex64 = `[a-f0-9]{64}`
+
+	alphaNumeric14 = `[a-z0-9]{14}`
+	alphaNumeric15 = `[a-z0-9]{15}`
+	alphaNumeric16 = `[a-z0-9]{16}`
+	alphaNumeric20 = `[a-z0-9]{20}`
+	alphaNumeric24 = `[a-z0-9]{24}`
+	alphaNumeric25 = `[a-z0-9]{25}`
+	alphaNumeric30 = `[a-z0-9]{30}`
+	alphaNumeric32 = `[a-z0-9]{32}`
+	alphaNumeric64 = `[a-z0-9]{64}`
+
+	numeric16 = `[0-9]{16}`
+	numeric18 = `[0-9]{18}`
+
+	extendedAlphaNumeric32 = `[a-z0-9=_\-]{32}`
+	extendedAlphaNumeric60 = `[a-z0-9_\-]{60}`
+	extendedAlphaNumeric64 = `[a-z0-9_\-]{64}`
+
+	// token examples
+	sampleHex12Token = `b0549eee7368`                                                     // gitleaks:allow
+	sampleHex14Token = `b0549eee7368aa`                                                   // gitleaks:allow
+	sampleHex16Token = `bbb0549eee7368aa`                                                 // gitleaks:allow
+	sampleHex19Token = `d0e94828b0549eee736`                                              // gitleaks:allow
+	sampleHex20Token = `d0e94828b0549eee7368`                                             // gitleaks:allow
+	sampleHex24Token = `d0e94828b0549eee73688888`                                         // gitleaks:allow
+	sampleHex31Token = `d0e94828b0549eee7368e53f6cb41d1`                                  // gitleaks:allow
+	sampleHex32Token = `d0e94828b0549eee7368e53f6cb41d17`                                 // gitleaks:allow
+	sampleHex34Token = `d0e94828b0549eee7368e53f6cb41d17aa`                               // gitleaks:allow
+	sampleHex35Token = `d0e94828b0549eee7368e53f6cb41d17aaa`                              // gitleaks:allow
+	sampleHex40Token = `aaaaad0e94828b0549eee7368e53f6cb41d17aaa`                         // gitleaks:allow
+	sampleHex48Token = `aaaaaaaaaaaaad0e94828b0549eee7368e53f6cb41d17aaa`                 // gitleaks:allow
+	sampleHex64Token = `d0e94828b0549eee7368e53f6cb41d17d0e94828b0549eee7368e53f6cb41d17` // gitleaks:allow
+
+	sampleAlphaNumeric14Token = `00000AAAAAbbbb`
+	sampleAlphaNumeric15Token = `00000AAAAAbbbbb`
+	sampleAlphaNumeric16Token = `00000AAAAAbbbbbb`
+	sampleAlphaNumeric20Token = `00000AAAAAbbbbb99999`
+	sampleAlphaNumeric22Token = `00000AAAAAbbbbb99999qq`
+	sampleAlphaNumeric24Token = `00000AAAAAbbbbb99999qqqq`
+	sampleAlphaNumeric25Token = `00000AAAAAbbbbb99999qqqqq`
+	sampleAlphaNumeric27Token = `00000AAAAAbbbbb99999qqqqqqq`
+	sampleAlphaNumeric30Token = `00000AAAAAbbbbb99999aaaaalllll`
+	sampleAlphaNumeric32Token = `00000AAAAAbbbbb99999aaaaalllllzz`
+	sampleAlphaNumeric36Token = `00000AAAAAbbbbb9999900000AAAAAbbbbb9`
+	sampleAlphaNumeric40Token = `000000000AAAAAbbbbb9999900000AAAAAbbbbb9`
+	sampleAlphaNumeric43Token = `00000AAAAAbbbbb99999aaaaallllpppeqaaaa00000`
+	sampleAlphaNumeric54Token = `00000AAAAAbbbbb99999aaaaallllpppeqaaaa00000ttttttttttt`
+	sampleAlphaNumeric64Token = `00000AAAAAbbbbb99999aaaaalllllzz00000AAAAAbbbbb99999aaaaalllllll`
+
+	sampleNumeric16 = `1111222233334444`
+	sampleNumeric18 = `111122223333444422`
+
+	sampleExtendedAlphaNumeric64Token = `00000AAAAAbbbbb99999aaaaalllllzz00000AAAAAbbbbb99999aaaaalllll_-`
+	sampleExtendedAlphaNumeric66Token = `0000000AAAAAbbbbb99999aaaaalllllzz00000AAAAAbbbbb99999aaaaalllll_-`
+	sampleExtendedAlphaNumeric59Token = `AAAAAbbbbb99999aaaaalllllzz00000AAAAAbbbbb99999aaaaalllll_-`
+	sampleExtendedAlphaNumeric60Token = `AAAAAAbbbbb99999aaaaalllllzz00000AAAAAbbbbb99999aaaaalllll_-`
+	sampleExtendedAlphaNumeric40Token = `00AAAAAbbbbb99999aaaaallll_--eq-=aa00000`
+	sampleExtendedAlphaNumeric43Token = `00000AAAAAbbbbb99999aaaaallll_--eq-=aa00000`
+	sampleExtendedAlphaNumeric32Token = `00000AAAAAbbbbb99999aaaaalllll=_`
+	sampleExtendedAlphaNumeric20Token = `bbb99999aaaaalllll=_`
+	sampleAlphaNumeric60Token         = `00000AAAAAbbbbb99999aaaaalllllzz00000AAAAAbbbbb99999aaaaalll`
+)
+
+func generateSemiGenericRegex(identifiers []string, secretRegex string) *regexp.Regexp {
+	var sb strings.Builder
+	sb.WriteString(caseInsensitive)
+	sb.WriteString(identifierPrefix)
+	sb.WriteString(strings.Join(identifiers, "|"))
+	sb.WriteString(identifierSuffix)
+	sb.WriteString(operator)
+	sb.WriteString(secretPrefix)
+	sb.WriteString(secretRegex)
+	sb.WriteString(secretSuffix)
+	return regexp.MustCompile(sb.String())
+}
+
+func generateUniqueTokenRegex(secretRegex string) *regexp.Regexp {
+	var sb strings.Builder
+	sb.WriteString(caseInsensitive)
+	sb.WriteString(secretPrefixUnique)
+	sb.WriteString(secretRegex)
+	sb.WriteString(secretSuffix)
+	return regexp.MustCompile(sb.String())
+}
+
+func generateSampleSecret(identifier string, secret string) string {
+	return fmt.Sprintf("%s_api_token = \"%s\"", identifier, secret)
+}
+
+func validate(r config.Rule, truePositives []string) *config.Rule {
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range truePositives {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msgf("Failed to validate %s", r.RuleID)
+		}
+	}
+	return &r
+}

+ 24 - 0
cmd/generate/config/rules/sendgrid.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func SendGridAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "sendgrid-api-token",
+		Description: "SendGrid API token",
+		Regex:       generateUniqueTokenRegex(`SG\.(?i)[a-z0-9=_\-\.]{66}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"SG.",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("sengridAPIToken", "SG."+sampleExtendedAlphaNumeric66Token),
+	}
+	return validate(r, tps)
+}

+ 24 - 0
cmd/generate/config/rules/sendinblue.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func SendInBlueAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "sendinblue-api-token",
+		Description: "Sendinblue API token",
+		Regex:       generateUniqueTokenRegex(`xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"xkeysib-",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("sendinblue", "xkeysib-"+sampleHex64Token+"-"+sampleHex16Token),
+	}
+	return validate(r, tps)
+}

+ 25 - 0
cmd/generate/config/rules/shippo.go

@@ -0,0 +1,25 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func ShippoAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "shippo-api-token",
+		Description: "Shippo API token",
+		Regex:       generateUniqueTokenRegex(`shippo_(live|test)_[a-f0-9]{40}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"shippo_",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("shippo", "shippo_live_"+sampleHex40Token),
+		generateSampleSecret("shippo", "shippo_test_"+sampleHex40Token),
+	}
+	return validate(r, tps)
+}

+ 98 - 0
cmd/generate/config/rules/shopify.go

@@ -0,0 +1,98 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/rs/zerolog/log"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+	"github.com/zricethezav/gitleaks/v8/detect"
+)
+
+func ShopifySharedSecret() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Shopify shared secret",
+		RuleID:      "shopify-shared-secret",
+		Regex:       regexp.MustCompile(`shpss_[a-fA-F0-9]{32}`),
+		Keywords:    []string{"shpss_"},
+	}
+
+	// validate
+	tps := []string{"shopifySecret := \"shpss_" + sampleHex32Token + "\""}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate shopify-shared-secret")
+		}
+	}
+	return &r
+}
+
+func ShopifyAccessToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Shopify access token",
+		RuleID:      "shopify-access-token",
+		Regex:       regexp.MustCompile(`shpat_[a-fA-F0-9]{32}`),
+		Keywords:    []string{"shpat_"},
+	}
+
+	// validate
+	tps := []string{"shopifyToken := \"shpat_" + sampleHex32Token + "\""}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate shopify-access-token")
+		}
+	}
+	return &r
+}
+
+func ShopifyCustomAccessToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Shopify custom access token",
+		RuleID:      "shopify-custom-access-token",
+		Regex:       regexp.MustCompile(`shpca_[a-fA-F0-9]{32}`),
+		Keywords:    []string{"shpca_"},
+	}
+
+	// validate
+	tps := []string{"shopifyToken := \"shpca_" + sampleHex32Token + "\""}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate shopify-custom-access-token")
+		}
+	}
+	return &r
+}
+
+func ShopifyPrivateAppAccessToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Shopify private app access token",
+		RuleID:      "shopify-private-app-access-token",
+		Regex:       regexp.MustCompile(`shppa_[a-fA-F0-9]{32}`),
+		Keywords:    []string{"shppa_"},
+	}
+
+	// validate
+	tps := []string{"shopifyToken := \"shppa_" + sampleHex32Token + "\""}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate shopify-private-app-access-token")
+		}
+	}
+	return &r
+}

+ 49 - 0
cmd/generate/config/rules/slack.go

@@ -0,0 +1,49 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func SlackAccessToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Slack token",
+		RuleID:      "slack-access-token",
+		Regex: regexp.MustCompile(
+			"xox[baprs]-([0-9a-zA-Z]{10,48})"),
+		Keywords: []string{
+			"xoxb",
+			"xoxa",
+			"xoxp",
+			"xoxr",
+			"xoxs",
+		},
+	}
+
+	// validate
+	tps := []string{
+		"\"slackToken\": \"xoxb-" + sampleHex32Token + "\"",
+	}
+	return validate(r, tps)
+}
+
+func SlackWebHook() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Slack Webhook",
+		RuleID:      "slack-web-hook",
+		Regex: regexp.MustCompile(
+			`https:\/\/hooks.slack.com\/services\/[A-Za-z0-9+\/]{44,46}`),
+		Keywords: []string{
+			"hooks.slack.com",
+		},
+	}
+
+	// validate
+	tps := []string{
+		"https://hooks.slack.com/services/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", // gitleaks:allow
+	}
+	return validate(r, tps)
+}

+ 37 - 0
cmd/generate/config/rules/stripe.go

@@ -0,0 +1,37 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/rs/zerolog/log"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+	"github.com/zricethezav/gitleaks/v8/detect"
+)
+
+func StripeAccessToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Stripe",
+		RuleID:      "stripe-access-token",
+		Regex:       regexp.MustCompile(`(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}`),
+		Keywords: []string{
+			"sk_test",
+			"pk_test",
+			"sk_live",
+			"pk_live",
+		},
+	}
+
+	// validate
+	tps := []string{"stripeToken := \"sk_test_" + sampleHex32Token + "\""}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate stripe-access-token")
+		}
+	}
+	return &r
+}

+ 34 - 0
cmd/generate/config/rules/twilio.go

@@ -0,0 +1,34 @@
+package rules
+
+import (
+	"regexp"
+
+	"github.com/rs/zerolog/log"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+	"github.com/zricethezav/gitleaks/v8/detect"
+)
+
+func Twilio() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "Twilio API Key",
+		RuleID:      "twilio-api-key",
+		Regex:       regexp.MustCompile(`SK[0-9a-fA-F]{32}`),
+		Keywords:    []string{"twilio"},
+	}
+
+	// validate
+	tps := []string{
+		"twilioAPIKey := \"SK" + sampleHex32Token + "\"",
+	}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate twilio")
+		}
+	}
+	return &r
+}

+ 24 - 0
cmd/generate/config/rules/twitch.go

@@ -0,0 +1,24 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func TwitchAPIToken() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "twitch-api-token",
+		Description: "Twitch API token",
+		Regex:       generateSemiGenericRegex([]string{"twitch"}, alphaNumeric30),
+		SecretGroup: 1,
+		Keywords: []string{
+			"twitch",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("twitch", sampleAlphaNumeric30Token),
+	}
+	return validate(r, tps)
+}

+ 35 - 0
cmd/generate/config/rules/twitter.go

@@ -0,0 +1,35 @@
+package rules
+
+import (
+	"github.com/rs/zerolog/log"
+
+	"github.com/zricethezav/gitleaks/v8/config"
+	"github.com/zricethezav/gitleaks/v8/detect"
+)
+
+func Twitter() *config.Rule {
+	// define rule
+	r := config.Rule{
+		Description: "twitter",
+		RuleID:      "twitter",
+		Regex: generateSemiGenericRegex([]string{"twitter"},
+			hex+"{35,44}"),
+		SecretGroup: 1,
+		Keywords:    []string{"twitter"},
+	}
+
+	// validate
+	tps := []string{
+		"twitterToken := \"" + sampleHex32Token + "aaaa\"",
+		"twitterToken := `" + sampleHex32Token + "aaaa`",
+	}
+	d := detect.NewDetector(config.Config{
+		Rules: []*config.Rule{&r},
+	})
+	for _, tp := range tps {
+		if len(d.DetectString(tp)) != 1 {
+			log.Fatal().Msg("Failed to validate twitter")
+		}
+	}
+	return &r
+}

+ 25 - 0
cmd/generate/config/rules/typeform.go

@@ -0,0 +1,25 @@
+package rules
+
+import (
+	"github.com/zricethezav/gitleaks/v8/config"
+)
+
+func Typeform() *config.Rule {
+	// define rule
+	r := config.Rule{
+		RuleID:      "typeform-api-token",
+		Description: "Typeform API token",
+		Regex: generateSemiGenericRegex([]string{"typeform"},
+			`tfp_[a-z0-9\-_\.=]{59}`),
+		SecretGroup: 1,
+		Keywords: []string{
+			"tfp_",
+		},
+	}
+
+	// validate
+	tps := []string{
+		generateSampleSecret("typeformAPIToken", "tfp_"+sampleExtendedAlphaNumeric59Token),
+	}
+	return validate(r, tps)
+}

+ 514 - 443
config/gitleaks.toml

@@ -1,653 +1,724 @@
 title = "gitleaks config"
 
-[[rules]]
-id = "gitlab-pat"
-description = "GitLab Personal Access Token"
-regex = '''glpat-[0-9a-zA-Z\-\_]{20}'''
-keywords = ["glpat"]
-
-[[rules]]
-id = "aws-access-token"
-description = "AWS"
-regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}'''
-keywords = [
-    "AKIA",
-    "AGPA",
-    "AIDA",
-    "AROA",
-    "AIPA",
-    "ANPA",
-    "ANVA",
-    "ASIA",
-]
-
-[[rules]]
-id = "PKCS8-PK"
-description = "PKCS8 private key"
-regex = '''-----BEGIN PRIVATE KEY-----'''
-keywords = ["BEGIN PRIVATE"]
-
-[[rules]]
-id = "RSA-PK"
-description = "RSA private key"
-regex = '''-----BEGIN RSA PRIVATE KEY-----'''
-keywords = ["BEGIN RSA"]
-
-[[rules]]
-id = "OPENSSH-PK"
-description = "SSH private key"
-regex = '''-----BEGIN OPENSSH PRIVATE KEY-----'''
-keywords = ["BEGIN OPENSSH"]
-
-[[rules]]
-id = "PGP-PK"
-description = "PGP private key"
-regex = '''-----BEGIN PGP PRIVATE KEY BLOCK-----'''
-keywords = ["BEGIN PGP"]
-
-[[rules]]
-id = "github-pat"
-description = "GitHub Personal Access Token"
-regex = '''ghp_[0-9a-zA-Z]{36}'''
-keywords = ["ghp_"]
-
-[[rules]]
-id = "github-oauth"
-description = "GitHub OAuth Access Token"
-regex = '''gho_[0-9a-zA-Z]{36}'''
-keywords = ["gho_"]
-
-
-[[rules]]
-id = "SSH-DSA-PK"
-description = "SSH (DSA) private key"
-regex = '''-----BEGIN DSA PRIVATE KEY-----'''
-keywords = ["BEGIN DSA"]
-
-[[rules]]
-id = "SSH-EC-PK"
-description = "SSH (EC) private key"
-regex = '''-----BEGIN EC PRIVATE KEY-----'''
-keywords = ["BEGIN EC"]
-
-
-[[rules]]
-id = "github-app-token"
-description = "GitHub App Token"
-regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}'''
-keywords = [
-    "ghu_",
-    "ghs_"
-]
-
-[[rules]]
-id = "github-refresh-token"
-description = "GitHub Refresh Token"
-regex = '''ghr_[0-9a-zA-Z]{76}'''
-keywords = ["ghr_"]
-
-[[rules]]
-id = "shopify-shared-secret"
-description = "Shopify shared secret"
-regex = '''shpss_[a-fA-F0-9]{32}'''
-keywords = ["shpss_"]
-
-[[rules]]
-id = "shopify-access-token"
-description = "Shopify access token"
-regex = '''shpat_[a-fA-F0-9]{32}'''
-keywords = ["shpat_"]
-
-[[rules]]
-id = "shopify-custom-access-token"
-description = "Shopify custom app access token"
-regex = '''shpca_[a-fA-F0-9]{32}'''
-keywords = ["shpca_"]
-
-[[rules]]
-id = "shopify-private-app-access-token"
-description = "Shopify private app access token"
-regex = '''shppa_[a-fA-F0-9]{32}'''
-keywords = ["shppa_"]
-
-[[rules]]
-id = "slack-access-token"
-description = "Slack token"
-regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?'''
-keywords = [
-    "xoxb",
-    "xoxa",
-    "xoxp",
-    "xoxr",
-    "xoxs"
+[allowlist]
+description = "global allow lists"
+regexes = [
+    '''219-09-9999''',
+    '''078-05-1120''',
+    '''(9[0-9]{2}|666)-\d{2}-\d{4}''',
     ]
-
-[[rules]]
-id = "stripe-access-token"
-description = "Stripe"
-regex = '''(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}'''
-keywords = [
-    "sk_test",
-    "pk_test",
-    "sk_live",
-    "pk_live"
+paths = [
+    '''gitleaks.toml''',
+    '''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''',
+    '''(go.mod|go.sum)$'''
 ]
 
 [[rules]]
-id = "pypi-upload-token"
-description = "PyPI upload token"
-regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}'''
-keywords = ["pypi-AgEIcHlwaS5vcmc"]
-
-[[rules]]
-id = "gcp-service-account"
-description = "Google (GCP) Service-account"
-regex = '''\"type\": \"service_account\"'''
-keywords = ["\"type\": \"service_account\""]
-
-[[rules]]
-id = "heroku-api-key"
-description = "Heroku API Key"
-regex = ''' (?i)(heroku[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})['\"]'''
-secretGroup = 3
-keywords = ["heroku"]
-
-[[rules]]
-id = "slack-web-hook"
-description = "Slack Webhook"
-regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8,12}/[a-zA-Z0-9_]{24}'''
-keywords = ["https://hooks.slack.com/services/"]
-
-[[rules]]
-id = "twilio-api-key"
-description = "Twilio API Key"
-regex = '''SK[0-9a-fA-F]{32}'''
-keywords = ["twilio"]
-
-[[rules]]
-id = "age-secret-key"
 description = "Age secret key"
+id = "age secret key"
 regex = '''AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}'''
-keywords = ["AGE-SECRET-KEY-1"]
-
-[[rules]]
-id = "facebook-token"
-description = "Facebook token"
-regex = '''(?i)(facebook[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32})['\"]'''
-secretGroup = 3
-keywords = ["facebook"]
-
-[[rules]]
-id = "twitter-token"
-description = "Twitter token"
-regex = '''(?i)(twitter[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{35,44})['\"]'''
-secretGroup = 3
-keywords = ["twitter"]
+keywords = [
+    "AGE-SECRET-KEY-1",
+]
 
 [[rules]]
-id = "adobe-client-id"
 description = "Adobe Client ID (Oauth Web)"
-regex = '''(?i)(adobe[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32})['\"]'''
-secretGroup = 3
-keywords = ["adobe"]
+id = "adobe-client-id"
+regex = '''(?i)(?:adobe)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "adobe",
+]
 
 [[rules]]
-id = "adobe-client-secret"
 description = "Adobe Client Secret"
+id = "adobe-client-secret"
 regex = '''(p8e-)(?i)[a-z0-9]{32}'''
-keywords = ["p8e-"]
+keywords = [
+    "p8e-",
+]
 
 [[rules]]
-id = "alibaba-access-key-id"
 description = "Alibaba AccessKey ID"
+id = "alibaba-access-key-id"
 regex = '''(LTAI)(?i)[a-z0-9]{20}'''
-keywords = ["LTAI"]
+keywords = [
+    "LTAI",
+]
 
 [[rules]]
-id = "alibaba-secret-key"
 description = "Alibaba Secret Key"
-regex = '''(?i)(alibaba[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{30})['\"]'''
-secretGroup = 3
-keywords = ["alibaba"]
+id = "alibaba-secret-key"
+regex = '''(?i)(?:alibaba)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "alibaba",
+]
 
 [[rules]]
-id = "asana-client-id"
 description = "Asana Client ID"
-regex = '''(?i)(asana[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9]{16})['\"]'''
-secretGroup = 3
-keywords = ["asana"]
+id = "asana-client-id"
+regex = '''(?i)(?:asana)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9]{16})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "asana",
+]
 
 [[rules]]
-id = "asana-client-secret"
 description = "Asana Client Secret"
-regex = '''(?i)(asana[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{32})['\"]'''
-secretGroup = 3
-keywords = ["asana"]
+id = "asana-client-secret"
+regex = '''(?i)(?:asana)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})['|\"|\n|\r|\s|\x60]'''
+keywords = [
+    "asana",
+]
 
 [[rules]]
-id = "atlassian-api-token"
 description = "Atlassian API token"
-regex = '''(?i)(atlassian[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{24})['\"]'''
-secretGroup = 3
-keywords = ["atlassian"]
+id = "atlassian-api-token"
+regex = '''(?i)(?:atlassian)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "atlassian",
+]
 
 [[rules]]
+description = "AWS"
+id = "aws-access-token"
+regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}'''
+keywords = [
+    "AKIA","AGPA","AIDA","AROA","AIPA","ANPA","ANVA","ASIA",
+]
+
+[[rules]]
+description = "BitBucket Client ID"
 id = "bitbucket-client-id"
-description = "Bitbucket client ID"
-regex = '''(?i)(bitbucket[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{32})['\"]'''
-secretGroup = 3
-keywords = ["bitbucket"]
+regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "bitbucket",
+]
 
 [[rules]]
+description = "BitBucket Client Secret"
 id = "bitbucket-client-secret"
-description = "Bitbucket client secret"
-regex = '''(?i)(bitbucket[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9_\-]{64})['\"]'''
-secretGroup = 3
-keywords = ["bitbucket"]
+regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_\-]{64})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "bitbucket",
+]
 
 [[rules]]
-id = "beamer-api-token"
 description = "Beamer API token"
-regex = '''(?i)(beamer[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](b_[a-z0-9=_\-]{44})['\"]'''
-secretGroup = 3
-keywords = ["beamer"]
+id = "beamer-api-token"
+regex = '''(?i)(?:beamer)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(b_[a-z0-9=_\-]{44})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "beamer",
+]
 
 [[rules]]
-id = "clojars-api-token"
 description = "Clojars API token"
+id = "clojars-api-token"
 regex = '''(CLOJARS_)(?i)[a-z0-9]{60}'''
-keywords = ["clojars"]
+keywords = [
+    "clojars",
+]
 
 [[rules]]
-id = "contentful-delivery-api-token"
 description = "Contentful delivery API token"
-regex = '''(?i)(contentful[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9\-=_]{43})['\"]'''
-secretGroup = 3
-keywords = ["contentful"]
+id = "contentful-delivery-api-token"
+regex = '''(?i)(?:contentful)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9\-=_]{43})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "contentful",
+]
 
 [[rules]]
-id = "databricks-api-token"
 description = "Databricks API token"
+id = "databricks-api-token"
 regex = '''dapi[a-h0-9]{32}'''
-keywords = ["dapi"]
+keywords = [
+    "dapi",
+]
 
 [[rules]]
-id = "discord-api-token"
 description = "Discord API key"
-regex = '''(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{64})['\"]'''
-secretGroup = 3
-keywords = ["discord"]
+id = "discord-api-token"
+regex = '''(?i)(?:discord)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "discord",
+]
 
 [[rules]]
-id = "discord-client-id"
 description = "Discord client ID"
-regex = '''(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9]{18})['\"]'''
-secretGroup = 3
-keywords = ["discord"]
+id = "discord-client-id"
+regex = '''(?i)(?:discord)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9]{18})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "discord",
+]
 
 [[rules]]
-id = "discord-client-secret"
 description = "Discord client secret"
-regex = '''(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9=_\-]{32})['\"]'''
-secretGroup = 3
-keywords = ["discord"]
+id = "discord-client-secret"
+regex = '''(?i)(?:discord)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "discord",
+]
 
 [[rules]]
+description = "Dropbox API secret"
 id = "doppler-api-token"
-description = "Doppler API token"
-regex = '''['\"](dp\.pt\.)(?i)[a-z0-9]{43}['\"]'''
-keywords = ["doppler"]
-
-[[rules]]
-id = "dropbox-api-secret"
-description = "Dropbox API secret/key"
-regex = '''(?i)(dropbox[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{15})['\"]'''
-keywords = ["dropbox"]
+regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{15})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "dropbox",
+]
 
 [[rules]]
-id = "dropbox--api-key"
-description = "Dropbox API secret/key"
-regex = '''(?i)(dropbox[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{15})['\"]'''
-keywords = ["dropbox"]
+description = "Dropbox long lived API token"
+id = "dropbox-long-lived-api-token"
+regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})['|\"|\n|\r|\s|\x60]'''
+keywords = [
+    "dropbox",
+]
 
 [[rules]]
-id = "dropbox-short-lived-api-token"
 description = "Dropbox short lived API token"
-regex = '''(?i)(dropbox[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](sl\.[a-z0-9\-=_]{135})['\"]'''
-keywords = ["dropbox"]
+id = "dropbox-short-lived-api-token"
+regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(sl\.[a-z0-9\-=_]{135})['|\"|\n|\r|\s|\x60]'''
+keywords = [
+    "dropbox",
+]
 
 [[rules]]
-id = "dropbox-long-lived-api-token"
-description = "Dropbox long lived API token"
-regex = '''(?i)(dropbox[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"][a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43}['\"]'''
-keywords = ["dropbox"]
+description = "Doppler API token"
+id = "doppler-api-token"
+regex = '''(dp\.pt\.)(?i)[a-z0-9]{43}'''
+keywords = [
+    "doppler",
+]
 
 [[rules]]
-id = "duffel-api-token"
 description = "Duffel API token"
-regex = '''['\"]duffel_(test|live)_(?i)[a-z0-9_-]{43}['\"]'''
-keywords = ["duffel"]
+id = "duffel-api-token"
+regex = '''duffel_(test|live)_(?i)[a-z0-9_\-=]{43}'''
+keywords = [
+    "duffel",
+]
 
 [[rules]]
-id = "dynatrace-api-token"
 description = "Dynatrace API token"
-regex = '''['\"]dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}['\"]'''
-keywords = ["dynatrace"]
+id = "dynatrace-api-token"
+regex = '''dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}'''
+keywords = [
+    "dynatrace",
+]
 
 [[rules]]
-id = "easypost-api-token"
 description = "EasyPost API token"
-regex = '''['\"]EZAK(?i)[a-z0-9]{54}['\"]'''
-keywords = ["EZAK"]
+id = "easypost-api-token"
+regex = '''EZAK(?i)[a-z0-9]{54}'''
+keywords = [
+    "EZAK",
+]
 
 [[rules]]
-id = "easypost-test-api-token"
 description = "EasyPost test API token"
-regex = '''['\"]EZTK(?i)[a-z0-9]{54}['\"]'''
-keywords = ["EZTK"]
+id = "easypost-test-api-token"
+regex = '''EZTK(?i)[a-z0-9]{54}'''
+keywords = [
+    "EZTK",
+]
 
 [[rules]]
+description = "facebook"
+id = "facebook"
+regex = '''(?i)(?:facebook)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "facebook",
+]
+
+[[rules]]
+description = "Fastly API key"
 id = "fastly-api-token"
-description = "Fastly API token"
-regex = '''(?i)(fastly[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9\-=_]{32})['\"]'''
-secretGroup = 3
-keywords = ["fastly"]
+regex = '''(?i)(?:fastly)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "fastly",
+]
 
 [[rules]]
+description = "Finicity Client Secret"
 id = "finicity-client-secret"
-description = "Finicity client secret"
-regex = '''(?i)(finicity[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{20})['\"]'''
-secretGroup = 3
-keywords = ["finicity"]
+regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "finicity",
+]
 
 [[rules]]
-id = "finicity-api-token"
 description = "Finicity API token"
-regex = '''(?i)(finicity[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32})['\"]'''
-secretGroup = 3
-keywords = ["finicity"]
+id = "finicity-api-token"
+regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "finicity",
+]
 
 [[rules]]
+description = "Finicity Public Key"
 id = "flutterwave-public-key"
-description = "Flutterwave public key"
 regex = '''FLWPUBK_TEST-(?i)[a-h0-9]{32}-X'''
-keywords = ["FLWPUBK_TEST"]
+keywords = [
+    "FLWPUBK_TEST",
+]
 
 [[rules]]
-id = "flutterwave-secret-key"
-description = "Flutterwave secret key"
+description = "Finicity Secret Key"
+id = "flutterwave-public-key"
 regex = '''FLWSECK_TEST-(?i)[a-h0-9]{32}-X'''
-keywords = ["FLWSECK_TEST"]
+keywords = [
+    "FLWSECK_TEST",
+]
 
 [[rules]]
-id = "flutterwave-enc-key"
-description = "Flutterwave encrypted key"
-regex = '''FLWSECK_TEST[a-h0-9]{12}'''
-keywords = ["FLWSECK_TEST"]
+description = "Finicity Secret Key"
+id = "flutterwave-public-key"
+regex = '''FLWSECK_TEST-(?i)[a-h0-9]{32}-X'''
+keywords = [
+    "FLWSECK_TEST",
+]
 
 [[rules]]
-id = "frameio-api-token"
 description = "Frame.io API token"
+id = "frameio-api-token"
 regex = '''fio-u-(?i)[a-z0-9\-_=]{64}'''
-keywords = ["fio-u-"]
+keywords = [
+    "fio-u-",
+]
+
+[[rules]]
+description = "Generic API Key"
+id = "generic-api-key"
+regex = '''(?i)(?:key|api[^Version]|token|pat|secret|client|password|auth)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9a-z\-_.=]{10,150})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+entropy = 3.7
+keywords = [
+    "key","api","token","secret","client","pat","password","auth",
+]
 
 [[rules]]
-id = "gocardless-api-token"
 description = "GoCardless API token"
-regex = '''['\"]live_(?i)[a-z0-9\-_=]{40}['\"]'''
-keywords = ["live_"]
+id = "gocardless-api-token"
+regex = '''(?i)(?:gocardless)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(live_(?i)[a-z0-9\-_=]{40})['|\"|\n|\r|\s|\x60]'''
+keywords = [
+    "live_","gocardless",
+]
 
 [[rules]]
-id = "hashicorp-tf-api-token"
-description = "HashiCorp Terraform user/org API token"
-regex = '''['\"](?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}['\"]'''
-keywords = ["atlasv1"]
+description = "GitHub Personal Access Token"
+id = "github-pat"
+regex = '''ghp_[0-9a-zA-Z]{36}'''
+keywords = [
+    "ghp_",
+]
+
+[[rules]]
+description = "GitHub OAuth Access Token"
+id = "github-oauth"
+regex = '''gho_[0-9a-zA-Z]{36}'''
+keywords = [
+    "gho_",
+]
+
+[[rules]]
+description = "GitHub App Token"
+id = "github-app-token"
+regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}'''
+keywords = [
+    "ghu_","ghs_",
+]
+
+[[rules]]
+description = "GitHub Refresh Token"
+id = "github-refresh-token"
+regex = '''ghr_[0-9a-zA-Z]{36}'''
+keywords = [
+    "ghr_",
+]
+
+[[rules]]
+description = "Gitlab Personal Access Token"
+id = "gitlab-pat"
+regex = '''glpat-[0-9a-zA-Z\-\_]{20}'''
+keywords = [
+    "glpat-",
+]
 
 [[rules]]
-id = "hubspot-api-token"
-description = "HubSpot API token"
-regex = '''(?i)(hubspot[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{8}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{12})['\"]'''
-secretGroup = 3
-keywords = ["hubspot"]
+description = "HashiCorp Terraform user/org API token"
+id = "hashicorp-tf-api-token"
+regex = '''(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}'''
+keywords = [
+    "atlasv1",
+]
 
 [[rules]]
-id = "intercom-api-token"
-description = "Intercom API token"
-regex = '''(?i)(intercom[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9=_]{60})['\"]'''
-secretGroup = 3
-keywords = ["intercom"]
+description = "Heroku API Key"
+id = "heroku-api-key"
+regex = '''(?i)(?:heroku)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "heroku",
+]
 
 [[rules]]
-id = "intercom-client-secret"
-description = "Intercom client secret/ID"
-regex = '''(?i)(intercom[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{8}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{12})['\"]'''
-secretGroup = 3
-keywords = ["intercom"]
+description = "HubSpot API Token"
+id = "hubspot-api-key"
+regex = '''(?i)(?:hubspot)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "hubspot",
+]
 
 [[rules]]
-id = "ionic-api-token"
-description = "Ionic API token"
-regex = '''(?i)(ionic[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](ion_[a-z0-9]{42})['\"]'''
-keywords = ["ionic"]
+description = "Intercom API Token"
+id = "intercom-api-key"
+regex = '''(?i)(?:intercom)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_\-]{60})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "intercom",
+]
 
 [[rules]]
-id = "linear-api-token"
-description = "Linear API token"
+description = "Linear API Token"
+id = "linear-api-key"
 regex = '''lin_api_(?i)[a-z0-9]{40}'''
-keywords = ["lin_api_"]
+keywords = [
+    "lin_api_",
+]
 
 [[rules]]
+description = "Linear Client Secret"
 id = "linear-client-secret"
-description = "Linear client secret/ID"
-regex = '''(?i)(linear[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32})['\"]'''
-secretGroup = 3
-keywords = ["linear"]
+regex = '''(?i)(?:linear)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})['|\"|\n|\r|\s|\x60]'''
+keywords = [
+    "linear",
+]
+
+[[rules]]
+description = "LinkedIn Client ID"
+id = "linkedin-client-id"
+regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "linkedin","linked-in",
+]
+
+[[rules]]
+description = "LinkedIn Client secret"
+id = "linkedin-client-secret"
+regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "linkedin","linked-in",
+]
 
 [[rules]]
-id = "lob-api-key"
 description = "Lob API Key"
-regex = '''(?i)(lob[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]((live|test)_[a-f0-9]{35})['\"]'''
-secretGroup = 3
-keywords = ["lob"]
+id = "lob-api-key"
+regex = '''(?i)(?:lob)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}((live|test)_[a-f0-9]{35})['|\"|\n|\r|\s|\x60]'''
+keywords = [
+    "test_","live_",
+]
 
 [[rules]]
-id = "lob-pub-api-key"
 description = "Lob Publishable API Key"
-regex = '''(?i)(lob[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]((test|live)_pub_[a-f0-9]{31})['\"]'''
-secretGroup = 3
+id = "lob-pub-api-key"
+regex = '''(?i)(?:lob)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}((test|live)_pub_[a-f0-9]{31})['|\"|\n|\r|\s|\x60]'''
 keywords = [
-    "test_pub",
-    "live_pub",
-    "_pub"
+    "test_pub","live_pub","_pub",
 ]
 
 [[rules]]
-id = "mailchimp-api-key"
 description = "Mailchimp API key"
-regex = '''(?i)(mailchimp[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32}-us20)['\"]'''
-secretGroup = 3
-keywords = ["mailchimp"]
+id = "mailchimp-api-key"
+regex = '''(?i)(?:mailchimp)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32}-us20)['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "mailchimp",
+]
 
 [[rules]]
-id = "mailgun-private-api-token"
-description = "Mailgun private API token"
-regex = '''(?i)(mailgun[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](key-[a-f0-9]{32})['\"]'''
-secretGroup = 3
+description = "Mailgun public validation key"
+id = "mailgun-pub-key"
+regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(pubkey-[a-f0-9]{32})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
 keywords = [
     "mailgun",
-    "key-"
 ]
 
 [[rules]]
-id = "mailgun-pub-key"
-description = "Mailgun public validation key"
-regex = '''(?i)(mailgun[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](pubkey-[a-f0-9]{32})['\"]'''
-secretGroup = 3
+description = "Mailgun private API token"
+id = "mailgun-private-api-token"
+regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(key-[a-f0-9]{32})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
 keywords = [
     "mailgun",
-    "pubkey-"
 ]
 
 [[rules]]
-id = "mailgun-signing-key"
 description = "Mailgun webhook signing key"
-regex = '''(?i)(mailgun[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})['\"]'''
-secretGroup = 3
-keywords = ["mailgun"]
+id = "mailgun-signing-key"
+regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "mailgun",
+]
 
 [[rules]]
+description = "MapBox API token"
 id = "mapbox-api-token"
-description = "Mapbox API token"
-regex = '''(?i)(pk\.[a-z0-9]{60}\.[a-z0-9]{22})'''
-keywords = ["mapbox"]
+regex = '''(?i)(?:mapbox)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "mapbox",
+]
 
 [[rules]]
-id = "messagebird-api-token"
 description = "MessageBird API token"
-regex = '''(?i)(messagebird[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{25})['\"]'''
-secretGroup = 3
+id = "messagebird-api-token"
+regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
 keywords = [
-    "messagebird",
-    "message_bird",
-    "message-bird"
+    "messagebird","message-bird","message_bird",
 ]
 
 [[rules]]
+description = "MessageBird client ID"
 id = "messagebird-client-id"
-description = "MessageBird API client ID"
-regex = '''(?i)(messagebird[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{8}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{12})['\"]'''
-secretGroup = 3
+regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{8}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{12})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
 keywords = [
-    "messagebird",
-    "message_bird",
-    "message-bird"
+    "messagebird","message-bird","message_bird",
 ]
 
 [[rules]]
-id = "new-relic-user-api-key"
 description = "New Relic user API Key"
-regex = '''['\"](NRAK-[A-Z0-9]{27})['\"]'''
-keywords = ["NRAK-"]
+id = "new-relic-user-api-key"
+regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(NRAK-[a-z0-9]{27})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "NRAK",
+]
 
 [[rules]]
-id = "new-relic-user-api-id"
 description = "New Relic user API ID"
-regex = '''(?i)(newrelic[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([A-Z0-9]{64})['\"]'''
-secretGroup = 3
-keywords = ["newrelic"]
+id = "new-relic-user-api-id"
+regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "new-relic","newrelic","new_relic",
+]
 
 [[rules]]
-id = "new-relic-browser-api-token"
 description = "New Relic ingest browser API token"
-regex = '''['\"](NRJS-[a-f0-9]{19})['\"]'''
-keywords = ["NRJS-"]
+id = "new-relic-browser-api-token"
+regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(NRJS-[a-f0-9]{19})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "NRJS-",
+]
 
 [[rules]]
-id = "npm-access-token"
 description = "npm access token"
-regex = '''['\"](npm_(?i)[a-z0-9]{36})['\"]'''
-keywords = ["npm_"]
+id = "npm-access-token"
+regex = '''(?i)\b(npm_[a-z0-9]{36})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "npm_",
+]
 
 [[rules]]
-id = "planetscale-password"
 description = "PlanetScale password"
-regex = '''pscale_pw_(?i)[a-z0-9\-_\.]{43}'''
-keywords = ["pscale_pw_"]
+id = "planetscale-password"
+regex = '''(?i)\b(pscale_pw_(?i)[a-z0-9=\-_\.]{43})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "pscale_pw_",
+]
 
 [[rules]]
-id = "planetscale-api-token"
 description = "PlanetScale API token"
-regex = '''pscale_tkn_(?i)[a-z0-9\-_\.]{43}'''
-keywords = ["pscale_tkn_"]
+id = "planetscale-api-token"
+regex = '''(?i)\b(pscale_tkn_(?i)[a-z0-9=\-_\.]{43})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "pscale_tkn_",
+]
 
 [[rules]]
-id = "postman-api-token"
 description = "Postman API token"
-regex = '''PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34}'''
-keywords = ["PMAK-"]
+id = "postman-api-token"
+regex = '''(?i)\b(PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "PMAK-",
+]
+
+[[rules]]
+description = "Private Key"
+id = "private-key"
+regex = '''(?i)-----\s*?BEGIN[ A-Z0-9_-]*?PRIVATE KEY\s*?-----[\s\S]*?----\s*?END[ A-Z0-9_-]*? PRIVATE KEY\s*?-----'''
+keywords = [
+    "-----BEGIN PRIVATE",
+]
 
 [[rules]]
-id = "pulumi-api-token"
 description = "Pulumi API token"
-regex = '''pul-[a-f0-9]{40}'''
-keywords = ["pul-"]
+id = "pulumi-api-token"
+regex = '''(?i)\b(pul-[a-f0-9]{40})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "pul-",
+]
+
+[[rules]]
+description = "PyPI upload token"
+id = "pypi-upload-token"
+regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}'''
+keywords = [
+    "pypi-AgEIcHlwaS5vcmc",
+]
 
 [[rules]]
-id = "rubygems-api-token"
 description = "Rubygem API token"
-regex = '''rubygems_[a-f0-9]{48}'''
-keywords = ["rubygems_"]
+id = "rubygems-api-token"
+regex = '''(?i)\b(rubygems_[a-f0-9]{48})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "rubygems_",
+]
 
 [[rules]]
-id = "sendgrid-api-token"
 description = "SendGrid API token"
-regex = '''SG\.(?i)[a-z0-9_\-\.]{66}'''
-keywords = ["sendgrid"]
+id = "sendgrid-api-token"
+regex = '''(?i)\b(SG\.(?i)[a-z0-9=_\-\.]{66})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "SG.",
+]
 
 [[rules]]
-id = "sendinblue-api-token"
 description = "Sendinblue API token"
-regex = '''xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16}'''
-keywords = ["xkeysib-"]
+id = "sendinblue-api-token"
+regex = '''(?i)\b(xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "xkeysib-",
+]
 
 [[rules]]
-id = "shippo-api-token"
 description = "Shippo API token"
-regex = '''shippo_(live|test)_[a-f0-9]{40}'''
-keywords = ["shippo_"]
+id = "shippo-api-token"
+regex = '''(?i)\b(shippo_(live|test)_[a-f0-9]{40})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "shippo_",
+]
 
 [[rules]]
-id = "linkedin-client-secret"
-description = "LinkedIn Client secret"
-regex = '''(?i)(linkedin[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z]{16})['\"]'''
-secretGroup = 3
-keywords = ["linkedin"]
+description = "Shopify access token"
+id = "shopify-access-token"
+regex = '''shpat_[a-fA-F0-9]{32}'''
+keywords = [
+    "shpat_",
+]
 
 [[rules]]
-id = "linkedin-client-id"
-description = "LinkedIn Client ID"
-regex = '''(?i)(linkedin[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{14})['\"]'''
-secretGroup = 3
-keywords = ["linkedin"]
+description = "Shopify custom access token"
+id = "shopify-custom-access-token"
+regex = '''shpca_[a-fA-F0-9]{32}'''
+keywords = [
+    "shpca_",
+]
 
 [[rules]]
-id = "twitch-api-token"
-description = "Twitch API token"
-regex = '''(?i)(twitch[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{30})['\"]'''
-secretGroup = 3
-keywords = ["twitch"]
+description = "Shopify private app access token"
+id = "shopify-private-app-access-token"
+regex = '''shppa_[a-fA-F0-9]{32}'''
+keywords = [
+    "shppa_",
+]
 
 [[rules]]
-id = "typeform-api-token"
-description = "Typeform API token"
-regex = '''(?i)(typeform[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}(tfp_[a-z0-9\-_\.=]{59})'''
-secretGroup = 3
-keywords = ["tpf_"]
+description = "Shopify shared secret"
+id = "shopify-shared-secret"
+regex = '''shpss_[a-fA-F0-9]{32}'''
+keywords = [
+    "shpss_",
+]
 
 [[rules]]
-id = "generic-api-key"
-description = "Generic API Key"
-regex = '''(?i)((key|api[^Version]|token|secret|password|auth)[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9a-zA-Z\-_=]{8,64})['\"]'''
-entropy = 3.7
-secretGroup = 4
+description = "Slack token"
+id = "slack-access-token"
+regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})'''
 keywords = [
-    "key",
-    "api",
-    "token",
-    "secret",
-    "password",
-    "auth",
+    "xoxb","xoxa","xoxp","xoxr","xoxs",
 ]
 
-[allowlist]
-description = "global allow lists"
-regexes = [
-    '''219-09-9999''',
-    '''078-05-1120''',
-    '''(9[0-9]{2}|666)-\d{2}-\d{4}''',
-    ]
-paths = [
-    '''gitleaks.toml''',
-    '''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''',
-    '''(go.mod|go.sum)$'''
+[[rules]]
+description = "Slack Webhook"
+id = "slack-web-hook"
+regex = '''https:\/\/hooks.slack.com\/services\/[A-Za-z0-9+\/]{44,46}'''
+keywords = [
+    "hooks.slack.com",
 ]
+
+[[rules]]
+description = "Stripe"
+id = "stripe-access-token"
+regex = '''(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}'''
+keywords = [
+    "sk_test","pk_test","sk_live","pk_live",
+]
+
+[[rules]]
+description = "Twilio API Key"
+id = "twilio-api-key"
+regex = '''SK[0-9a-fA-F]{32}'''
+keywords = [
+    "twilio",
+]
+
+[[rules]]
+description = "Twitch API token"
+id = "twitch-api-token"
+regex = '''(?i)(?:twitch)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "twitch",
+]
+
+[[rules]]
+description = "twitter"
+id = "twitter"
+regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{35,44})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "twitter",
+]
+
+[[rules]]
+description = "Typeform API token"
+id = "typeform-api-token"
+regex = '''(?i)(?:typeform)(?:[0-9a-z\-_\s.]{0,20})(?:'|"){0,1}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|\"|\s|=|\x60){0,5}(tfp_[a-z0-9\-_\.=]{59})['|\"|\n|\r|\s|\x60]'''
+secretGroup = 1
+keywords = [
+    "tfp_",
+]
+

+ 2 - 3
detect/detect.go

@@ -374,10 +374,9 @@ func (d *Detector) DetectFiles(source string) ([]report.Finding, error) {
 // Detect scans the given fragment and returns a list of findings
 func (d *Detector) Detect(fragment Fragment) []report.Finding {
 	var findings []report.Finding
-
 	// check if filepath is allowed
-	if d.Config.Allowlist.PathAllowed(fragment.FilePath) ||
-		fragment.FilePath == d.Config.Path {
+	if fragment.FilePath != "" && (d.Config.Allowlist.PathAllowed(fragment.FilePath) ||
+		fragment.FilePath == d.Config.Path) {
 		return findings
 	}