Skip to content

Commit

Permalink
aws: unify errors returned to client
Browse files Browse the repository at this point in the history
This commit changes the errors returned to
the KES client when KES fails to create,
get or delete a master key for some (unexpected)
reason.

Before this commit, the KES server returned errors
that happened between KES and AWS Secrets Manager to
the client. This had two downsides:
 - The client could become aware of what KMS/key store
   the KES server is using.
 - The client may encounter AWS-specific error messages.

Now, the KES server returns always the same Bad Gateway error
with a generic error message indicating that the communication between
the KES server and its KMS failed for some reason.

This behavior is already implemented by the Gemalto KeySecure
integration.
  • Loading branch information
Andreas Auernhammer authored and harshavardhana committed Aug 1, 2020
1 parent 4a60cd5 commit 1bd93ff
Showing 1 changed file with 21 additions and 28 deletions.
49 changes: 21 additions & 28 deletions internal/aws/secrets-manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package aws

import (
"errors"
"fmt"
"log"
"net/http"
Expand Down Expand Up @@ -63,6 +62,12 @@ type SecretsManager struct {

var _ secret.Remote = (*SecretsManager)(nil)

var (
errCreateKey = kes.NewError(http.StatusBadGateway, "bad gateway: failed to create key")
errGetKey = kes.NewError(http.StatusBadGateway, "bad gateway: failed to access key")
errDeleteKey = kes.NewError(http.StatusBadGateway, "bad gateway: failed to delete key")
)

// Create stores the given key-value pair at the AWS SecretsManager
// if and only if it doesn't exists. If such an entry already exists
// it returns kes.ErrKeyExists.
Expand All @@ -72,8 +77,8 @@ var _ secret.Remote = (*SecretsManager)(nil)
// encrypting secrets at the AWS SecretsManager.
func (s *SecretsManager) Create(key, value string) error {
if s.client == nil {
s.log(errNoConnection)
return errNoConnection
s.logf("aws: no connection to AWS secrets manager: '%s'", s.Addr)
return errCreateKey
}

createOpt := secretsmanager.CreateSecretInput{
Expand All @@ -90,9 +95,8 @@ func (s *SecretsManager) Create(key, value string) error {
return kes.ErrKeyExists
}
}
err = fmt.Errorf("aws: failed to create '%s': %v", key, err)
s.log(err)
return err
s.logf("aws: failed to create '%s': %v", key, err)
return errCreateKey
}
return nil
}
Expand All @@ -101,8 +105,8 @@ func (s *SecretsManager) Create(key, value string) error {
// If no entry for key exists, it returns kes.ErrKeyNotFound.
func (s *SecretsManager) Get(key string) (string, error) {
if s.client == nil {
s.log(errNoConnection)
return "", errNoConnection
s.logf("aws: no connection to AWS secrets manager: '%s'", s.Addr)
return "", errGetKey
}

response, err := s.client.GetSecretValue(&secretsmanager.GetSecretValueInput{
Expand All @@ -117,9 +121,8 @@ func (s *SecretsManager) Get(key string) (string, error) {
return "", kes.ErrKeyNotFound
}
}
err = fmt.Errorf("aws: failed to read '%s': %v", key, err)
s.log(err)
return "", err
s.logf("aws: failed to read '%s': %v", key, err)
return "", errGetKey
}

// AWS has two different ways to store a secret. Either as
Expand All @@ -139,8 +142,8 @@ func (s *SecretsManager) Get(key string) (string, error) {
// it exists.
func (s *SecretsManager) Delete(key string) error {
if s.client == nil {
s.log(errNoConnection)
return errNoConnection
s.logf("aws: no connection to AWS secrets manager: '%s'", s.Addr)
return errDeleteKey
}

_, err := s.client.DeleteSecret(&secretsmanager.DeleteSecretInput{
Expand All @@ -153,9 +156,8 @@ func (s *SecretsManager) Delete(key string) error {
return nil
}
}
err = fmt.Errorf("aws: failed to delete '%s': %v", key, err)
s.log(err)
return err
s.logf("aws: failed to delete '%s': %v", key, err)
return errDeleteKey
}
return nil
}
Expand Down Expand Up @@ -196,19 +198,10 @@ func (s *SecretsManager) Authenticate() error {
return nil
}

// errNoConnection is the error returned and logged by
// the key store if the AWS Secrets Manager client hasn't
// been initialized.
//
// This error is returned by Create, Get, Delete, a.s.o.
// in case of an invalid configuration - i.e. when Authenticate()
// hasn't been called.
var errNoConnection = errors.New("aws: no connection to AWS secrets manager")

func (s *SecretsManager) log(v ...interface{}) {
func (s *SecretsManager) logf(format string, v ...interface{}) {
if s.ErrorLog == nil {
log.Println(v...)
log.Printf(format, v...)
} else {
s.ErrorLog.Println(v...)
s.ErrorLog.Printf(format, v...)
}
}

0 comments on commit 1bd93ff

Please sign in to comment.