Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM amazonlinux:2

ADD https://github.com/s12v/exec-with-secrets/releases/latest/download/exec-with-secrets-linux-amd64 /exec-with-secrets
ADD https://github.com/johnrichardrinehart/exec-with-secrets/releases/latest/download/exec-with-secrets-linux-amd64 /exec-with-secrets

RUN chmod +x /exec-with-secrets

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![Build Status](https://travis-ci.com/s12v/exec-with-secrets.svg?branch=master)](https://travis-ci.com/s12v/exec-with-secrets)
[![codecov](https://codecov.io/gh/s12v/exec-with-secrets/branch/master/graph/badge.svg)](https://codecov.io/gh/s12v/exec-with-secrets)
[![Build Status](https://travis-ci.com/johnrichardrinehart/exec-with-secrets.svg?branch=master)](https://travis-ci.com/johnrichardrinehart/exec-with-secrets)
[![codecov](https://codecov.io/gh/johnrichardrinehart/exec-with-secrets/branch/master/graph/badge.svg)](https://codecov.io/gh/johnrichardrinehart/exec-with-secrets)

# Inject secrets from AWS KMS/SSM/Secrets Manager and Azure Key Vault into your app environment

Expand Down Expand Up @@ -69,4 +69,4 @@ make TAGS=awsssm

## Adding a new provider

See example PR: https://github.com/s12v/exec-with-secrets/pull/1
See example PR: https://github.com/johnrichardrinehart/exec-with-secrets/pull/1
10 changes: 7 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
module github.com/s12v/exec-with-secrets

require github.com/aws/aws-sdk-go-v2 v0.24.0
module github.com/johnrichardrinehart/exec-with-secrets

require (
github.com/Azure/azure-sdk-for-go v30.1.0+incompatible
github.com/Azure/go-autorest/autorest v0.11.19
github.com/Azure/go-autorest/autorest/azure/auth v0.1.0 // indirect
github.com/Azure/go-autorest/autorest/to v0.2.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.1.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.9.0
github.com/aws/aws-sdk-go-v2/config v1.8.1
github.com/aws/aws-sdk-go-v2/service/kms v1.6.0
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.6.0
github.com/aws/aws-sdk-go-v2/service/ssm v1.10.0
github.com/stretchr/testify v1.4.0 // indirect
)

go 1.13
42 changes: 33 additions & 9 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,30 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/aws/aws-sdk-go-v2 v0.24.0 h1:R0lL0krk9EyTI1vmO1ycoeceGZotSzCKO51LbPGq3rU=
github.com/aws/aws-sdk-go-v2 v0.24.0/go.mod h1:2LhT7UgHOXK3UXONKI5OMgIyoQL6zTAw/jwIeX6yqzw=
github.com/aws/aws-sdk-go-v2 v1.9.0 h1:+S+dSqQCN3MSU5vJRu1HqHrq00cJn6heIMU7X9hcsoo=
github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2/config v1.8.1 h1:AcAenV2NVwOViG+3ts73uT08L1olN4NBNNz7lUlHSUo=
github.com/aws/aws-sdk-go-v2/config v1.8.1/go.mod h1:AQtpYfVYjuuft4Dgh0jGSkPQJ9MvmK9vXfSub7oSXlI=
github.com/aws/aws-sdk-go-v2/credentials v1.4.1 h1:oDiUP50hKRwC6xAgESAj46lgL2prJRZQWnCBzn+TU/c=
github.com/aws/aws-sdk-go-v2/credentials v1.4.1/go.mod h1:dgGR+Qq7Wjcd4AOAW5Rf5Tnv3+x7ed6kETXyS9WCuAY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.0 h1:OxTAgH8Y4BXHD6PGCJ8DHx2kaZPCQfSTqmDsdRZFezE=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.0/go.mod h1:CpNzHK9VEFUCknu50kkB8z58AH2B5DvPP7ea1LHve/Y=
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.2 h1:d95cddM3yTm4qffj3P6EnP+TzX1SSkWaQypXSgT/hpA=
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.2/go.mod h1:BQV0agm+JEhqR+2RT5e1XTFIDcAAV0eW6z2trp+iduw=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.0 h1:VNJ5NLBteVXEwE2F1zEXVmyIH58mZ6kIQGJoC7C+vkg=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.0/go.mod h1:R1KK+vY8AfalhG1AOu5e35pOD2SdoPKQCFLTvnxiohk=
github.com/aws/aws-sdk-go-v2/service/kms v1.6.0 h1:HT72gDSqXoE9xZ7x7lvfyIjNOgvwT4Gqvjs0UsVrDBA=
github.com/aws/aws-sdk-go-v2/service/kms v1.6.0/go.mod h1:w7JuP9Oq1IKMFQPkNe3V6s9rOssXzOVEMNEqK1L1bao=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.6.0 h1:3vxYnnbPWwECs3xN+cu/bRefhynMOH6elQAxuHES01Q=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.6.0/go.mod h1:B+7C5UKdVq1ylkI/A6O8wcurFtaux0R1njePNPtKwoA=
github.com/aws/aws-sdk-go-v2/service/ssm v1.10.0 h1:kEYH8NMfMA5gC5MMcEr5gVtJxyGmaxIYJwwZ7T6ygNs=
github.com/aws/aws-sdk-go-v2/service/ssm v1.10.0/go.mod h1:4dXS5YNqI3SNbetQ7X7vfsMlX6ZnboJA2dulBwJx7+g=
github.com/aws/aws-sdk-go-v2/service/sso v1.4.0 h1:sHXMIKYS6YiLPzmKSvDpPmOpJDHxmAUgbiF49YNVztg=
github.com/aws/aws-sdk-go-v2/service/sso v1.4.0/go.mod h1:+1fpWnL96DL23aXPpMGbsmKe8jLTEfbjuQoA4WS1VaA=
github.com/aws/aws-sdk-go-v2/service/sts v1.7.0 h1:1at4e5P+lvHNl2nUktdM2/v+rpICg/QSEr9TO/uW9vU=
github.com/aws/aws-sdk-go-v2/service/sts v1.7.0/go.mod h1:0qcSMCyASQPN2sk/1KQLQ2Fh6yq8wm0HSDAimPhzCoM=
github.com/aws/smithy-go v1.8.0 h1:AEwwwXQZtUwP5Mz506FeXXrKBe0jA8gVM+1gEcSRooc=
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
Expand All @@ -57,7 +79,6 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
Expand All @@ -67,15 +88,18 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -134,7 +158,6 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -174,7 +197,8 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
11 changes: 6 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package main

import (
"fmt"
"github.com/s12v/exec-with-secrets/provider"
_ "github.com/s12v/exec-with-secrets/provider/awskms"
_ "github.com/s12v/exec-with-secrets/provider/awssecretsmanager"
_ "github.com/s12v/exec-with-secrets/provider/awsssm"
_ "github.com/s12v/exec-with-secrets/provider/azurekeyvault"
"os"
"os/exec"
"syscall"

"github.com/johnrichardrinehart/exec-with-secrets/provider"
_ "github.com/johnrichardrinehart/exec-with-secrets/provider/awskms"
_ "github.com/johnrichardrinehart/exec-with-secrets/provider/awssecretsmanager"
_ "github.com/johnrichardrinehart/exec-with-secrets/provider/awsssm"
_ "github.com/johnrichardrinehart/exec-with-secrets/provider/azurekeyvault"
)

func main() {
Expand Down
42 changes: 28 additions & 14 deletions provider/awskms/awskms.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import (
"encoding/base64"
"errors"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws/external"
"github.com/aws/aws-sdk-go-v2/service/kms"
"github.com/s12v/exec-with-secrets/provider"
"os"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/kms"
"github.com/johnrichardrinehart/exec-with-secrets/provider"
)

type KmsProvider struct {
Expand All @@ -22,21 +25,35 @@ const prefix = "{aws-kms}"
var decrypt func(awsKmsClient *kms.Client, input *kms.DecryptInput) (*kms.DecryptOutput, error)

func init() {
cfg, err := external.LoadDefaultAWSConfig()
decrypt = awsDecrypt

cfg, err := config.LoadDefaultConfig(
context.TODO(),
config.WithSharedConfigProfile("default"),
)
if err != nil {
panic("unable to load AWS-SDK config, " + err.Error())
fmt.Println("error obtaining AWS credentials:", err)
os.Exit(1)
}

decrypt = awsDecrypt
provider.Register(&KmsProvider{kms.New(cfg)})
opts := kms.Options{
Region: "us-east-1",
Credentials: cfg.Credentials,
}

kmsClient := kms.New(opts)

provider.Register(&KmsProvider{kmsClient})
}

func awsDecrypt(awsKmsClient *kms.Client, input *kms.DecryptInput) (*kms.DecryptOutput, error) {
ctx := context.Background()
if resp, err := awsKmsClient.DecryptRequest(input).Send(ctx); err != nil {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
resp, err := awsKmsClient.Decrypt(ctx, input)
if err != nil {
return nil, errors.New(fmt.Sprintf("KMS error: %v", err))
} else {
return resp.DecryptOutput, nil
return resp, nil
}
}

Expand All @@ -51,12 +68,9 @@ func (p *KmsProvider) Decode(val string) (string, error) {
}

input := &kms.DecryptInput{CiphertextBlob: blob}
if err = input.Validate(); err != nil {
return "", err
}

if output, err := decrypt(p.awsKmsClient, input); err != nil {
return "", err
return "", fmt.Errorf("failed to decrypt secret %s: %s", val, err)
} else {
return string(output.Plaintext), nil
}
Expand Down
49 changes: 30 additions & 19 deletions provider/awssecretsmanager/awsecretsmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ package awssecretsmanager
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/external"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
"github.com/s12v/exec-with-secrets/provider"
"os"
"regexp"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
"github.com/johnrichardrinehart/exec-with-secrets/provider"
)

type SecretsManagerProvider struct {
Expand All @@ -28,24 +30,36 @@ var fetch func(
input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error)

func init() {
cfg, err := external.LoadDefaultAWSConfig()
fetch = awsFetch // set global

cfg, err := config.LoadDefaultConfig(
context.TODO(),
config.WithSharedConfigProfile("default"),
)
if err != nil {
panic("unable to load AWS-SDK config, " + err.Error())
fmt.Println("error obtaining AWS credentials:", err)
os.Exit(1)
}

fetch = awsFetch
provider.Register(&SecretsManagerProvider{secretsmanager.New(cfg)})
opts := secretsmanager.Options{
Region: "us-east-1",
Credentials: cfg.Credentials,
}
smClient := secretsmanager.New(opts)

provider.Register(&SecretsManagerProvider{smClient}) // register externally
}

func awsFetch(
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.GetSecretValueOutput, nil
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
resp, err := awsClient.GetSecretValue(ctx, input)
if err != nil {
return nil, fmt.Errorf("AWS SecretsManager error: %v", err)
}
return resp, nil
}

func (p *SecretsManagerProvider) Match(val string) bool {
Expand All @@ -71,7 +85,7 @@ func (p *SecretsManagerProvider) decodeJson(val string, property string) (string
properties, _ := unmarshal(jsobj)
value, ok := properties[property]
if !ok {
return "", errors.New(fmt.Sprintf("property '%v' does not exist", property))
return "", fmt.Errorf("property '%v' does not exist", property)
}
return value, nil
}
Expand All @@ -80,12 +94,9 @@ func (p *SecretsManagerProvider) fetchString(name string) (string, error) {
input := &secretsmanager.GetSecretValueInput{
SecretId: aws.String(name),
}
if err := input.Validate(); err != nil {
return "", err
}

if output, err := fetch(p.awsClient, input); err != nil {
return "", err
return "", fmt.Errorf("failed to fetch secret %s: %s", name, err)
} else {
return *output.SecretString, nil
}
Expand Down
44 changes: 28 additions & 16 deletions provider/awsssm/awsssm.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import (
"context"
"errors"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws/external"
"github.com/aws/aws-sdk-go-v2/service/ssm"
"github.com/s12v/exec-with-secrets/provider"
"os"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/ssm"
"github.com/johnrichardrinehart/exec-with-secrets/provider"
)

type SsmProvider struct {
Expand All @@ -21,21 +24,34 @@ const prefix = "{aws-ssm}"
var fetch func(awsSsmClient *ssm.Client, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error)

func init() {
cfg, err := external.LoadDefaultAWSConfig()
fetch = awsFetch

cfg, err := config.LoadDefaultConfig(
context.TODO(),
config.WithSharedConfigProfile("default"),
)
if err != nil {
panic("unable to load AWS-SDK config, " + err.Error())
fmt.Println("error obtaining AWS credentials:", err)
os.Exit(1)
}

fetch = awsFetch
provider.Register(&SsmProvider{ssm.New(cfg)})
opts := ssm.Options{
Credentials: cfg.Credentials,
}

ssmClient := ssm.New(opts)

provider.Register(&SsmProvider{ssmClient})
}

func awsFetch(awsSsmClient *ssm.Client, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) {
ctx := context.Background()
if resp, err := awsSsmClient.GetParameterRequest(input).Send(ctx); err != nil {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
resp, err := awsSsmClient.GetParameter(ctx, input)
if err != nil {
return nil, errors.New(fmt.Sprintf("SSM error: %v", err))
} else {
return resp.GetParameterOutput, nil
return resp, nil
}
}

Expand All @@ -45,14 +61,10 @@ func (p *SsmProvider) Match(val string) bool {

func (p *SsmProvider) Decode(val string) (string, error) {
name := val[len(prefix):]
var withEncryption = true
input := &ssm.GetParameterInput{Name: &name, WithDecryption: &withEncryption}
if err := input.Validate(); err != nil {
return "", err
}
input := &ssm.GetParameterInput{Name: &name, WithDecryption: true}

if output, err := fetch(p.awsSsmClient, input); err != nil {
return "", err
return "", fmt.Errorf("failed to fetch secret %s: %s", name, err)
} else {
return *output.Parameter.Value, nil
}
Expand Down
Loading