-
Notifications
You must be signed in to change notification settings - Fork 820
Adds support to S3 server side encryption using AWS KMS #3651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0925ad6
192b1ab
3fdf51c
183895d
c9d03a8
ea13344
61db766
1132d86
cf146e5
8ca51e3
590c0c8
62082bb
2972428
bffcc7d
2536269
93ec9e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package aws | ||
|
||
import ( | ||
"encoding/base64" | ||
"encoding/json" | ||
"flag" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
const ( | ||
// SSEKMS config type constant to configure S3 server side encryption using KMS | ||
// https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html | ||
SSEKMS = "SSE-KMS" | ||
sseKMSType = "aws:kms" | ||
// SSES3 config type constant to configure S3 server side encryption with AES-256 | ||
// https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html | ||
SSES3 = "SSE-S3" | ||
sseS3Type = "AES256" | ||
) | ||
|
||
// SSEParsedConfig configures server side encryption (SSE) | ||
// struct used internally to configure AWS S3 | ||
type SSEParsedConfig struct { | ||
ServerSideEncryption string | ||
KMSKeyID *string | ||
KMSEncryptionContext *string | ||
Comment on lines
+26
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a big fan of pointers in config structs. You can achieve the same assuming empty string means not configured (which should be fine in this context). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AWS lib uses string pointers several times in there. Removing string pointers from |
||
} | ||
|
||
// SSEConfig configures S3 server side encryption | ||
// struct that is going to receive user input (through config file or CLI) | ||
type SSEConfig struct { | ||
Type string `yaml:"type"` | ||
KMSKeyID string `yaml:"kms_key_id"` | ||
KMSEncryptionContext string `yaml:"kms_encryption_context"` | ||
} | ||
|
||
// RegisterFlagsWithPrefix adds the flags required to config this to the given FlagSet | ||
func (cfg *SSEConfig) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { | ||
f.StringVar(&cfg.Type, prefix+"type", "", "Enable AWS Server Side Encryption. Only SSE-S3 and SSE-KMS are supported") | ||
f.StringVar(&cfg.KMSKeyID, prefix+"kms-key-id", "", "KMS Key ID used to encrypt objects in S3") | ||
f.StringVar(&cfg.KMSEncryptionContext, prefix+"kms-encryption-context", "", "KMS Encryption Context used for object encryption. It expects a JSON as a string.") | ||
} | ||
|
||
// NewSSEParsedConfig creates a struct to configure server side encryption (SSE) | ||
func NewSSEParsedConfig(cfg SSEConfig) (*SSEParsedConfig, error) { | ||
switch cfg.Type { | ||
case SSES3: | ||
return &SSEParsedConfig{ | ||
ServerSideEncryption: sseS3Type, | ||
}, nil | ||
case SSEKMS: | ||
if cfg.KMSKeyID == "" { | ||
return nil, errors.New("KMS key id must be passed when SSE-KMS encryption is selected") | ||
} | ||
|
||
parsedKMSEncryptionContext, err := parseKMSEncryptionContext(cfg.KMSEncryptionContext) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "failed to parse KMS encryption context") | ||
} | ||
|
||
return &SSEParsedConfig{ | ||
ServerSideEncryption: sseKMSType, | ||
KMSKeyID: &cfg.KMSKeyID, | ||
KMSEncryptionContext: parsedKMSEncryptionContext, | ||
}, nil | ||
default: | ||
return nil, errors.New("SSE type is empty or invalid") | ||
} | ||
} | ||
|
||
func parseKMSEncryptionContext(kmsEncryptionContext string) (*string, error) { | ||
if kmsEncryptionContext == "" { | ||
return nil, nil | ||
} | ||
|
||
// validates if kmsEncryptionContext is a valid JSON | ||
jsonKMSEncryptionContext, err := json.Marshal(json.RawMessage(kmsEncryptionContext)) | ||
pstibrany marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err != nil { | ||
return nil, errors.Wrap(err, "failed to marshal KMS encryption context") | ||
} | ||
|
||
parsedKMSEncryptionContext := base64.StdEncoding.EncodeToString([]byte(jsonKMSEncryptionContext)) | ||
|
||
return &parsedKMSEncryptionContext, nil | ||
} |
Uh oh!
There was an error while loading. Please reload this page.