retriever

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 23, 2022 License: MIT Imports: 9 Imported by: 0

README

retriever

Golden Retriever Puppies

Easily fetch secrets from AWS Parameter Store or Secrets Manager.

After a week where I wrote two CLIs and a small web service that required copying and pasting the same secret-fetching boilerplate, I decided to abstract the boring details.

Usage

Configure using YAML or environment thanks to viper. Some examples...

Parameter Store with many secrets under one prefix:

type: parameter
prefix: /foo
credentials:
  - BAR
  - BAZ_QUX

Parameter Store with different secret prefixes (note: no leading /):

type: parameter
credentials:
  - foo/BAR
  - baz/QUX

Same rules for Secrets Manager, just change type:

type: secret
prefix: /foo
credentials:
  - BAR
  - BAZ_QUX

Environment variables are prefixed with RTVR_ and have the same keys as YAML.

❯ RTVR_TYPE="secret" RTVR_PREFIX="/foo" RTVR_CREDENTIALS="BAR" aws-vault exec dev -- go run main.go
INFO: retriever not config found; using environment
RESULT: map[BAR:{"key1":"value1","key2":"value2"}]%

❯ RTVR_TYPE="parameter" RTVR_CREDENTIALS="foo/BAR QUX" aws-vault exec dev -- go run main.go
INFO: retriever not config found; using environment
RESULT: map[QUX:top secret foo/BAR:baz]%

To dispel any magic, test code is just:

package main

import (
        "fmt"
        "log"

        "github.com/deadlysyn/retriever"
)

func main() {
        c, err := retriever.Fetch()
        if err != nil {
                log.Fatalf("CALLER: %v", err)
        }
        fmt.Printf("RESULT: %+v", c)
}

Of course the idea is not to print things, but to use returned values. Fetch() returns a map of credentials with keys equal to secret names. Let's see that in action:

type: parameter
prefix: /app/dev
credentials:
  - CONSUMER_SECRET
  - CONSUMER_KEY
  - OAUTH_TOKEN
  - OAUTH_TOKEN_SECRET
package main

import (
    // ...

    "github.com/deadlysyn/retriever"
)

var (
    creds = make(map[string]string)
)

func init() {
    creds, err := retriever.Fetch()
    if err != nil {
        log.Fatalf("deal with it: %v", err)
    }
}

func getClient(ctx context.Context) *http.Client {
    keyDERBlock, _ := pem.Decode([]byte(creds["CONSUMER_SECRET"]))
    privateKey, _ := x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes)

    config := oauth1.Config{
        ConsumerKey: creds["CONSUMER_KEY"],
        // etc...
    }

    tok := &oauth1.Token{
        Token:       creds["OAUTH_TOKEN"],
        TokenSecret: creds["OAUTH_TOKEN_SECRET"],
    }

    return config.Client(ctx, tok)
}

// ...

TODO

  • Secrets Manager versioning
  • Customer managed KMS keys
  • Values other than strings (?)
  • Ideas? Open an issue or PR.

Thanks

On the shoulders of giants.

Documentation

Overview

Package retriever provides primitives for interacting with AWS Parameter Store and Secrets Manager.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Fetch

func Fetch() (map[string]string, error)

Fetch retrieves secrets specified via configuration or environment from Parameter Store or Secrets Manager and returns a map with secret names as keys.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL