diff --git a/README.md b/README.md index 3b76329..58d52d8 100644 --- a/README.md +++ b/README.md @@ -64,5 +64,6 @@ $ onstaging ./bin/ci/deploy-service.sh - :white_check_mark: Build a CI/CD pipeline - :white_check_mark: Implement some tests - Loading Environment variables from a .env file -- Encrypted environment variables via [dragoman](https://github.com/meltwater/dragoman) +- :white_check_mark: Encrypted environment variables via [dragoman](https://github.com/meltwater/dragoman) +- Kubernetes context setting - Potentially switching to [cobra](https://github.com/spf13/cobra) for the cli \ No newline at end of file diff --git a/go.mod b/go.mod index 5701a90..377ae81 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/aws/aws-sdk-go-v2/credentials v1.12.4 github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.9 github.com/aws/aws-sdk-go-v2/service/sts v1.16.6 + github.com/meltwater/dragoman v1.2.2 github.com/stretchr/testify v1.7.1 gopkg.in/yaml.v3 v3.0.1 ) @@ -18,9 +19,12 @@ require ( github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.5 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.12 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.5 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.14.0 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.11.7 // indirect github.com/aws/smithy-go v1.11.2 // indirect - github.com/davecgh/go-spew v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/objx v0.1.0 // indirect + github.com/stretchr/objx v0.1.1 // indirect + golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect ) diff --git a/go.sum b/go.sum index d1f90a0..d79219f 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +github.com/aws/aws-sdk-go-v2 v1.13.0/go.mod h1:L6+ZpqHaLbAaxsqV0L4cvxZY7QupWJB4fhkf8LXvC7w= github.com/aws/aws-sdk-go-v2 v1.16.4 h1:swQTEQUyJF/UkEA94/Ga55miiKFoXmm/Zd67XHgmjSg= github.com/aws/aws-sdk-go-v2 v1.16.4/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= github.com/aws/aws-sdk-go-v2/config v1.15.9 h1:TK5yNEnFDQ9iaO04gJS/3Y+eW8BioQiCUafW75/Wc3Q= @@ -6,34 +7,49 @@ github.com/aws/aws-sdk-go-v2/credentials v1.12.4 h1:xggwS+qxCukXRVXJBJWQJGyUsvux github.com/aws/aws-sdk-go-v2/credentials v1.12.4/go.mod h1:7g+GGSp7xtR823o1jedxKmqRZGqLdoHQfI4eFasKKxs= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.5 h1:YPxclBeE07HsLQE8vtjC8T2emcTjM9nzqsnDi2fv5UM= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.5/go.mod h1:WAPnuhG5IQ/i6DETFl5NmX3kKqCzw7aau9NHAGcm4QE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.4/go.mod h1:XHgQ7Hz2WY2GAn//UXHofLfPXWh+s62MbMOijrg12Lw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.11 h1:gsqHplNh1DaQunEKZISK56wlpbCg0yKxNVvGWCFuF1k= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.11/go.mod h1:tmUB6jakq5DFNcXsXOA/ZQ7/C8VnSKYkx58OI7Fh79g= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.2.0/go.mod h1:BsCSJHx5DnDXIrOcqB8KN1/B+hXLG/bi4Y6Vjcx/x9E= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.5 h1:PLFj+M2PgIDHG//hw3T0O0KLI4itVtAjtxrZx4AHPLg= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.5/go.mod h1:fV1AaS2gFc1tM0RCb015FJ0pvWVUfJZANzjwoO4YakM= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.12 h1:j0VqrjtgsY1Bx27tD0ysay36/K4kFMWRp9K3ieO9nLU= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.12/go.mod h1:00c7+ALdPh4YeEUPXJzyU0Yy01nPGOq2+9rUaz05z9g= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.5 h1:gRW1ZisKc93EWEORNJRvy/ZydF3o6xLSveJHdi1Oa0U= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.5/go.mod h1:ZbkttHXaVn3bBo/wpJbQGiiIWR90eTBUVBrEHUEQlho= +github.com/aws/aws-sdk-go-v2/service/kms v1.14.0 h1:A8FMqkP+OlnSiVY+2QakwqW0fAGnE18TqPig/T7aJU0= +github.com/aws/aws-sdk-go-v2/service/kms v1.14.0/go.mod h1:arlReKeYmnfm/LmGiURTuIYIKWJf0FEpajiVX0hlv7M= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.9 h1:a7+ZYQbKAziY5a7H8Ggwp/6HM9UKT6h9al+QHY+P6jI= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.9/go.mod h1:Jt1lSw1fYlQ60lqrZ9ViN2LMGizbWTWbkStm4rbuYuE= github.com/aws/aws-sdk-go-v2/service/sso v1.11.7 h1:suAGD+RyiHWPPihZzY+jw4mCZlOFWgmdjb2AeTenz7c= github.com/aws/aws-sdk-go-v2/service/sso v1.11.7/go.mod h1:TFVe6Rr2joVLsYQ1ABACXgOC6lXip/qpX2x5jWg/A9w= github.com/aws/aws-sdk-go-v2/service/sts v1.16.6 h1:aYToU0/iazkMY67/BYLt3r6/LT/mUtarLAF5mGof1Kg= github.com/aws/aws-sdk-go-v2/service/sts v1.16.6/go.mod h1:rP1rEOKAGZoXp4iGDxSXFvODAtXpm34Egf0lL0eshaQ= +github.com/aws/smithy-go v1.10.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/meltwater/dragoman v1.2.2 h1:ZdpdB2vkm9grPjqvp9/6eZEmGubCQtVPuMUi4NDgdoE= +github.com/meltwater/dragoman v1.2.2/go.mod h1:waYPsylnXTj4F7xblDEeDEKqxNPZjkqcLYd/6DaUoOM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/src/lib/setters/dragoman_setter.go b/src/lib/setters/dragoman_setter.go new file mode 100644 index 0000000..9b1a770 --- /dev/null +++ b/src/lib/setters/dragoman_setter.go @@ -0,0 +1,44 @@ +package setters + +import ( + "fmt" + "os" + + "github.com/jeff-roche/biome/src/repos" +) + +const DRAGOMAN_ENV_KEY = "from_dragoman" + +// DragomanEnvironmentSetter will decrypt a secret that has been encrypted with dragoman +type DragomanEnvironmentSetter struct { + Encrypted string // The dragoman encrypted string + EnvKey string // The environment variable to be set + repo repos.DragomanRepoIfc // The repo that handles decrypting with dragoman +} + +// NewDragomanEnvironmentSetter is the builder function for DragomanEnvironmentSetter +func NewDragomanEnvironmentSetter(key string, val string) (*DragomanEnvironmentSetter, error) { + dragomanRepo, err := repos.NewDragomanRepo() + if err != nil { + return nil, err + } + + return &DragomanEnvironmentSetter{ + EnvKey: key, + Encrypted: val, + repo: dragomanRepo, + }, nil +} + +func (s DragomanEnvironmentSetter) SetEnv() error { + dec, err := s.repo.Decrypt(s.Encrypted) + if err != nil { + return err + } + + if s.EnvKey == "" { + return fmt.Errorf("no environment key specified") + } + + return os.Setenv(s.EnvKey, dec) +} diff --git a/src/lib/setters/secrets_manager_setter.go b/src/lib/setters/secrets_manager_setter.go index dcaf512..e421e6a 100644 --- a/src/lib/setters/secrets_manager_setter.go +++ b/src/lib/setters/secrets_manager_setter.go @@ -11,8 +11,6 @@ import ( const SECRETS_MANAGER_ENV_ARN_KEY = "secret_arn" const SECRETS_MANAGER_ENV_JSON_KEY = "secret_json_key" -// secretsManagerClientIfc allows us to mock out the call to secrets manager - // SecretsManagerEnvironmentSetter will set an environment variable // from a JSON secret stored in AWS Secrets Manager type SecretsManagerEnvironmentSetter struct { diff --git a/src/lib/setters/setter_helpers.go b/src/lib/setters/setter_helpers.go index 454b2ed..9cdab32 100644 --- a/src/lib/setters/setter_helpers.go +++ b/src/lib/setters/setter_helpers.go @@ -27,5 +27,10 @@ func getComplexSetter(key string, node map[string]interface{}) (EnvironmentSette return NewSecretsManagerEnvironmentSetter(key, node) } + // Dragoman Encrypted Secret + if val, exists := node[DRAGOMAN_ENV_KEY]; exists { + return NewDragomanEnvironmentSetter(key, val.(string)) + } + return nil, fmt.Errorf("unkown environment config for variable '%s'", key) } diff --git a/src/repos/dragoman.go b/src/repos/dragoman.go new file mode 100644 index 0000000..ce7c978 --- /dev/null +++ b/src/repos/dragoman.go @@ -0,0 +1,41 @@ +package repos + +import "github.com/meltwater/dragoman/cryptography" + +// The interface for the Secrets Manager Repository +type DragomanRepoIfc interface { + Decrypt(string) (string, error) +} + +// DragomanRepo handles decryption via dragoman +type DragomanRepo struct { + client interface{} +} + +// NewDragomanRepo is the builder function for DragomanRepo +func NewDragomanRepo() (*DragomanRepo, error) { + return &DragomanRepo{ + client: nil, + }, nil +} + +func (r DragomanRepo) Decrypt(val string) (string, error) { + + // Setup the allowed cryptography techniques + // Currently allow KMS Envelope encryption and Secrets Manager + strat, err := cryptography.NewWildcardDecryptionStrategy([]cryptography.StrategyBuilder{ + func() (cryptography.Decryptor, error) { return cryptography.NewKmsCryptoStrategy("") }, + func() (cryptography.Decryptor, error) { return cryptography.NewSecretsManagerCryptoStrategy("") }, + }) + + if err != nil { + return "", err + } + + data, err := strat.Decrypt(val) + if err != nil { + return "", err + } + + return string(data), nil +}