@@ -356,15 +356,36 @@ func VirtualBeaconSearchableEncryptionExample(
356
356
}
357
357
resolveOutput , err := transformsClient .ResolveAttributes (context .TODO (), resolveInput )
358
358
utils .HandleError (err )
359
- fmt .Println (len (resolveOutput .CompoundBeacons ))
359
+ // CompoundBeacons is empty because we have no Compound Beacons configured
360
+ if len (resolveOutput .CompoundBeacons ) != 0 {
361
+ panic ("CompoundBeacons is not empty although it is not configured" )
362
+ }
363
+ // Verify that VirtualFields has the expected value
364
+ virtualFields := resolveOutput .VirtualFields
365
+ if (len (virtualFields )) != 1 {
366
+ panic ("VirtualFields does not have the expected length" )
367
+ }
368
+ if virtualFields ["stateAndHasTestResult" ] != "CAt" {
369
+ panic ("VirtualFields does not have the expected value" )
370
+ }
360
371
372
+ // 13. Create a new AWS SDK DynamoDb client using the DynamoDb Encryption Interceptor
361
373
dbEsdkMiddleware , err := dbesdkmiddleware .NewDBEsdkMiddleware (encryptionConfig )
362
374
utils .HandleError (err )
363
-
364
- // 13. Create a new AWS SDK DynamoDb client using the DynamoDb Encryption Interceptor above
365
375
ddb := dynamodb .NewFromConfig (cfg , dbEsdkMiddleware .CreateMiddleware ())
366
376
367
377
// 14. Put two items into our table using the above client.
378
+ // The two items will differ only in their `customer_id` attribute (primary key)
379
+ // and their `hasTestResult` attribute.
380
+ // We will query against these items to demonstrate how to use our setup above
381
+ // to query against our `stateAndHasTestResult` beacon.
382
+ // Before the item gets sent to DynamoDb, it will be encrypted
383
+ // client-side, according to our configuration.
384
+ // Since our configuration includes a beacon on a virtual field named
385
+ // `stateAndHasTestResult`, the client will add an attribute
386
+ // to the item with name `aws_dbe_b_stateAndHasTestResult`.
387
+ // Its value will be an HMAC truncated to as many bits as the
388
+ // beacon's `length` parameter; i.e. 5.
368
389
itemWithHasTestResultPutRequest := & dynamodb.PutItemInput {
369
390
TableName : aws .String (ddbTableName ),
370
391
Item : itemWithHasTestResult ,
@@ -382,6 +403,17 @@ func VirtualBeaconSearchableEncryptionExample(
382
403
utils .HandleError (err )
383
404
384
405
// 15. Query by stateAndHasTestResult attribute.
406
+ // Note that we are constructing the query as if we were querying on plaintext values.
407
+ // However, the DDB encryption client will detect that this attribute name has a beacon configured.
408
+ // The client will add the beaconized attribute name and attribute value to the query,
409
+ // and transform the query to use the beaconized name and value.
410
+ // Internally, the client will query for and receive all items with a matching HMAC value in the beacon field.
411
+ // This may include a number of "false positives" with different ciphertext, but the same truncated HMAC.
412
+ // e.g. if truncate(HMAC("CAt"), 5) == truncate(HMAC("DCf"), 5), the query will return both items.
413
+ // The client will decrypt all returned items to determine which ones have the expected attribute values,
414
+ // and only surface items with the correct plaintext to the user.
415
+ // This procedure is internal to the client and is abstracted away from the user;
416
+ // e.g. the user will only see "CAt" and never "DCf", though the actual query returned both.
385
417
expressionAttributeNames := map [string ]string {
386
418
"#stateAndHasTestResult" : "stateAndHasTestResult" ,
387
419
}
0 commit comments