Skip to content

Commit

Permalink
AWS vault and SOPS support
Browse files Browse the repository at this point in the history
  • Loading branch information
heppu committed Oct 20, 2023
1 parent 0ba5de6 commit ca5eaa9
Show file tree
Hide file tree
Showing 6 changed files with 782 additions and 0 deletions.
131 changes: 131 additions & 0 deletions awsvault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package mageutil

import (
"context"
"fmt"
"os"

"github.com/99designs/aws-vault/v6/iso8601"
"github.com/99designs/aws-vault/v7/cli"
"github.com/99designs/aws-vault/v7/vault"
"github.com/99designs/keyring"
"github.com/alecthomas/kingpin/v2"
"github.com/aws/aws-sdk-go-v2/aws"
)

// AwsVault runs embedded aws-vault command with given args.
func AwsVault(ctx context.Context, args ...string) error {
app := kingpin.New("aws-vault", "A vault for securely storing and accessing AWS credentials in development environments.")
app.Version("Embedded")

a := cli.ConfigureGlobals(app)
cli.ConfigureAddCommand(app, a)
cli.ConfigureRemoveCommand(app, a)
cli.ConfigureListCommand(app, a)
cli.ConfigureRotateCommand(app, a)
cli.ConfigureExecCommand(app, a)
cli.ConfigureExportCommand(app, a)
cli.ConfigureClearCommand(app, a)
cli.ConfigureLoginCommand(app, a)
cli.ConfigureProxyCommand(app)

_, err := app.Parse(args)
return err
}

// AwsVaultExec executes command inside subshell with aws credentials.
func AwsVaultExec(ctx context.Context, awsProfile string, args ...string) error {
return AwsVault(ctx, append([]string{"exec", awsProfile, "--"}, args...)...)
}

// AwsWithEnvCredentials sets aws credentials in environment variables, executes given functions and unsets env.
func AwsWithEnvCredentials(ctx context.Context, awsProfile string, fn func() error) error {
env, err := AwsVaultEnv(ctx, awsProfile)
if err != nil {
return err
}

defer func() {
for k := range env {
_ = os.Unsetenv(k)
}
}()

for k, v := range env {
_ = os.Setenv(k, v)
}

return fn()
}

// AwsVaultCredentials fetches aws vault credentials.
func AwsVaultCredentials(ctx context.Context, awsProfile string) (aws.Credentials, error) {
app := kingpin.New("aws-vault", "A vault for securely storing and accessing AWS credentials in development environments.")
app.Version("Embedded")
a := cli.ConfigureGlobals(app)
input := cli.ExportCommandInput{
ProfileName: awsProfile,
Config: vault.ProfileConfig{
MfaPromptMethod: a.PromptDriver(false),
},
}

f, err := a.AwsConfigFile()
if err != nil {
return aws.Credentials{}, err
}
keyring, err := a.Keyring()
if err != nil {
return aws.Credentials{}, err
}

return fetchCredentials(input, f, keyring)
}

// AwsVaultEnv fetches aws vault credentials in env format.
func AwsVaultEnv(ctx context.Context, awsProfile string) (map[string]string, error) {
creds, err := AwsVaultCredentials(ctx, awsProfile)
if err != nil {
return nil, err
}

return credentialToEnvMap(creds), nil
}

func fetchCredentials(input cli.ExportCommandInput, f *vault.ConfigFile, keyring keyring.Keyring) (aws.Credentials, error) {
if os.Getenv("AWS_VAULT") != "" {
return aws.Credentials{}, fmt.Errorf("in an existing aws-vault subshell; 'exit' from the subshell or unset AWS_VAULT to force")
}

config, err := vault.NewConfigLoader(input.Config, f, input.ProfileName).GetProfileConfig(input.ProfileName)
if err != nil {
return aws.Credentials{}, fmt.Errorf("error loading config: %w", err)
}

ckr := &vault.CredentialKeyring{Keyring: keyring}
credsProvider, err := vault.NewTempCredentialsProvider(config, ckr, input.NoSession, false)
if err != nil {
return aws.Credentials{}, fmt.Errorf("error getting temporary credentials: %w", err)
}

creds, err := credsProvider.Retrieve(context.TODO())
if err != nil {
return aws.Credentials{}, fmt.Errorf("failed to get credentials for %s: %w", input.ProfileName, err)
}

return creds, nil
}

func credentialToEnvMap(creds aws.Credentials) map[string]string {
env := make(map[string]string)
env["AWS_ACCESS_KEY_ID"] = creds.AccessKeyID
env["AWS_SECRET_ACCESS_KEY"] = creds.SecretAccessKey

if creds.SessionToken != "" {
env["AWS_SESSION_TOKEN"] = creds.SessionToken
}
if creds.CanExpire {
env["AWS_CREDENTIAL_EXPIRATION"] = iso8601.Format(creds.Expires)
}
return env
}
77 changes: 77 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ go 1.21
toolchain go1.21.2

require (
github.com/99designs/aws-vault/v6 v6.6.2
github.com/99designs/aws-vault/v7 v7.2.0
github.com/99designs/keyring v1.2.2
github.com/alecthomas/kingpin/v2 v2.3.2
github.com/aws/aws-sdk-go-v2 v1.21.2
github.com/getsops/sops/v3 v3.8.1
github.com/golangci/golangci-lint v1.54.2
github.com/google/go-licenses v1.6.0
github.com/google/yamlfmt v0.10.0
Expand All @@ -18,25 +24,53 @@ require (
require (
4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
4d63.com/gochecknoglobals v0.2.1 // indirect
cloud.google.com/go/compute v1.23.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.2 // indirect
cloud.google.com/go/kms v1.15.2 // indirect
filippo.io/age v1.1.1 // indirect
github.com/4meepo/tagalign v1.3.2 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/Abirdcfly/dupword v0.0.13 // indirect
github.com/Antonboom/errname v0.1.12 // indirect
github.com/Antonboom/nilnil v0.1.7 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/OpenPeeDeeP/depguard/v2 v2.1.0 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect
github.com/RageCage64/multilinediff v0.2.0 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/alexkohler/nakedret/v2 v2.0.2 // indirect
github.com/alexkohler/prealloc v1.0.0 // indirect
github.com/alingse/asasalint v0.0.11 // indirect
github.com/ashanbrown/forbidigo v1.6.0 // indirect
github.com/ashanbrown/makezero v1.1.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.18.44 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.42 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.12 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.44 // indirect
github.com/aws/aws-sdk-go-v2/service/iam v1.19.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.36 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.24.6 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.15.1 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.23.1 // indirect
github.com/aws/smithy-go v1.15.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bkielbasa/cyclop v1.2.1 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/blizzy78/varnamelen v0.8.0 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect
github.com/bombsimon/wsl/v3 v3.4.0 // indirect
Expand All @@ -46,13 +80,18 @@ require (
github.com/butuzov/ireturn v0.2.0 // indirect
github.com/butuzov/mirror v1.1.0 // indirect
github.com/ccojocar/zxcvbn-go v1.0.1 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/charithe/durationcheck v0.0.10 // indirect
github.com/chavacava/garif v0.1.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/curioswitch/go-reassign v0.2.0 // indirect
github.com/daixiang0/gci v0.11.2 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/denis-tingaikin/go-header v0.4.3 // indirect
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/esimonov/ifshort v1.0.4 // indirect
github.com/ettle/strcase v0.1.1 // indirect
Expand All @@ -61,7 +100,9 @@ require (
github.com/firefart/nonamedreturns v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/getsops/gopgagent v0.0.0-20170926210634-4d7ea76ff71a // indirect
github.com/go-critic/go-critic v0.9.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
Expand All @@ -76,7 +117,9 @@ require (
github.com/go-toolsmith/typep v1.1.0 // indirect
github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
Expand All @@ -90,15 +133,28 @@ require (
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/licenseclassifier v0.0.0-20210722185704-3043a050f148 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.4.2 // indirect
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/vault/api v1.10.0 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
Expand All @@ -113,10 +169,12 @@ require (
github.com/kkHAIKE/contextcheck v1.1.4 // indirect
github.com/kulti/thelper v0.6.3 // indirect
github.com/kunwardeep/paralleltest v1.0.8 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/kyoh86/exportloopref v0.1.11 // indirect
github.com/ldez/gomoddirectives v0.2.3 // indirect
github.com/ldez/tagliatelle v0.5.0 // indirect
github.com/leonklingele/grouper v1.1.1 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/lufeee/execinquery v1.2.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
Expand All @@ -126,18 +184,23 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-tty v0.0.4 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mbilski/exhaustivestruct v1.2.0 // indirect
github.com/mgechev/revive v1.3.4 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moricho/tparallel v0.3.1 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/nishanths/exhaustive v0.11.0 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
github.com/nunnatsa/ginkgolinter v0.14.0 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/polyfloyd/go-errorlint v1.4.5 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
Expand All @@ -149,8 +212,10 @@ require (
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/ryancurrah/gomodguard v1.3.0 // indirect
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
Expand All @@ -163,6 +228,7 @@ require (
github.com/sivchari/containedctx v1.0.3 // indirect
github.com/sivchari/nosnakecase v1.7.0 // indirect
github.com/sivchari/tenv v1.7.1 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/sonatard/noctx v0.0.2 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/sourcegraph/go-diff v0.7.0 // indirect
Expand All @@ -186,9 +252,11 @@ require (
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/ultraware/funlen v0.1.0 // indirect
github.com/ultraware/whitespace v0.0.5 // indirect
github.com/urfave/cli v1.22.14 // indirect
github.com/uudashr/gocognit v1.0.7 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xen0n/gosmopolitan v1.2.2 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
github.com/yagipy/maintidx v1.0.0 // indirect
github.com/yeya24/promlinter v0.2.0 // indirect
github.com/ykadowak/zerologlint v0.1.3 // indirect
Expand All @@ -202,9 +270,18 @@ require (
golang.org/x/exp/typeparams v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sync v0.4.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/api v0.146.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect
google.golang.org/grpc v1.58.3 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect
Expand Down
Loading

0 comments on commit ca5eaa9

Please sign in to comment.