diff --git a/README.md b/README.md index b9de231..2a466c0 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,12 @@ This small utility looks for prefixed variables in environment and replaces them - `{aws-sm}/app/staging/param{prop1}` - loads secret `/app/staging/param` from AWS Secrets Manager and takes `prop1` property - `{az-kv}vault/name` - loads secret `name` from Azure Key Vault `vault` -Then it runs `exec` system call and replaces itself with your app. -The secrets are only available to your application and not accessible with `docker inspect`. +Then it runs `exec` system call. **The secrets are only available to your application and not accessible with `docker inspect`** + +Basic example: +``` +SECRET="{aws-ssm}/my/secret" exec-with-secrets myapp # $SECRET is plaintext in myapp environment +``` Access: - The default credentials chain is used for AWS access @@ -26,7 +30,7 @@ Access: ## Examples -### Wrap an executable +### Wrap executable ``` # Download the latest binary diff --git a/go.mod b/go.mod index 8d6efef..0953d4d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/s12v/exec-with-secrets -require github.com/aws/aws-sdk-go-v2 v0.8.0 +require github.com/aws/aws-sdk-go-v2 v0.9.0 require ( github.com/Azure/azure-sdk-for-go v30.0.0+incompatible diff --git a/go.sum b/go.sum index 5252483..82ed387 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/aws/aws-sdk-go-v2 v0.8.0 h1:IyCzxvwRVe2ehXfi7YMsVxaVU6JvaH58ZO7uPFS3HlY= github.com/aws/aws-sdk-go-v2 v0.8.0/go.mod h1:sa1GePZ/LfBGI4dSq30f6uR4Tthll8axxtEPvlpXZ8U= +github.com/aws/aws-sdk-go-v2 v0.9.0 h1:dWtJKGRFv3UZkMBQaIzMsF0/y4ge3iQPWTzeC4r/vl4= +github.com/aws/aws-sdk-go-v2 v0.9.0/go.mod h1:sa1GePZ/LfBGI4dSq30f6uR4Tthll8axxtEPvlpXZ8U= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/provider/awskms/awskms.go b/provider/awskms/awskms.go index 26a8673..558ebb5 100644 --- a/provider/awskms/awskms.go +++ b/provider/awskms/awskms.go @@ -14,12 +14,12 @@ import ( ) type KmsProvider struct { - awsKmsClient *kms.KMS + awsKmsClient *kms.Client } const prefix = "{aws-kms}" -var decrypt func(awsKmsClient *kms.KMS, input *kms.DecryptInput) (*kms.DecryptOutput, error) +var decrypt func(awsKmsClient *kms.Client, input *kms.DecryptInput) (*kms.DecryptOutput, error) func init() { cfg, err := external.LoadDefaultAWSConfig() @@ -31,12 +31,12 @@ func init() { provider.Register(&KmsProvider{kms.New(cfg)}) } -func awsDecrypt(awsKmsClient *kms.KMS, input *kms.DecryptInput) (*kms.DecryptOutput, error) { +func awsDecrypt(awsKmsClient *kms.Client, input *kms.DecryptInput) (*kms.DecryptOutput, error) { ctx := context.Background() if resp, err := awsKmsClient.DecryptRequest(input).Send(ctx); err != nil { return nil, errors.New(fmt.Sprintf("KMS error: %v", err)) } else { - return resp, nil + return resp.DecryptOutput, nil } } diff --git a/provider/awskms/awskms_test.go b/provider/awskms/awskms_test.go index bfce065..c5bb3b6 100644 --- a/provider/awskms/awskms_test.go +++ b/provider/awskms/awskms_test.go @@ -8,7 +8,7 @@ import ( ) func init() { - decrypt = func(awsKmsClient *kms.KMS, input *kms.DecryptInput) (*kms.DecryptOutput, error) { + decrypt = func(awsKmsClient *kms.Client, input *kms.DecryptInput) (*kms.DecryptOutput, error) { return &kms.DecryptOutput{Plaintext: input.CiphertextBlob}, nil } } diff --git a/provider/awssecretsmanager/awsecretsmanager.go b/provider/awssecretsmanager/awsecretsmanager.go index 5859211..d4bcf17 100644 --- a/provider/awssecretsmanager/awsecretsmanager.go +++ b/provider/awssecretsmanager/awsecretsmanager.go @@ -16,7 +16,7 @@ import ( ) type SecretsManagerProvider struct { - awsClient *secretsmanager.SecretsManager + awsClient *secretsmanager.Client } const prefix = "{aws-sm}" @@ -24,7 +24,7 @@ const prefix = "{aws-sm}" var postfix = regexp.MustCompile("{[^{^}]+}$") var fetch func( - awsClient *secretsmanager.SecretsManager, + awsClient *secretsmanager.Client, input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error) func init() { @@ -38,13 +38,13 @@ func init() { } func awsFetch( - awsClient *secretsmanager.SecretsManager, + awsClient *secretsmanager.Client, input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error) { ctx := context.Background() if resp, err := awsClient.GetSecretValueRequest(input).Send(ctx); err != nil { return nil, errors.New(fmt.Sprintf("AWS SecretsManager error: %v", err)) } else { - return resp, nil + return resp.GetSecretValueOutput, nil } } diff --git a/provider/awssecretsmanager/awsecretsmanager_test.go b/provider/awssecretsmanager/awsecretsmanager_test.go index 08e7da0..4f1c130 100644 --- a/provider/awssecretsmanager/awsecretsmanager_test.go +++ b/provider/awssecretsmanager/awsecretsmanager_test.go @@ -25,7 +25,7 @@ func TestSecretsManagerProvider_Decode(t *testing.T) { value := "boom" fetch = func( - awsClient *secretsmanager.SecretsManager, + awsClient *secretsmanager.Client, input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error) { if *input.SecretId != "/foo/bar" { t.Fatalf("unexpected SecretId %v", input.SecretId) @@ -44,7 +44,7 @@ func TestSecretsManagerProvider_DecodeJson(t *testing.T) { value := `{"prop1": "aaa", "prop2": "bbb"}` fetch = func( - awsClient *secretsmanager.SecretsManager, + awsClient *secretsmanager.Client, input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error) { if *input.SecretId != "/foo/bar" { t.Fatalf("unexpected SecretId %v", *input.SecretId) @@ -63,7 +63,7 @@ func TestSecretsManagerProvider_DecodeJson_MissingProperty(t *testing.T) { value := `{"prop1": "foo", "prop2": "bar"}` fetch = func( - awsClient *secretsmanager.SecretsManager, + awsClient *secretsmanager.Client, input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error) { if *input.SecretId != "/foo/bar" { t.Fatalf("unexpected SecretId %v", *input.SecretId) @@ -81,7 +81,7 @@ func TestSecretsManagerProvider_Decode_FetchError(t *testing.T) { provider := SecretsManagerProvider{} fetch = func( - awsClient *secretsmanager.SecretsManager, + awsClient *secretsmanager.Client, input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error) { return nil, errors.New("test error") @@ -96,7 +96,7 @@ func TestSecretsManagerProvider_DecodeJson_FetchError(t *testing.T) { provider := SecretsManagerProvider{} fetch = func( - awsClient *secretsmanager.SecretsManager, + awsClient *secretsmanager.Client, input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error) { return nil, errors.New("test error") diff --git a/provider/awsssm/awsssm.go b/provider/awsssm/awsssm.go index ec382a8..4f9c93e 100644 --- a/provider/awsssm/awsssm.go +++ b/provider/awsssm/awsssm.go @@ -13,12 +13,12 @@ import ( ) type SsmProvider struct { - awsSsmClient *ssm.SSM + awsSsmClient *ssm.Client } const prefix = "{aws-ssm}" -var fetch func(awsSsmClient *ssm.SSM, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) +var fetch func(awsSsmClient *ssm.Client, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) func init() { cfg, err := external.LoadDefaultAWSConfig() @@ -30,12 +30,12 @@ func init() { provider.Register(&SsmProvider{ssm.New(cfg)}) } -func awsFetch(awsSsmClient *ssm.SSM, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) { +func awsFetch(awsSsmClient *ssm.Client, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) { ctx := context.Background() if resp, err := awsSsmClient.GetParameterRequest(input).Send(ctx); err != nil { return nil, errors.New(fmt.Sprintf("SSM error: %v", err)) } else { - return resp, nil + return resp.GetParameterOutput, nil } } diff --git a/provider/awsssm/awsssm_test.go b/provider/awsssm/awsssm_test.go index 760d104..e2c00af 100644 --- a/provider/awsssm/awsssm_test.go +++ b/provider/awsssm/awsssm_test.go @@ -23,7 +23,7 @@ func TestSsmProvider_Decode(t *testing.T) { ssmProvider := SsmProvider{} value := "boom" - fetch = func(awsSsmClient *ssm.SSM, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) { + fetch = func(awsSsmClient *ssm.Client, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) { if *input.Name != "/foo/bar" { t.Fatalf("unexpected name %v", input.Name) }