Introducing Retriever

aws dev go oss

The AWS SDK is great. Writing boilerplate for simple tasks is… Well, you have better things to do.

Whether creating CLIs or services, one task I routinely encounter is secrets management. With AWS, I might use Secrets Manager (advanced features such as versioning simplify programmatic rotation) or Parameter Store (cost savings at scale, works great for injecting container environment).

I find myself repeating boilerplate (load configuration, create client, retrieve secret):

func main() {
  ctx := context.TODO()

  cfg, err := config.LoadDefaultConfig(ctx)
  if err != nil {
    return nil, fmt.Errorf("ERROR: unable to load AWS configuration: %v", err.Error())
  }

  client := ssm.NewFromConfig(cfg)
  res, err := getParam(ctx, client, fmt.Sprintf("%s/%s", p, v))
  if err != nil {
    return nil, fmt.Errorf("ERROR: unable to retrieve %v/%v (%v)", p, v, err.Error())
  }
}

// ...

func getParam(ctx context.Context, c *ssm.Client, p string) (*ssm.GetParameterOutput, error) {
	i := ssm.GetParameterInput{
		Name:           aws.String(p),
		WithDecryption: true,
	}

	out, err := c.GetParameter(ctx, &i)
	if err != nil {
		return nil, err
	}

	return out, nil
}

Retriever abstracts secret management. Regardless of backend, simply specify required secrets as configuration (YAML or environment):

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

If this sounds useful, browse the project repo for more detail. Feel free to open issues or submit PRs for bugs or feature requests.