AWS AppSync encrypting DynamoDB Data - amazon-web-services

I'm working with AppSync on a project, and will be capturing relatively sensitive user data which will require encryption at rest in a database.
Currently, I am building with DynamoDB resolvers after a mutation or query, but happy to explore other solutions (such as encrypting with KMS through a Lambda function and then sending to DynamoDB; or using DynamoDB Streams to refactor the data once a new entry is created in a table?)
The KMS would be managed through IAM, with user's assigned through a Cognito user pool (I'm quite new to this, but believe that's the best approach).

this all depends on who you are protecting the data from. if the decrypt is going to actually happen in AWS, then AWS has the decrypt key at least temporarily (because you let them manage the keys, and give them to ciphers that reside in AWS). you can assume that AWS are trusted to forget the key and the decrypted plaintext ASAP, and not backdoor your decrypts. if you are only worried about third-parties (ie: not-AWS) getting in, then this is ok. Just keep in mind that your defenses against the cloud provider if you do not do end-to-end are limited.
If you are actually worried about AWS decrypting your stuff, there are a few major issues, because that demands end-to-end encryption to handle: decrypts would have to happen outside of AWS (ie: decrypt on a phone or a program that runs on a user's laptop), which implies that keys themselves are only decrypted outside of AWS, and if you search data you are not telling AWS what you are searching for (ie: angry-protesters-on-my-last-visit.mp4). The latter is possible do to, but there are very few general purpose products that even attempt to do correct end-to-end encryption.

DynamoDB now supports encryption at rest, you can enable it on your table.

Related

Doesn't bring your own key (BYOK) lose control of the key to cloud provider like AWS anyway?

My understanding is that by generating your own key and use that to encrypt stuff, it prevents a cloud provider from being able to read your data at rest. But before a cloud provider can use this customer managed key to encrypt/decrypt, it has to first have access to the key's plaintext. What stops a cloud provider from actually storing that plaintext and still has access to my data at rest?
Different cloud provider might have different approach to this, so I'm using AWS S3 as a reference here, which requires you to send the key in the request. https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html
In the SSE-C scenario you refer to, the user provides AWS the plaintext data and plaintext key (over https) and then AWS performs the encryption and discards the key. The benefit to the user is that the user does not have to perform cryptographic operations.
If there is a concern about AWS having access to plaintext data or keys, the user can encrypt the data on the client computer and then send the data to AWS already encrypted. This is the client-side encryption scenario.

How AWS RDS KMS encryption really works?

I know we can select a KMS (customer or AWS managed) key when creating our RDS database.
However I find the documentation quite vague about the different processes so I've got the following questions:
Does it mean that only one datakey will be used for the whole database to encrypt everything ?
Where exactly is the encrypted version of the data key located ?
When does RDS decrypt the encrypted datakey to use it ?
How often does RDS need to make an API call against KMS to decrypt the encrypted version of the data key it keeps ?
Does it mean that only one datakey will be used for the whole database
The documentation really doesn't specify any details. Based on the aws best practices and other documentation I'd assume the data key is cached and reused for certain time and then regenerated.
However the details are not publicly available. All the storage encryption is hidden under the hood and not visible to the client
How often does RDS need to make an API call against KMS to decrypt the encrypted version of the data key it keeps ?
AWS KMS calls are logged in the CloudTrail and you will see the calls on the bill as well. At least for the CMK (I'm not sure how is it for the default service KMS).

Should I use Secrets Manager for storing customers' API keys?

I'm implementing a service that requires me to call my customers' API using their API keys. My customers will provide me with their API keys in their accounts.
When I'm calling my customers' API, I have to retrieve their API key before making the call. Since these are my customers' API keys and I want them to be kept safely, I'm considering keeping all of them in AWS Secrets Manager. I have roughly about 5,000 users (still growing) and I plan to store all their keys into a single secret in Secrets Manager. My application makes about a few millions calls to my customers API a month and it needs to retrieve the keys at high frequency and concurrency.
However, I'm not sure if this is the kind of use case for Secrets Manager because their docs sound to me like it was meant for just keeping secret information for the application and not for customers like a database. At the same time, storing encrypted keys in the database and having to decrypt them with a KMS key sounds like I may end up with roughly the same cost.
Is Secrets Manager meant for such a use case to store customers' sensitive information such as API keys? If not, what should I consider in my case?
50k api keys in a single secret is goinfg to be very unwieldy. Assuming a 40 byte token, you're looking at 2mb of data - SSM has a max data length for a value of 4096 bytes unless I'm mistaken.
To me it would make more sense to generate a key with KMS and use that key to encrypt customer API keys before writing them to a DynamoDB table (or even RDS if you so desire) When you need to use a customer API key, fetch it from dynamoDB, decrypt it with the KMS key, and then make use of it.
If you want automatic key rotation, SSM could be used to encrypt the key you use to encrypt the client API tokens. Your token decryption key would remain usable while the wrapping SSM entry would be reencrypted with a key rotation set by policy.
Finally, as Software Engineer suggested above, there is Vault.

Where to store multiple access tokens on AWS?

I'm working on a Slack app which will have to store access token per each customer using the app (ex. 1000 teams using it = 1000 tokens). Token enables the app to access Slack API for customers workspace and will be used frequently every day.
App will be running on AWS, using Lambda's and DynamoDB.
What would be the best practice to store those access tokens securly?
I cannot find any strict recomendation for this scenario. Was thinking initially to put those in DynamoDB in a dedicated table but thinking now if I should use other AWS services for that use case. I've checked Secrets Manager but looks like a rather expensive option and not sure if it applies to my scenario.
Appreciate any suggestions.
I would probably use a dedicated DynamoDB table for this purpose. At a minimum, I would configure it to use a KMS CMK to encrypt the data at-rest, and also restrict access to the table through fairly granular IAM permissions in your AWS account. If you also wanted to encrypt each value separately you could look into client-side encryption.
Your findings on the Secrets Manager costs are a good point. You could also look at Systems Manager Parameter Store as an alternative that is generally cheaper than Secrets Manager. Secrets Manager does have the added security of being able to set an IAM resource policy on the secret itself.
Ultimately it's up to you to determine how secure your solution needs to be, and how much you are willing to pay for that. You could even spin up an AWS HSM to encrypt the values, but that would increase the cost by quite a bit.

What is the purpose of encrypting data at rest with AWS KMS?

I'm currently going about setting up encryption on AWS DynamoDB for individual columns on a table that are deemed sensitive. From my research, I've decided that the best way of doing this is likely with AWS KMS. From this sprouted a (perhaps very basic) question about the fundamental workings of doing this.
The true purpose, I would suppose, of me encrypting this data is to prevent people from accessing my data via a compromised AWS account (and perhaps AWS itself being compromised, but I'd imagine that's secondary). However, if my AWS account is compromised... doesn't the attacker have access to my KMS key (not directly, but the ability to use the API to encrypt and decrypt data?)
This is a really basic question, I'm sure, but I feel like I can't move forward with a hole in my knowledge this big.
The purpose of having KMS is to protect your data while the key is never visible to your application since the key never leaves KMS. You submit data to AWS KMS to be encrypted, or decrypted, under keys that you control. You set usage policies on these keys that determine which users can use them to encrypt and decrypt data. All requests to use these keys are logged in AWS CloudTrail so you can understand who used which key when.
Having KMS makes it impossible for an attacker to get the encryption keys. Even if an attacker get on hold of your AWS Account(Assuming he gets Admin Access and KMS Access) and use KMS to decrypt a message, you will be able to see that through the logs in accessing these keys which is a necessary security steps to identify these threats.
So in general, if you provide least privilege to users(Not allowing everyone to access KMS), while keeping root account safe with MFA, it will be really difficult for an attacker to access KMS.