@@ -37,145 +37,145 @@ public class MigrationStep1
3737 {
3838 public static async Task < bool > MigrationStep1Example ( string kmsKeyId , string ddbTableName , string partitionKeyValue , string sortKeyWriteValue , string sortKeyReadValue )
3939 {
40- // 1. Create a Keyring. This Keyring will be responsible for protecting the data keys that protect your data.
41- // For this example, we will create a AWS KMS Keyring with the AWS KMS Key we want to use.
42- // We will use the `CreateMrkMultiKeyring` method to create this keyring,
43- // as it will correctly handle both single region and Multi-Region KMS Keys.
44- var matProv = new MaterialProviders ( new MaterialProvidersConfig ( ) ) ;
45- var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId } ;
46- var kmsKeyring = matProv . CreateAwsKmsMrkMultiKeyring ( keyringInput ) ;
40+ // 1. Create a Keyring. This Keyring will be responsible for protecting the data keys that protect your data.
41+ // For this example, we will create a AWS KMS Keyring with the AWS KMS Key we want to use.
42+ // We will use the `CreateMrkMultiKeyring` method to create this keyring,
43+ // as it will correctly handle both single region and Multi-Region KMS Keys.
44+ var matProv = new MaterialProviders ( new MaterialProvidersConfig ( ) ) ;
45+ var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId } ;
46+ var kmsKeyring = matProv . CreateAwsKmsMrkMultiKeyring ( keyringInput ) ;
4747
48- // 2. Configure which attributes are encrypted and/or signed when writing new items.
49- // For each attribute that may exist on the items we plan to write to our DynamoDbTable,
50- // we must explicitly configure how they should be treated during item encryption:
51- // - ENCRYPT_AND_SIGN: The attribute is encrypted and included in the signature
52- // - SIGN_ONLY: The attribute not encrypted, but is still included in the signature
53- // - DO_NOTHING: The attribute is not encrypted and not included in the signature
54- var attributeActionsOnEncrypt = new Dictionary < string , CryptoAction >
55- {
56- [ "partition_key" ] = CryptoAction . SIGN_ONLY , // Our partition attribute must be SIGN_ONLY
57- [ "sort_key" ] = CryptoAction . SIGN_ONLY , // Our sort attribute must be SIGN_ONLY
58- [ "attribute1" ] = CryptoAction . ENCRYPT_AND_SIGN ,
59- [ "attribute2" ] = CryptoAction . SIGN_ONLY ,
60- [ "attribute3" ] = CryptoAction . DO_NOTHING
61- } ;
48+ // 2. Configure which attributes are encrypted and/or signed when writing new items.
49+ // For each attribute that may exist on the items we plan to write to our DynamoDbTable,
50+ // we must explicitly configure how they should be treated during item encryption:
51+ // - ENCRYPT_AND_SIGN: The attribute is encrypted and included in the signature
52+ // - SIGN_ONLY: The attribute not encrypted, but is still included in the signature
53+ // - DO_NOTHING: The attribute is not encrypted and not included in the signature
54+ var attributeActionsOnEncrypt = new Dictionary < string , CryptoAction >
55+ {
56+ [ "partition_key" ] = CryptoAction . SIGN_ONLY , // Our partition attribute must be SIGN_ONLY
57+ [ "sort_key" ] = CryptoAction . SIGN_ONLY , // Our sort attribute must be SIGN_ONLY
58+ [ "attribute1" ] = CryptoAction . ENCRYPT_AND_SIGN ,
59+ [ "attribute2" ] = CryptoAction . SIGN_ONLY ,
60+ [ "attribute3" ] = CryptoAction . DO_NOTHING
61+ } ;
6262
63- // 3. Configure which attributes we expect to be excluded in the signature
64- // when reading items. There are two options for configuring this:
65- //
66- // - (Recommended) Configure `allowedUnsignedAttributesPrefix`:
67- // When defining your DynamoDb schema and deciding on attribute names,
68- // choose a distinguishing prefix (such as ":") for all attributes that
69- // you do not want to include in the signature.
70- // This has two main benefits:
71- // - It is easier to reason about the security and authenticity of data within your item
72- // when all unauthenticated data is easily distinguishable by their attribute name.
73- // - If you need to add new unauthenticated attributes in the future,
74- // you can easily make the corresponding update to your `attributeActionsOnEncrypt`
75- // and immediately start writing to that new attribute, without
76- // any other configuration update needed.
77- // Once you configure this field, it is not safe to update it.
78- //
79- // - Configure `allowedUnsignedAttributes`: You may also explicitly list
80- // a set of attributes that should be considered unauthenticated when encountered
81- // on read. Be careful if you use this configuration. Do not remove an attribute
82- // name from this configuration, even if you are no longer writing with that attribute,
83- // as old items may still include this attribute, and our configuration needs to know
84- // to continue to exclude this attribute from the signature scope.
85- // If you add new attribute names to this field, you must first deploy the update to this
86- // field to all readers in your host fleet before deploying the update to start writing
87- // with that new attribute.
88- //
89- // For this example, we will explicitly list the attributes that are not signed.
90- var unsignedAttributes = new List < string > { "attribute3" } ;
63+ // 3. Configure which attributes we expect to be excluded in the signature
64+ // when reading items. There are two options for configuring this:
65+ //
66+ // - (Recommended) Configure `allowedUnsignedAttributesPrefix`:
67+ // When defining your DynamoDb schema and deciding on attribute names,
68+ // choose a distinguishing prefix (such as ":") for all attributes that
69+ // you do not want to include in the signature.
70+ // This has two main benefits:
71+ // - It is easier to reason about the security and authenticity of data within your item
72+ // when all unauthenticated data is easily distinguishable by their attribute name.
73+ // - If you need to add new unauthenticated attributes in the future,
74+ // you can easily make the corresponding update to your `attributeActionsOnEncrypt`
75+ // and immediately start writing to that new attribute, without
76+ // any other configuration update needed.
77+ // Once you configure this field, it is not safe to update it.
78+ //
79+ // - Configure `allowedUnsignedAttributes`: You may also explicitly list
80+ // a set of attributes that should be considered unauthenticated when encountered
81+ // on read. Be careful if you use this configuration. Do not remove an attribute
82+ // name from this configuration, even if you are no longer writing with that attribute,
83+ // as old items may still include this attribute, and our configuration needs to know
84+ // to continue to exclude this attribute from the signature scope.
85+ // If you add new attribute names to this field, you must first deploy the update to this
86+ // field to all readers in your host fleet before deploying the update to start writing
87+ // with that new attribute.
88+ //
89+ // For this example, we will explicitly list the attributes that are not signed.
90+ var unsignedAttributes = new List < string > { "attribute3" } ;
9191
92- // 4. Create the DynamoDb Encryption configuration for the table we will be writing to.
93- // This configuration uses PlaintextOverride.FORCE_PLAINTEXT_WRITE_ALLOW_PLAINTEXT_READ
94- // which means:
95- // - Write: Items are forced to be written as plaintext.
96- // Items may not be written as encrypted items.
97- // - Read: Items are allowed to be read as plaintext.
98- // Items are allowed to be read as encrypted items.
99- var tableConfig = new DynamoDbTableEncryptionConfig
100- {
101- LogicalTableName = ddbTableName ,
102- PartitionKeyName = "partition_key" ,
103- SortKeyName = "sort_key" ,
104- AttributeActionsOnEncrypt = attributeActionsOnEncrypt ,
105- Keyring = kmsKeyring ,
106- AllowedUnsignedAttributes = unsignedAttributes ,
107- PlaintextOverride = PlaintextOverride . FORCE_PLAINTEXT_WRITE_ALLOW_PLAINTEXT_READ
108- } ;
92+ // 4. Create the DynamoDb Encryption configuration for the table we will be writing to.
93+ // This configuration uses PlaintextOverride.FORCE_PLAINTEXT_WRITE_ALLOW_PLAINTEXT_READ
94+ // which means:
95+ // - Write: Items are forced to be written as plaintext.
96+ // Items may not be written as encrypted items.
97+ // - Read: Items are allowed to be read as plaintext.
98+ // Items are allowed to be read as encrypted items.
99+ var tableConfig = new DynamoDbTableEncryptionConfig
100+ {
101+ LogicalTableName = ddbTableName ,
102+ PartitionKeyName = "partition_key" ,
103+ SortKeyName = "sort_key" ,
104+ AttributeActionsOnEncrypt = attributeActionsOnEncrypt ,
105+ Keyring = kmsKeyring ,
106+ AllowedUnsignedAttributes = unsignedAttributes ,
107+ PlaintextOverride = PlaintextOverride . FORCE_PLAINTEXT_WRITE_ALLOW_PLAINTEXT_READ
108+ } ;
109109
110- var tableConfigs = new Dictionary < string , DynamoDbTableEncryptionConfig >
111- {
112- [ ddbTableName ] = tableConfig
113- } ;
110+ var tableConfigs = new Dictionary < string , DynamoDbTableEncryptionConfig >
111+ {
112+ [ ddbTableName ] = tableConfig
113+ } ;
114114
115- // 5. Create a new AWS SDK DynamoDb client using the TableEncryptionConfigs
116- var ddb = new Client . DynamoDbClient (
117- new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs } ) ;
115+ // 5. Create a new AWS SDK DynamoDb client using the TableEncryptionConfigs
116+ var ddb = new Client . DynamoDbClient (
117+ new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs } ) ;
118118
119- // 6. Put an item into our table using the above client.
120- // This item will be stored in plaintext due to our PlaintextOverride configuration.
121- string encryptedAndSignedValue = MigrationUtils . ENCRYPTED_AND_SIGNED_VALUE ;
122- string signOnlyValue = MigrationUtils . SIGN_ONLY_VALUE ;
123- string doNothingValue = MigrationUtils . DO_NOTHING_VALUE ;
124- var item = new Dictionary < string , AttributeValue >
125- {
126- [ "partition_key" ] = new AttributeValue { S = partitionKeyValue } ,
127- [ "sort_key" ] = new AttributeValue { N = sortKeyWriteValue } ,
128- [ "attribute1" ] = new AttributeValue { S = encryptedAndSignedValue } ,
129- [ "attribute2" ] = new AttributeValue { S = signOnlyValue } ,
130- [ "attribute3" ] = new AttributeValue { S = doNothingValue }
131- } ;
119+ // 6. Put an item into our table using the above client.
120+ // This item will be stored in plaintext due to our PlaintextOverride configuration.
121+ string encryptedAndSignedValue = MigrationUtils . ENCRYPTED_AND_SIGNED_VALUE ;
122+ string signOnlyValue = MigrationUtils . SIGN_ONLY_VALUE ;
123+ string doNothingValue = MigrationUtils . DO_NOTHING_VALUE ;
124+ var item = new Dictionary < string , AttributeValue >
125+ {
126+ [ "partition_key" ] = new AttributeValue { S = partitionKeyValue } ,
127+ [ "sort_key" ] = new AttributeValue { N = sortKeyWriteValue } ,
128+ [ "attribute1" ] = new AttributeValue { S = encryptedAndSignedValue } ,
129+ [ "attribute2" ] = new AttributeValue { S = signOnlyValue } ,
130+ [ "attribute3" ] = new AttributeValue { S = doNothingValue }
131+ } ;
132132
133- var putRequest = new PutItemRequest
134- {
135- TableName = ddbTableName ,
136- Item = item
137- } ;
133+ var putRequest = new PutItemRequest
134+ {
135+ TableName = ddbTableName ,
136+ Item = item
137+ } ;
138138
139- var putResponse = await ddb . PutItemAsync ( putRequest ) ;
140- Debug . Assert ( putResponse . HttpStatusCode == HttpStatusCode . OK ) ;
139+ var putResponse = await ddb . PutItemAsync ( putRequest ) ;
140+ Debug . Assert ( putResponse . HttpStatusCode == HttpStatusCode . OK ) ;
141141
142- // 7. Get an item back from the table using the same client.
143- // If this is an item written in plaintext (i.e. any item written
144- // during Step 0 or 1), then the item will still be in plaintext.
145- // If this is an item that was encrypted client-side (i.e. any item written
146- // during Step 2 or after), then the item will be decrypted client-side
147- // and surfaced as a plaintext item.
148- var key = new Dictionary < string , AttributeValue >
149- {
150- [ "partition_key" ] = new AttributeValue { S = partitionKeyValue } ,
151- [ "sort_key" ] = new AttributeValue { N = sortKeyReadValue }
152- } ;
142+ // 7. Get an item back from the table using the same client.
143+ // If this is an item written in plaintext (i.e. any item written
144+ // during Step 0 or 1), then the item will still be in plaintext.
145+ // If this is an item that was encrypted client-side (i.e. any item written
146+ // during Step 2 or after), then the item will be decrypted client-side
147+ // and surfaced as a plaintext item.
148+ var key = new Dictionary < string , AttributeValue >
149+ {
150+ [ "partition_key" ] = new AttributeValue { S = partitionKeyValue } ,
151+ [ "sort_key" ] = new AttributeValue { N = sortKeyReadValue }
152+ } ;
153153
154- var getRequest = new GetItemRequest
155- {
156- TableName = ddbTableName ,
157- Key = key ,
158- // In this example we configure a strongly consistent read
159- // because we perform a read immediately after a write (for demonstrative purposes).
160- // By default, reads are only eventually consistent.
161- ConsistentRead = true
162- } ;
154+ var getRequest = new GetItemRequest
155+ {
156+ TableName = ddbTableName ,
157+ Key = key ,
158+ // In this example we configure a strongly consistent read
159+ // because we perform a read immediately after a write (for demonstrative purposes).
160+ // By default, reads are only eventually consistent.
161+ ConsistentRead = true
162+ } ;
163163
164- var getResponse = await ddb . GetItemAsync ( getRequest ) ;
165- Debug . Assert ( getResponse . HttpStatusCode == HttpStatusCode . OK ) ;
164+ var getResponse = await ddb . GetItemAsync ( getRequest ) ;
165+ Debug . Assert ( getResponse . HttpStatusCode == HttpStatusCode . OK ) ;
166166
167- // 8. Verify we get the expected item back
168- if ( getResponse . Item == null )
169- {
170- throw new Exception ( "No item found" ) ;
171- }
167+ // 8. Verify we get the expected item back
168+ if ( getResponse . Item == null )
169+ {
170+ throw new Exception ( "No item found" ) ;
171+ }
172172
173- bool success = MigrationUtils . VerifyReturnedItem ( getResponse , partitionKeyValue , sortKeyReadValue ) ;
174- if ( success )
175- {
176- Console . WriteLine ( "MigrationStep1 completed successfully" ) ;
177- }
178- return success ;
173+ bool success = MigrationUtils . VerifyReturnedItem ( getResponse , partitionKeyValue , sortKeyReadValue ) ;
174+ if ( success )
175+ {
176+ Console . WriteLine ( "MigrationStep1 completed successfully" ) ;
177+ }
178+ return success ;
179179 }
180180 }
181181}
0 commit comments