diff --git a/main.go b/main.go
index 0bfcbd6..ff6521d 100644
--- a/main.go
+++ b/main.go
@@ -22,6 +22,7 @@ import (
 	"log"
 	"os"
 	"path/filepath"
+	"sort"
 	"strings"
 
 	gas "github.com/HewlettPackard/gas/core"
@@ -61,15 +62,20 @@ USAGE:
 
 var logger *log.Logger
 
-func extendConfList(conf map[string]interface{}, name string, input []string) {
-	if val, ok := conf[name]; ok {
-		if data, ok := val.(*[]string); ok {
-			conf[name] = append(*data, input...)
-		} else {
-			logger.Fatal("Config item must be a string list: ", name)
-		}
-	} else {
+func extendConfList(conf map[string]interface{}, name string, inputStr string) {
+	if inputStr == "" {
 		conf[name] = []string{}
+	} else {
+		input := strings.Split(inputStr, ",")
+		if val, ok := conf[name]; ok {
+			if data, ok := val.(*[]string); ok {
+				conf[name] = append(*data, input...)
+			} else {
+				logger.Fatal("Config item must be a string list: ", name)
+			}
+		} else {
+			conf[name] = input
+		}
 	}
 }
 
@@ -86,8 +92,8 @@ func buildConfig(incRules string, excRules string) map[string]interface{} {
 	}
 
 	// add in CLI include and exclude data
-	extendConfList(config, "include", strings.Split(incRules, ","))
-	extendConfList(config, "exclude", strings.Split(excRules, ","))
+	extendConfList(config, "include", incRules)
+	extendConfList(config, "exclude", excRules)
 
 	// override ignoreNosec if given on CLI
 	if flagIgnoreNoSec != nil {
@@ -108,6 +114,20 @@ func usage() {
 	fmt.Fprintln(os.Stderr, usageText)
 	fmt.Fprint(os.Stderr, "OPTIONS:\n\n")
 	flag.PrintDefaults()
+	fmt.Fprint(os.Stderr, "\n\nRULES:\n\n")
+
+	// sorted rule list for eas of reading
+	rl := GetFullRuleList()
+	keys := make([]string, 0, len(rl))
+	for key := range rl {
+		keys = append(keys, key)
+	}
+	sort.Strings(keys)
+	for _, k := range keys {
+		v := rl[k]
+		fmt.Fprintf(os.Stderr, "\t%s: %s\n", k, v.description)
+	}
+	fmt.Fprint(os.Stderr, "\n")
 }
 
 func main() {
@@ -119,15 +139,11 @@ func main() {
 	var excluded filelist = []string{"*_test.go"}
 	flag.Var(&excluded, "skip", "File pattern to exclude from scan")
 
-	// Rule configuration
-	rules := newRulelist()
-	flag.Var(&rules, "rule", "GAS rules enabled when performing a scan")
-
 	incRules := ""
-	flag.StringVar(&incRules, "include", "", "comma sperated list of rules to include")
+	flag.StringVar(&incRules, "include", "", "comma sperated list of rules IDs to include, see rule list")
 
 	excRules := ""
-	flag.StringVar(&excRules, "exclude", "", "comma sperated list of rules to exclude")
+	flag.StringVar(&excRules, "exclude", "", "comma sperated list of rules IDs to exclude, see rule list")
 
 	// Custom commands / utilities to run instead of default analyzer
 	tools := newUtils()
@@ -155,12 +171,8 @@ func main() {
 
 	// Setup analyzer
 	config := buildConfig(incRules, excRules)
-
 	analyzer := gas.NewAnalyzer(config, logger)
-	if !rules.overwritten {
-		rules.useDefaults()
-	}
-	rules.apply(&analyzer)
+	AddRules(&analyzer, config)
 
 	// Traverse directory structure if './...'
 	if flag.NArg() == 1 && flag.Arg(0) == "./..." {
diff --git a/rulelist.go b/rulelist.go
index 3aa6f31..2502122 100644
--- a/rulelist.go
+++ b/rulelist.go
@@ -17,85 +17,77 @@ package main
 import (
 	"fmt"
 	"go/ast"
-	"strings"
 
 	gas "github.com/HewlettPackard/gas/core"
 	"github.com/HewlettPackard/gas/rules"
 )
 
-type ruleMaker func() (gas.Rule, ast.Node)
-type ruleConfig struct {
-	enabled      bool
-	constructors []ruleMaker
+type RuleInfo struct {
+	description string
+	build       func(map[string]interface{}) (gas.Rule, ast.Node)
 }
 
-type rulelist struct {
-	rules       map[string]*ruleConfig
-	overwritten bool
-}
+// GetFullRuleList get the full list of all rules available to GAS
+func GetFullRuleList() map[string]RuleInfo {
+	return map[string]RuleInfo{
+		// misc
+		"G101": RuleInfo{"hardcoded credentials", rules.NewHardcodedCredentials},
+		"G102": RuleInfo{"bind to all interfaces", rules.NewBindsToAllNetworkInterfaces},
+		"G103": RuleInfo{"use of unsafe block", rules.NewUsingUnsafe},
+		"G104": RuleInfo{"errors not checked", rules.NewTemplateCheck},
 
-func newRulelist() rulelist {
-	var rs rulelist
-	rs.rules = make(map[string]*ruleConfig)
-	rs.overwritten = false
-	rs.register("sql", rules.NewSqlStrConcat, rules.NewSqlStrFormat)
-	rs.register("crypto", rules.NewUsesWeakCryptography)
-	rs.register("hardcoded", rules.NewHardcodedCredentials)
-	rs.register("perms", rules.NewMkdirPerms, rules.NewChmodPerms)
-	rs.register("tempfile", rules.NewBadTempFile)
-	rs.register("tls_good", rules.NewModernTlsCheck)
-	rs.register("tls_ok", rules.NewIntermediateTlsCheck)
-	rs.register("tls_old", rules.NewCompatTlsCheck)
-	rs.register("bind", rules.NewBindsToAllNetworkInterfaces)
-	rs.register("unsafe", rules.NewUsingUnsafe)
-	rs.register("rsa", rules.NewWeakKeyStrength)
-	rs.register("templates", rules.NewTemplateCheck)
-	rs.register("exec", rules.NewSubproc)
-	rs.register("errors", rules.NewNoErrorCheck)
-	rs.register("rand", rules.NewWeakRandCheck)
-	rs.register("blacklist_imports", rules.NewBlacklistImports)
-	return rs
-}
+		// injection
+		"G201": RuleInfo{"sql string format", rules.NewSqlStrFormat},
+		"G202": RuleInfo{"sql string concat", rules.NewSqlStrConcat},
+		"G203": RuleInfo{"unescaped templates", rules.NewTemplateCheck},
+		"G204": RuleInfo{"use of exec", rules.NewSubproc},
 
-func (r *rulelist) register(name string, cons ...ruleMaker) {
-	r.rules[name] = &ruleConfig{false, cons}
-}
+		// filesystem
+		"G301": RuleInfo{"poor mkdir permissions", rules.NewMkdirPerms},
+		"G302": RuleInfo{"poor chmod permisions", rules.NewChmodPerms},
+		"G303": RuleInfo{"predicatable tempfile", rules.NewBadTempFile},
 
-func (r *rulelist) useDefaults() {
-	for k := range r.rules {
-		r.rules[k].enabled = true
+		// crypto
+		"G401": RuleInfo{"weak crypto", rules.NewUsesWeakCryptography},
+		"G402": RuleInfo{"bad TLS options", rules.NewIntermediateTlsCheck},
+		"G403": RuleInfo{"bad RSA key length", rules.NewWeakKeyStrength},
+		"G404": RuleInfo{"poor random source (rand)", rules.NewWeakRandCheck},
+
+		// blacklist
+		"G501": RuleInfo{"blacklist: crypto/md5", rules.NewBlacklist_crypto_md5},
+		"G502": RuleInfo{"blacklist: crypto/des", rules.NewBlacklist_crypto_des},
+		"G503": RuleInfo{"blacklist: crypto/rc4", rules.NewBlacklist_crypto_rc4},
+		"G504": RuleInfo{"blacklist: net/http/cgi", rules.NewBlacklist_net_http_cgi},
 	}
 }
 
-func (r *rulelist) list() []string {
-	i := 0
-	keys := make([]string, len(r.rules))
-	for k := range r.rules {
-		keys[i] = k
-		i++
-	}
-	return keys
-}
+func AddRules(analyzer *gas.Analyzer, conf map[string]interface{}) {
+	var all map[string]RuleInfo
 
-func (r *rulelist) apply(g *gas.Analyzer) {
-	for _, v := range r.rules {
-		if v.enabled {
-			for _, ctor := range v.constructors {
-				g.AddRule(ctor())
+	inc := conf["include"].([]string)
+	exc := conf["exclude"].([]string)
+
+	fmt.Println(len(inc))
+
+	// add included rules
+	if len(inc) == 0 {
+		all = GetFullRuleList()
+	} else {
+		all = map[string]RuleInfo{}
+		tmp := GetFullRuleList()
+		for _, v := range inc {
+			if val, ok := tmp[v]; ok {
+				all[v] = val
 			}
 		}
 	}
-}
 
-func (r *rulelist) String() string {
-	return strings.Join(r.list(), ", ")
-}
-
-func (r *rulelist) Set(opt string) error {
-	r.overwritten = true
-	if x, ok := r.rules[opt]; ok {
-		x.enabled = true
-		return nil
+	// remove excluded rules
+	for _, v := range exc {
+		delete(all, v)
+	}
+
+	for _, v := range all {
+		analyzer.AddRule(v.build(conf))
 	}
-	return fmt.Errorf("Valid rules are: %s", r)
 }
diff --git a/rules/bind.go b/rules/bind.go
index 4770608..f46285e 100644
--- a/rules/bind.go
+++ b/rules/bind.go
@@ -15,9 +15,10 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"go/ast"
 	"regexp"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 // Looks for net.Listen("0.0.0.0") or net.Listen(":8080")
@@ -38,7 +39,7 @@ func (r *BindsToAllNetworkInterfaces) Match(n ast.Node, c *gas.Context) (gi *gas
 	return
 }
 
-func NewBindsToAllNetworkInterfaces() (r gas.Rule, n ast.Node) {
+func NewBindsToAllNetworkInterfaces(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &BindsToAllNetworkInterfaces{
 		call:    regexp.MustCompile(`^net\.Listen$`),
 		pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`),
diff --git a/rules/bind_test.go b/rules/bind_test.go
index 41787e4..a93a73f 100644
--- a/rules/bind_test.go
+++ b/rules/bind_test.go
@@ -23,7 +23,7 @@ import (
 func TestBind0000(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewBindsToAllNetworkInterfaces())
+	analyzer.AddRule(NewBindsToAllNetworkInterfaces(config))
 
 	issues := gasTestRunner(`
 		package main
@@ -45,7 +45,7 @@ func TestBind0000(t *testing.T) {
 func TestBindEmptyHost(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewBindsToAllNetworkInterfaces())
+	analyzer.AddRule(NewBindsToAllNetworkInterfaces(config))
 
 	issues := gasTestRunner(`
 		package main
diff --git a/rules/blacklist.go b/rules/blacklist.go
index 85505f5..04dc5c3 100644
--- a/rules/blacklist.go
+++ b/rules/blacklist.go
@@ -20,47 +20,68 @@ import (
 	gas "github.com/HewlettPackard/gas/core"
 )
 
-type BlacklistImports struct {
-	BlacklistSet map[string]gas.MetaData
+type BlacklistImport struct {
+	gas.MetaData
+	Path string
 }
 
-func (r *BlacklistImports) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
+func (r *BlacklistImport) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
 	if node, ok := n.(*ast.ImportSpec); ok {
-		if data, ok := r.BlacklistSet[node.Path.Value]; ok {
-			return gas.NewIssue(c, n, data.What, data.Severity, data.Confidence), nil
+		if r.Path == node.Path.Value {
+			return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil
 		}
 	}
 	return nil, nil
 }
 
-func NewBlacklistImports() (r gas.Rule, n ast.Node) {
-	// TODO(tkelsey): make this configurable
-	// TODO(tkelsey): make it so each item can be selected/excluded individually
-	r = &BlacklistImports{
-		BlacklistSet: map[string]gas.MetaData{
-			`"crypto/md5"`: gas.MetaData{
-				Severity:   gas.High,
-				Confidence: gas.High,
-				What:       "Use of weak cryptographic primitive",
-			},
-			`"crypto/des"`: gas.MetaData{
-				Severity:   gas.High,
-				Confidence: gas.High,
-				What:       "Use of weak cryptographic primitive",
-			},
-			`"crypto/rc4"`: gas.MetaData{
-				Severity:   gas.High,
-				Confidence: gas.High,
-				What:       "Use of weak cryptographic primitive",
-			},
-			`"net/http/cgi"`: gas.MetaData{
-				Severity:   gas.High,
-				Confidence: gas.Low,
-				What:       "Go code running under CGI is vulnerable to Httpoxy attack. (CVE-2016-5386)",
-			},
+func NewBlacklist_crypto_md5(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
+	r = &BlacklistImport{
+		MetaData: gas.MetaData{
+			Severity:   gas.High,
+			Confidence: gas.High,
+			What:       "Use of weak cryptographic primitive",
 		},
+		Path: `"crypto/md5"`,
+	}
+	n = (*ast.ImportSpec)(nil)
+	return
+}
+
+func NewBlacklist_crypto_des(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
+	r = &BlacklistImport{
+		MetaData: gas.MetaData{
+			Severity:   gas.High,
+			Confidence: gas.High,
+			What:       "Use of weak cryptographic primitive",
+		},
+		Path: `"crypto/des"`,
+	}
+	n = (*ast.ImportSpec)(nil)
+	return
+}
+
+func NewBlacklist_crypto_rc4(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
+	r = &BlacklistImport{
+		MetaData: gas.MetaData{
+			Severity:   gas.High,
+			Confidence: gas.High,
+			What:       "Use of weak cryptographic primitive",
+		},
+		Path: `"crypto/rc4"`,
+	}
+	n = (*ast.ImportSpec)(nil)
+	return
+}
+
+func NewBlacklist_net_http_cgi(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
+	r = &BlacklistImport{
+		MetaData: gas.MetaData{
+			Severity:   gas.High,
+			Confidence: gas.High,
+			What:       "Go code running under CGI is vulnerable to Httpoxy attack. (CVE-2016-5386)",
+		},
+		Path: `"net/http/cgi"`,
 	}
-
 	n = (*ast.ImportSpec)(nil)
 	return
 }
diff --git a/rules/errors.go b/rules/errors.go
index 75d6634..2951731 100644
--- a/rules/errors.go
+++ b/rules/errors.go
@@ -50,7 +50,7 @@ func (r *NoErrorCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err err
 	return nil, nil
 }
 
-func NewNoErrorCheck() (r gas.Rule, n ast.Node) {
+func NewNoErrorCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &NoErrorCheck{
 		MetaData: gas.MetaData{
 			Severity:   gas.Low,
diff --git a/rules/errors_test.go b/rules/errors_test.go
index c644ad0..70c1861 100644
--- a/rules/errors_test.go
+++ b/rules/errors_test.go
@@ -23,7 +23,7 @@ import (
 func TestErrorsMulti(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewNoErrorCheck())
+	analyzer.AddRule(NewNoErrorCheck(config))
 
 	issues := gasTestRunner(
 		`package main
@@ -46,7 +46,7 @@ func TestErrorsMulti(t *testing.T) {
 func TestErrorsSingle(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewNoErrorCheck())
+	analyzer.AddRule(NewNoErrorCheck(config))
 
 	issues := gasTestRunner(
 		`package main
@@ -69,7 +69,7 @@ func TestErrorsSingle(t *testing.T) {
 func TestErrorsGood(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewNoErrorCheck())
+	analyzer.AddRule(NewNoErrorCheck(config))
 
 	issues := gasTestRunner(
 		`package main
diff --git a/rules/fileperms.go b/rules/fileperms.go
index 1d7bafe..ea22e8b 100644
--- a/rules/fileperms.go
+++ b/rules/fileperms.go
@@ -16,9 +16,10 @@ package rules
 
 import (
 	"fmt"
-	gas "github.com/HewlettPackard/gas/core"
 	"go/ast"
 	"regexp"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 type FilePermissions struct {
@@ -36,7 +37,7 @@ func (r *FilePermissions) Match(n ast.Node, c *gas.Context) (*gas.Issue, error)
 	return nil, nil
 }
 
-func NewChmodPerms() (r gas.Rule, n ast.Node) {
+func NewChmodPerms(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	mode := 0600
 	r = &FilePermissions{
 		pattern: regexp.MustCompile(`^os\.Chmod$`),
@@ -51,7 +52,7 @@ func NewChmodPerms() (r gas.Rule, n ast.Node) {
 	return
 }
 
-func NewMkdirPerms() (r gas.Rule, n ast.Node) {
+func NewMkdirPerms(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	mode := 0700
 	r = &FilePermissions{
 		pattern: regexp.MustCompile(`^(os\.Mkdir|os\.MkdirAll)$`),
diff --git a/rules/fileperms_test.go b/rules/fileperms_test.go
index 601f570..f70dbef 100644
--- a/rules/fileperms_test.go
+++ b/rules/fileperms_test.go
@@ -23,7 +23,7 @@ import (
 func TestChmod(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewChmodPerms())
+	analyzer.AddRule(NewChmodPerms(config))
 
 	issues := gasTestRunner(`
 		package main
@@ -39,7 +39,7 @@ func TestChmod(t *testing.T) {
 func TestMkdir(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewMkdirPerms())
+	analyzer.AddRule(NewMkdirPerms(config))
 
 	issues := gasTestRunner(`
 		package main
diff --git a/rules/hardcoded_credentials.go b/rules/hardcoded_credentials.go
index eecf85f..47f9f84 100644
--- a/rules/hardcoded_credentials.go
+++ b/rules/hardcoded_credentials.go
@@ -43,7 +43,7 @@ func (r *CredsAssign) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
 	return
 }
 
-func NewHardcodedCredentials() (r gas.Rule, n ast.Node) {
+func NewHardcodedCredentials(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &CredsAssign{
 		pattern: regexp.MustCompile(`(?i)passwd|pass|password|pwd|secret|token`),
 		MetaData: gas.MetaData{
diff --git a/rules/hardcoded_credentials_test.go b/rules/hardcoded_credentials_test.go
index 1d512a7..46e2211 100644
--- a/rules/hardcoded_credentials_test.go
+++ b/rules/hardcoded_credentials_test.go
@@ -23,7 +23,7 @@ import (
 func TestHardcoded(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewHardcodedCredentials())
+	analyzer.AddRule(NewHardcodedCredentials(config))
 
 	issues := gasTestRunner(
 		`
diff --git a/rules/httpoxy_test.go b/rules/httpoxy_test.go
index cdaefe8..90f4074 100644
--- a/rules/httpoxy_test.go
+++ b/rules/httpoxy_test.go
@@ -23,7 +23,7 @@ import (
 func TestHttpoxy(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewBlacklistImports())
+	analyzer.AddRule(NewBlacklist_net_http_cgi(config))
 
 	issues := gasTestRunner(`
 		package main
diff --git a/rules/nosec_test.go b/rules/nosec_test.go
index d0f7103..efbab8e 100644
--- a/rules/nosec_test.go
+++ b/rules/nosec_test.go
@@ -23,7 +23,7 @@ import (
 func TestNosec(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSubproc())
+	analyzer.AddRule(NewSubproc(config))
 
 	issues := gasTestRunner(
 		`package main
@@ -42,7 +42,7 @@ func TestNosec(t *testing.T) {
 func TestNosecBlock(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSubproc())
+	analyzer.AddRule(NewSubproc(config))
 
 	issues := gasTestRunner(
 		`package main
@@ -64,7 +64,7 @@ func TestNosecBlock(t *testing.T) {
 func TestNosecIgnore(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": true}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSubproc())
+	analyzer.AddRule(NewSubproc(config))
 
 	issues := gasTestRunner(
 		`package main
diff --git a/rules/rand.go b/rules/rand.go
index 95c8b47..09cfbf4 100644
--- a/rules/rand.go
+++ b/rules/rand.go
@@ -39,7 +39,7 @@ func (w *WeakRand) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
 	return nil, nil
 }
 
-func NewWeakRandCheck() (r gas.Rule, n ast.Node) {
+func NewWeakRandCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &WeakRand{
 		pattern:     regexp.MustCompile(`^rand\.Read$`),
 		packageName: "rand",
diff --git a/rules/rand_test.go b/rules/rand_test.go
index 670b22c..93c1352 100644
--- a/rules/rand_test.go
+++ b/rules/rand_test.go
@@ -23,7 +23,7 @@ import (
 func TestRandOk(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewWeakRandCheck())
+	analyzer.AddRule(NewWeakRandCheck(config))
 
 	issues := gasTestRunner(
 		`
@@ -41,7 +41,7 @@ func TestRandOk(t *testing.T) {
 func TestRandBad(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewWeakRandCheck())
+	analyzer.AddRule(NewWeakRandCheck(config))
 
 	issues := gasTestRunner(
 		`
diff --git a/rules/rsa.go b/rules/rsa.go
index d2c640c..5a8d1d2 100644
--- a/rules/rsa.go
+++ b/rules/rsa.go
@@ -37,7 +37,7 @@ func (w *WeakKeyStrength) Match(n ast.Node, c *gas.Context) (*gas.Issue, error)
 	return nil, nil
 }
 
-func NewWeakKeyStrength() (r gas.Rule, n ast.Node) {
+func NewWeakKeyStrength(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	bits := 2048
 	r = &WeakKeyStrength{
 		pattern: regexp.MustCompile(`^rsa\.GenerateKey$`),
diff --git a/rules/rsa_test.go b/rules/rsa_test.go
index 7988562..9a814d7 100644
--- a/rules/rsa_test.go
+++ b/rules/rsa_test.go
@@ -23,7 +23,7 @@ import (
 func TestRSAKeys(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewWeakKeyStrength())
+	analyzer.AddRule(NewWeakKeyStrength(config))
 
 	issues := gasTestRunner(
 		`package main
diff --git a/rules/sql.go b/rules/sql.go
index 737f4e2..8b35317 100644
--- a/rules/sql.go
+++ b/rules/sql.go
@@ -56,7 +56,7 @@ func (s *SqlStrConcat) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
 	return nil, nil
 }
 
-func NewSqlStrConcat() (r gas.Rule, n ast.Node) {
+func NewSqlStrConcat(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &SqlStrConcat{
 		SqlStatement: SqlStatement{
 			pattern: regexp.MustCompile(`(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `),
@@ -86,7 +86,7 @@ func (s *SqlStrFormat) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err err
 	return nil, nil
 }
 
-func NewSqlStrFormat() (r gas.Rule, n ast.Node) {
+func NewSqlStrFormat(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &SqlStrFormat{
 		call: regexp.MustCompile(`^fmt\.Sprintf$`),
 		SqlStatement: SqlStatement{
diff --git a/rules/sql_test.go b/rules/sql_test.go
index 2590230..174b829 100644
--- a/rules/sql_test.go
+++ b/rules/sql_test.go
@@ -23,7 +23,7 @@ import (
 func TestSQLInjectionViaConcatenation(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSqlStrConcat())
+	analyzer.AddRule(NewSqlStrConcat(config))
 
 	source := `
         package main
@@ -51,7 +51,7 @@ func TestSQLInjectionViaConcatenation(t *testing.T) {
 func TestSQLInjectionViaIntepolation(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSqlStrFormat())
+	analyzer.AddRule(NewSqlStrFormat(config))
 
 	source := `
         package main
@@ -81,8 +81,8 @@ func TestSQLInjectionViaIntepolation(t *testing.T) {
 func TestSQLInjectionFalsePositiveA(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSqlStrConcat())
-	analyzer.AddRule(NewSqlStrFormat())
+	analyzer.AddRule(NewSqlStrConcat(config))
+	analyzer.AddRule(NewSqlStrFormat(config))
 
 	source := `
 
@@ -117,8 +117,8 @@ func TestSQLInjectionFalsePositiveA(t *testing.T) {
 func TestSQLInjectionFalsePositiveB(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSqlStrConcat())
-	analyzer.AddRule(NewSqlStrFormat())
+	analyzer.AddRule(NewSqlStrConcat(config))
+	analyzer.AddRule(NewSqlStrFormat(config))
 
 	source := `
 
@@ -153,8 +153,8 @@ func TestSQLInjectionFalsePositiveB(t *testing.T) {
 func TestSQLInjectionFalsePositiveC(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSqlStrConcat())
-	analyzer.AddRule(NewSqlStrFormat())
+	analyzer.AddRule(NewSqlStrConcat(config))
+	analyzer.AddRule(NewSqlStrFormat(config))
 
 	source := `
 
@@ -189,8 +189,8 @@ func TestSQLInjectionFalsePositiveC(t *testing.T) {
 func TestSQLInjectionFalsePositiveD(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSqlStrConcat())
-	analyzer.AddRule(NewSqlStrFormat())
+	analyzer.AddRule(NewSqlStrConcat(config))
+	analyzer.AddRule(NewSqlStrFormat(config))
 
 	source := `
 
diff --git a/rules/subproc.go b/rules/subproc.go
index d47ae26..4ca567b 100644
--- a/rules/subproc.go
+++ b/rules/subproc.go
@@ -49,7 +49,7 @@ func (r *Subprocess) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
 	return nil, nil
 }
 
-func NewSubproc() (r gas.Rule, n ast.Node) {
+func NewSubproc(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &Subprocess{
 		pattern: regexp.MustCompile(`^exec\.Command|syscall\.Exec$`),
 	}
diff --git a/rules/subproc_test.go b/rules/subproc_test.go
index d8199d4..f701653 100644
--- a/rules/subproc_test.go
+++ b/rules/subproc_test.go
@@ -23,7 +23,7 @@ import (
 func TestSubprocess(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSubproc())
+	analyzer.AddRule(NewSubproc(config))
 
 	issues := gasTestRunner(`
     package main
@@ -51,7 +51,7 @@ func TestSubprocess(t *testing.T) {
 func TestSubprocessVar(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSubproc())
+	analyzer.AddRule(NewSubproc(config))
 
 	issues := gasTestRunner(`
     package main
@@ -79,7 +79,7 @@ func TestSubprocessVar(t *testing.T) {
 func TestSubprocessPath(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSubproc())
+	analyzer.AddRule(NewSubproc(config))
 
 	issues := gasTestRunner(`
     package main
@@ -106,7 +106,7 @@ func TestSubprocessPath(t *testing.T) {
 func TestSubprocessSyscall(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewSubproc())
+	analyzer.AddRule(NewSubproc(config))
 
 	issues := gasTestRunner(`
     package main
diff --git a/rules/tempfiles.go b/rules/tempfiles.go
index c31b556..cd0df25 100644
--- a/rules/tempfiles.go
+++ b/rules/tempfiles.go
@@ -15,9 +15,10 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"go/ast"
 	"regexp"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 type BadTempFile struct {
@@ -35,7 +36,7 @@ func (t *BadTempFile) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
 	return nil, nil
 }
 
-func NewBadTempFile() (r gas.Rule, n ast.Node) {
+func NewBadTempFile(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &BadTempFile{
 		call: regexp.MustCompile(`ioutil\.WriteFile|os\.Create`),
 		args: regexp.MustCompile(`^/tmp/.*$|^/var/tmp/.*$`),
diff --git a/rules/tempfiles_test.go b/rules/tempfiles_test.go
index d3c019c..25ae3d5 100644
--- a/rules/tempfiles_test.go
+++ b/rules/tempfiles_test.go
@@ -23,7 +23,7 @@ import (
 func TestTempfiles(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewBadTempFile())
+	analyzer.AddRule(NewBadTempFile(config))
 
 	source := `
         package samples
diff --git a/rules/templates.go b/rules/templates.go
index 5b8a28b..ac537f2 100644
--- a/rules/templates.go
+++ b/rules/templates.go
@@ -15,9 +15,10 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"go/ast"
 	"regexp"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 type TemplateCheck struct {
@@ -36,7 +37,7 @@ func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err er
 	return nil, nil
 }
 
-func NewTemplateCheck() (r gas.Rule, n ast.Node) {
+func NewTemplateCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &TemplateCheck{
 		call: regexp.MustCompile(`^template\.(HTML|JS|URL)$`),
 		MetaData: gas.MetaData{
diff --git a/rules/templates_test.go b/rules/templates_test.go
index 0185ef7..5bf788d 100644
--- a/rules/templates_test.go
+++ b/rules/templates_test.go
@@ -23,7 +23,7 @@ import (
 func TestTemplateCheckSafe(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewTemplateCheck())
+	analyzer.AddRule(NewTemplateCheck(config))
 
 	source := `
   package samples
@@ -51,7 +51,7 @@ func TestTemplateCheckSafe(t *testing.T) {
 func TestTemplateCheckBadHTML(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewTemplateCheck())
+	analyzer.AddRule(NewTemplateCheck(config))
 
 	source := `
   package samples
@@ -80,7 +80,7 @@ func TestTemplateCheckBadHTML(t *testing.T) {
 func TestTemplateCheckBadJS(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewTemplateCheck())
+	analyzer.AddRule(NewTemplateCheck(config))
 
 	source := `
   package samples
@@ -109,7 +109,7 @@ func TestTemplateCheckBadJS(t *testing.T) {
 func TestTemplateCheckBadURL(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewTemplateCheck())
+	analyzer.AddRule(NewTemplateCheck(config))
 
 	source := `
   package samples
diff --git a/rules/tls.go b/rules/tls.go
index 3d8b521..ee398ba 100644
--- a/rules/tls.go
+++ b/rules/tls.go
@@ -109,7 +109,7 @@ func (t *InsecureConfigTLS) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, er
 	return
 }
 
-func NewModernTlsCheck() (r gas.Rule, n ast.Node) {
+func NewModernTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	// https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
 	r = &InsecureConfigTLS{
 		pattern:    regexp.MustCompile(`^tls\.Config$`),
@@ -126,7 +126,7 @@ func NewModernTlsCheck() (r gas.Rule, n ast.Node) {
 	return
 }
 
-func NewIntermediateTlsCheck() (r gas.Rule, n ast.Node) {
+func NewIntermediateTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	// https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
 	r = &InsecureConfigTLS{
 		pattern:    regexp.MustCompile(`^tls\.Config$`),
@@ -154,7 +154,7 @@ func NewIntermediateTlsCheck() (r gas.Rule, n ast.Node) {
 	return
 }
 
-func NewCompatTlsCheck() (r gas.Rule, n ast.Node) {
+func NewCompatTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	// https://wiki.mozilla.org/Security/Server_Side_TLS#Old_compatibility_.28default.29
 	r = &InsecureConfigTLS{
 		pattern:    regexp.MustCompile(`^tls\.Config$`),
diff --git a/rules/tls_test.go b/rules/tls_test.go
index 2f9c797..bf9237e 100644
--- a/rules/tls_test.go
+++ b/rules/tls_test.go
@@ -23,7 +23,7 @@ import (
 func TestInsecureSkipVerify(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewModernTlsCheck())
+	analyzer.AddRule(NewModernTlsCheck(config))
 
 	issues := gasTestRunner(`
         package main
@@ -52,7 +52,7 @@ func TestInsecureSkipVerify(t *testing.T) {
 func TestInsecureMinVersion(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewModernTlsCheck())
+	analyzer.AddRule(NewModernTlsCheck(config))
 
 	issues := gasTestRunner(`
         package main
@@ -81,7 +81,7 @@ func TestInsecureMinVersion(t *testing.T) {
 func TestInsecureMaxVersion(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewModernTlsCheck())
+	analyzer.AddRule(NewModernTlsCheck(config))
 
 	issues := gasTestRunner(`
         package main
@@ -110,7 +110,7 @@ func TestInsecureMaxVersion(t *testing.T) {
 func TestInsecureCipherSuite(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewModernTlsCheck())
+	analyzer.AddRule(NewModernTlsCheck(config))
 
 	issues := gasTestRunner(`
         package main
diff --git a/rules/unsafe.go b/rules/unsafe.go
index 186db9c..1d89ea9 100644
--- a/rules/unsafe.go
+++ b/rules/unsafe.go
@@ -15,9 +15,10 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"go/ast"
 	"regexp"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 type UsingUnsafe struct {
@@ -32,7 +33,7 @@ func (r *UsingUnsafe) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
 	return nil, nil
 }
 
-func NewUsingUnsafe() (r gas.Rule, n ast.Node) {
+func NewUsingUnsafe(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &UsingUnsafe{
 		pattern: regexp.MustCompile(`unsafe.*`),
 		MetaData: gas.MetaData{
diff --git a/rules/unsafe_test.go b/rules/unsafe_test.go
index 1dcbb3e..7714901 100644
--- a/rules/unsafe_test.go
+++ b/rules/unsafe_test.go
@@ -23,7 +23,7 @@ import (
 func TestUnsafe(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewUsingUnsafe())
+	analyzer.AddRule(NewUsingUnsafe(config))
 
 	issues := gasTestRunner(`
         package main
diff --git a/rules/weakcrypto.go b/rules/weakcrypto.go
index 7115195..c0bc552 100644
--- a/rules/weakcrypto.go
+++ b/rules/weakcrypto.go
@@ -34,7 +34,7 @@ func (r *UsesWeakCryptography) Match(n ast.Node, c *gas.Context) (*gas.Issue, er
 }
 
 // Uses des.* md5.* or rc4.*
-func NewUsesWeakCryptography() (r gas.Rule, n ast.Node) {
+func NewUsesWeakCryptography(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
 	r = &UsesWeakCryptography{
 		pattern: regexp.MustCompile(`des\.NewCipher|des\.NewTripleDESCipher|md5\.New|md5\.Sum|rc4\.NewCipher`),
 		MetaData: gas.MetaData{
diff --git a/rules/weakcrypto_test.go b/rules/weakcrypto_test.go
index 35070c6..8169387 100644
--- a/rules/weakcrypto_test.go
+++ b/rules/weakcrypto_test.go
@@ -23,8 +23,8 @@ import (
 func TestMD5(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewBlacklistImports())
-	analyzer.AddRule(NewUsesWeakCryptography())
+	analyzer.AddRule(NewBlacklist_crypto_md5(config))
+	analyzer.AddRule(NewUsesWeakCryptography(config))
 
 	issues := gasTestRunner(`
                 package main
@@ -45,8 +45,8 @@ func TestMD5(t *testing.T) {
 func TestDES(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewBlacklistImports())
-	analyzer.AddRule(NewUsesWeakCryptography())
+	analyzer.AddRule(NewBlacklist_crypto_des(config))
+	analyzer.AddRule(NewUsesWeakCryptography(config))
 
 	issues := gasTestRunner(`
                 package main
@@ -85,8 +85,8 @@ func TestDES(t *testing.T) {
 func TestRC4(t *testing.T) {
 	config := map[string]interface{}{"ignoreNosec": false}
 	analyzer := gas.NewAnalyzer(config, nil)
-	analyzer.AddRule(NewBlacklistImports())
-	analyzer.AddRule(NewUsesWeakCryptography())
+	analyzer.AddRule(NewBlacklist_crypto_rc4(config))
+	analyzer.AddRule(NewUsesWeakCryptography(config))
 
 	issues := gasTestRunner(`
                 package main