go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers-sdk/v1/vault/awssecretsmanager/secretsmanager.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package awssecretsmanager
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/aws/aws-sdk-go-v2/aws"
    10  	"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
    11  	"github.com/aws/aws-sdk-go/aws/arn"
    12  	"github.com/rs/zerolog/log"
    13  	"go.mondoo.com/cnquery/providers-sdk/v1/vault"
    14  )
    15  
    16  type Option func(*Vault)
    17  
    18  func New(cfg aws.Config, opts ...Option) *Vault {
    19  	v := &Vault{
    20  		cfg: cfg.Copy(),
    21  	}
    22  	for _, opt := range opts {
    23  		opt(v)
    24  	}
    25  	return v
    26  }
    27  
    28  func WithKmsKey(kmsKeyID string) Option {
    29  	return func(v *Vault) {
    30  		v.kmsKeyID = kmsKeyID
    31  	}
    32  }
    33  
    34  type Vault struct {
    35  	cfg      aws.Config
    36  	kmsKeyID string
    37  }
    38  
    39  func (v *Vault) About(context.Context, *vault.Empty) (*vault.VaultInfo, error) {
    40  	return &vault.VaultInfo{Name: "AWS Secrets Manager"}, nil
    41  }
    42  
    43  func (v *Vault) Get(ctx context.Context, id *vault.SecretID) (*vault.Secret, error) {
    44  	// create the client
    45  	parsedArn, err := arn.Parse(id.Key)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	cfg := v.cfg.Copy()
    50  	cfg.Region = parsedArn.Region
    51  	c := secretsmanager.NewFromConfig(cfg)
    52  
    53  	// retrieve secret
    54  	log.Debug().Str("secret-id", id.Key).Msg("getting cred from aws secrets manager")
    55  	out, err := c.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{
    56  		SecretId: &id.Key,
    57  	})
    58  	if err != nil {
    59  		log.Debug().Err(err).Str("secret-id", id.Key).Msg("could not retrieve secret from aws secret manager")
    60  		return nil, vault.NotFoundError
    61  	}
    62  
    63  	// NOTE: we cannot use out.SecretBinary since it is not guaranteed to be set
    64  	var data []byte
    65  	if out.SecretString != nil {
    66  		data = []byte(*out.SecretString)
    67  	} else {
    68  		data = out.SecretBinary
    69  	}
    70  
    71  	return &vault.Secret{
    72  		Key:  id.Key,
    73  		Data: data,
    74  		// we do not know the encoding here, but the default is binary
    75  		Encoding: vault.SecretEncoding_encoding_binary,
    76  	}, nil
    77  }
    78  
    79  func (v *Vault) Set(ctx context.Context, cred *vault.Secret) (*vault.SecretID, error) {
    80  	var kmsKeyID *string
    81  	if len(v.kmsKeyID) > 0 {
    82  		kmsKeyID = &v.kmsKeyID
    83  	}
    84  
    85  	c := secretsmanager.NewFromConfig(v.cfg)
    86  	o, err := c.CreateSecret(ctx, &secretsmanager.CreateSecretInput{
    87  		Name:         &cred.Key,
    88  		SecretBinary: cred.Data,
    89  		KmsKeyId:     kmsKeyID,
    90  	})
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	return &vault.SecretID{Key: *o.ARN}, err
    96  }