-
Notifications
You must be signed in to change notification settings - Fork 19
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
chore(examples): Add examples for Go with CI #733
Merged
Merged
Changes from 11 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
f24cc45
Examples init
rishav-karanjit c2e03da
auto commit
rishav-karanjit d6b366c
Merge branch 'mainline' of https://github.com/aws/aws-encryption-sdk-…
rishav-karanjit 2dd2328
auto commit
rishav-karanjit 9728534
remove duplicate example dir
rishav-karanjit 16d53a2
auto commit
rishav-karanjit a0d566c
will it panic?
rishav-karanjit 1f120de
Revert "will it panic?"
rishav-karanjit 6487e76
Remove get in getters https://go.dev/doc/effective_go\#Getters
rishav-karanjit 37c3f6b
Add examples
rishav-karanjit 74dfcac
Merge branch 'mainline' into rishav-goExamples
rishav-karanjit a6b0a34
rename readme.md to README.md
rishav-karanjit c432f3b
remove redundant code
rishav-karanjit File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
163 changes: 163 additions & 0 deletions
163
AwsEncryptionSDK/runtimes/go/examples/clientsupplier/clientSupplierExample.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
/* | ||
This example sets up an MRK multi-keyring and an MRK discovery | ||
multi-keyring using a custom client supplier. | ||
A custom client supplier grants users access to more granular | ||
configuration aspects of their authentication details and KMS | ||
client. In this example, we create a simple custom client supplier | ||
that authenticates with a different IAM role based on the | ||
region of the KMS key. | ||
|
||
This example creates a MRK multi-keyring configured with a custom | ||
client supplier using a single MRK and encrypts the example_data with it. | ||
Then, it creates a MRK discovery multi-keyring to decrypt the ciphertext. | ||
*/ | ||
|
||
package clientsupplier | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
mpl "github.com/aws/aws-cryptographic-material-providers-library/mpl/awscryptographymaterialproviderssmithygenerated" | ||
mpltypes "github.com/aws/aws-cryptographic-material-providers-library/mpl/awscryptographymaterialproviderssmithygeneratedtypes" | ||
client "github.com/aws/aws-encryption-sdk/awscryptographyencryptionsdksmithygenerated" | ||
esdktypes "github.com/aws/aws-encryption-sdk/awscryptographyencryptionsdksmithygeneratedtypes" | ||
) | ||
|
||
func ClientSupplierExample(exampleText, mrkKeyIdEncrypt, awsAccountId string, awsRegions []string) { | ||
// Step 1: Instantiate the encryption SDK client. | ||
// This builds the default client with the RequireEncryptRequireDecrypt commitment policy, | ||
// which enforces that this client only encrypts using committing algorithm suites and enforces | ||
// that this client will only decrypt encrypted messages that were created with a committing | ||
// algorithm suite. | ||
encryptionClient, err := client.NewClient(esdktypes.AwsEncryptionSdkConfig{}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
// Step 2: Create your encryption context. | ||
// Remember that your encryption context is NOT SECRET. | ||
// For more information, see | ||
// https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context | ||
encryptionContext := map[string]string{ | ||
"encryption": "context", | ||
"is not": "secret", | ||
"but adds": "useful metadata", | ||
"that can help you": "be confident that", | ||
"the data you are handling": "is what you think it is", | ||
} | ||
// Step 3: Initialize the mpl client | ||
matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
// Step 4: Create keyrings | ||
// First Keyring: Create the multi-keyring using our custom client supplier | ||
// defined in the RegionalRoleClientSupplier class in this directory. | ||
// Note: RegionalRoleClientSupplier will internally use the key_arn's region | ||
// to retrieve the correct IAM role. | ||
awsKmsMrkKeyringMultiInput := mpltypes.CreateAwsKmsMrkMultiKeyringInput{ | ||
ClientSupplier: &RegionalRoleClientSupplier{}, | ||
Generator: &mrkKeyIdEncrypt, | ||
} | ||
awsKmsMrkMultiKeyring, err := matProv.CreateAwsKmsMrkMultiKeyring(context.Background(), awsKmsMrkKeyringMultiInput) | ||
if err != nil { | ||
panic(err) | ||
} | ||
// Second Keyring: Create a MRK discovery multi-keyring with a custom client supplier. | ||
// A discovery MRK multi-keyring will be composed of | ||
// multiple discovery MRK keyrings, one for each region. | ||
// Each component keyring has its own KMS client in a particular region. | ||
// When we provide a client supplier to the multi-keyring, all component | ||
// keyrings will use that client supplier configuration. | ||
// In our tests, we make `mrk_key_id_encrypt` an MRK with a replica, and | ||
// provide only the replica region in our discovery filter. | ||
discoveryFilter := mpltypes.DiscoveryFilter{ | ||
AccountIds: []string{awsAccountId}, | ||
Partition: "aws", | ||
} | ||
awsKmsMrkDiscoveryMultiKeyringInput := mpltypes.CreateAwsKmsMrkDiscoveryMultiKeyringInput{ | ||
ClientSupplier: &RegionalRoleClientSupplier{}, | ||
Regions: awsRegions, | ||
DiscoveryFilter: &discoveryFilter, | ||
} | ||
awsKmsMrkDiscoveryMultiKeyring, err := matProv.CreateAwsKmsMrkDiscoveryMultiKeyring(context.Background(), awsKmsMrkDiscoveryMultiKeyringInput) | ||
// Step 5a: Encrypt | ||
res, err := encryptionClient.Encrypt(context.Background(), esdktypes.EncryptInput{ | ||
Plaintext: []byte(exampleText), | ||
EncryptionContext: encryptionContext, | ||
Keyring: awsKmsMrkMultiKeyring, | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
// Validate Ciphertext and Plaintext before encryption are NOT the same | ||
if string(res.Ciphertext) == exampleText { | ||
panic("Ciphertext and Plaintext before encryption are the same") | ||
} | ||
// Step 5b: Decrypt | ||
// Decrypt your encrypted data using the discovery multi keyring. | ||
// On Decrypt, the header of the encrypted message (ciphertext) will be parsed. | ||
// The header contains the Encrypted Data Keys (EDKs), which, if the EDK | ||
// was encrypted by a KMS Keyring, includes the KMS Key ARN. | ||
// For each member of the Multi Keyring, every EDK will try to be decrypted until a decryption | ||
// is successful. | ||
// Since every member of the Multi Keyring is a Discovery Keyring: | ||
// Each Keyring will filter the EDKs by the Discovery Filter and the Keyring's region. | ||
// For each filtered EDK, the keyring will attempt decryption with the keyring's client. | ||
// All of this is done serially, until a success occurs or all keyrings have failed | ||
// all (filtered) EDKs. KMS MRK Discovery Keyrings will attempt to decrypt | ||
// Multi Region Keys (MRKs) and regular KMS Keys. | ||
decryptOutput, err := encryptionClient.Decrypt(context.Background(), esdktypes.DecryptInput{ | ||
EncryptionContext: encryptionContext, | ||
Keyring: awsKmsMrkDiscoveryMultiKeyring, | ||
Ciphertext: res.Ciphertext, | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
// Validate Plaintext after decryption and Plaintext before encryption ARE the same | ||
if string(decryptOutput.Plaintext) != exampleText { | ||
panic("Plaintext after decryption and Plaintext before encryption are NOT the same") | ||
} | ||
// If you do not specify the encryption context on Decrypt, it's recommended to check if the resulting encryption context matches. | ||
// The encryption context was specified on decrypt; we are validating the encryption context for demonstration only. | ||
// Before your application uses plaintext data, verify that the encryption context that | ||
// you used to encrypt the message is included in the encryption context that was used to | ||
// decrypt the message. The AWS Encryption SDK can add pairs, so don't require an exact match. | ||
if err = validateEncryptionContext(encryptionContext, decryptOutput.EncryptionContext); err != nil { | ||
panic(err) | ||
} | ||
// Test the Missing Region Exception | ||
// (This is for demonstration; you do not need to do this in your code.) | ||
|
||
// Create a MRK discovery multi-keyring with a custom client supplier and a fake region. | ||
awsKmsMrkDiscoveryMultiKeyringInputMissingRegion := mpltypes.CreateAwsKmsMrkDiscoveryMultiKeyringInput{ | ||
ClientSupplier: &RegionalRoleClientSupplier{}, | ||
Regions: []string{"fake-region"}, | ||
DiscoveryFilter: &discoveryFilter, | ||
} | ||
_, err = matProv.CreateAwsKmsMrkDiscoveryMultiKeyring(context.Background(), awsKmsMrkDiscoveryMultiKeyringInputMissingRegion) | ||
// Swallow the AwsCryptographicMaterialProvidersException but you may choose how to handle the exception | ||
switch err.(type) { | ||
case mpltypes.AwsCryptographicMaterialProvidersException: | ||
// You may choose how to handle the exception in this switch case. | ||
default: | ||
panic("Decryption using discovery keyring with missing region MUST raise AwsCryptographicMaterialProvidersException") | ||
} | ||
fmt.Println("Client Supplier Example completed successfully") | ||
} | ||
|
||
// This function only does subset matching because AWS Encryption SDK can add pairs, so don't require an exact match. | ||
func validateEncryptionContext(expected, actual map[string]string) error { | ||
for expectedKey, expectedValue := range expected { | ||
actualValue, exists := actual[expectedKey] | ||
if !exists || actualValue != expectedValue { | ||
return fmt.Errorf("encryption context mismatch: expected key '%s' with value '%s'", | ||
expectedKey, expectedValue) | ||
} | ||
} | ||
return nil | ||
} |
57 changes: 57 additions & 0 deletions
57
AwsEncryptionSDK/runtimes/go/examples/clientsupplier/regionalroleclientsupplier.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package clientsupplier | ||
|
||
import ( | ||
"context" | ||
|
||
mpltypes "github.com/aws/aws-cryptographic-material-providers-library/mpl/awscryptographymaterialproviderssmithygeneratedtypes" | ||
"github.com/aws/aws-sdk-go-v2/config" | ||
"github.com/aws/aws-sdk-go-v2/credentials/stscreds" | ||
"github.com/aws/aws-sdk-go-v2/service/kms" | ||
"github.com/aws/aws-sdk-go-v2/service/sts" | ||
) | ||
|
||
/* | ||
Example class demonstrating an implementation of a custom client supplier. | ||
This particular implementation will create KMS clients with different IAM roles, | ||
depending on the region passed. | ||
*/ | ||
|
||
// RegionalRoleClientSupplier provides implementation for mpltypes.IClientSupplier | ||
type RegionalRoleClientSupplier struct { | ||
} | ||
|
||
func (this *RegionalRoleClientSupplier) GetClient(input mpltypes.GetClientInput) (kms.Client, error) { | ||
region := input.Region | ||
// Check if the region is supported | ||
regionIamRoleMap := RegionIamRoleMap() | ||
var defaultVal kms.Client | ||
// Check if region is supported | ||
if _, exists := regionIamRoleMap[region]; !exists { | ||
return defaultVal, mpltypes.AwsCryptographicMaterialProvidersException{ | ||
Message: "Region is not supported by this client supplier", | ||
} | ||
} | ||
// Get the IAM role ARN associated with the region | ||
arn := regionIamRoleMap[region] | ||
ctx := context.TODO() | ||
cfg, err := config.LoadDefaultConfig(ctx, | ||
config.WithRegion(region), | ||
) | ||
if err != nil { | ||
return defaultVal, err | ||
} | ||
stsClient := sts.NewFromConfig(cfg) | ||
// Create the AssumeRoleProvider | ||
provider := stscreds.NewAssumeRoleProvider(stsClient, arn, func(o *stscreds.AssumeRoleOptions) { | ||
o.RoleSessionName = "Go-ESDK-Client-Supplier-Example-Session" | ||
}) | ||
// Load AWS SDK configuration with the AssumeRoleProvider | ||
sdkConfig, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(region), config.WithCredentialsProvider(provider)) | ||
if err != nil { | ||
return defaultVal, mpltypes.AwsCryptographicMaterialProvidersException{Message: "failed to load AWS SDK config"} | ||
} | ||
// Create the KMS client | ||
kmsClient := kms.NewFromConfig(sdkConfig) | ||
// Return the KMS client wrapped in a custom type | ||
return *kmsClient, nil | ||
} |
22 changes: 22 additions & 0 deletions
22
AwsEncryptionSDK/runtimes/go/examples/clientsupplier/regionalroleclientsupplierconfig.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package clientsupplier | ||
|
||
/* | ||
File containing config for the RegionalRoleClientSupplier. | ||
In your own code, this might be hardcoded, or reference | ||
an external source, e.g. environment variables or AWS AppConfig. | ||
*/ | ||
|
||
const ( | ||
usEast1IamRole = "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Dafny-Role-only-us-east-1-KMS-keys" | ||
euWest1IamRole = "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Dafny-Role-only-eu-west-1-KMS-keys" | ||
) | ||
|
||
func RegionIamRoleMap() map[string]string { | ||
return map[string]string{ | ||
"us-east-1": usEast1IamRole, | ||
"eu-west-1": euWest1IamRole, | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be left in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh no. I forgot to remove it. Thats my faster polymorph'ing trick