6

If I am storing multiple customers' data in cloud-based file storage such as an AWS S3 bucket, and I use an encryption service such as AWS KMS to achieve encryption at rest, does it add any extra security for me to store each customer's data in a separate bucket and use a separate encryption key for each customer?

Or is it just as secure to encrypt all customer data with the same encryption key (provided the key is rotated regularly of course)?

CFL_Jeff
  • 193
  • 5

3 Answers3

4

One argument in favour of separate keys: assume at some point in the future your app has some sort of SQLInjection or Server-side request forgery (SSRF) vulnerability that lets a user logged in as CustomerA bypass the usual access control rules and fetch data belonging to CustomerB.

If all customers use the same key, then your application layer server will happily decrypt and serve it back through your UI. However if each customer has their own key, then your server will try to decrypt CustomerB's data with CustomerA's key and throw a decryption error. That would be a win for defense in depth.


While in general, using per-customer encryption keys doesn't do a lot (esp. if you store all the keys in the same place), there are some specific cases where it could save your butt.

Mike Ounsworth
  • 57,707
  • 21
  • 150
  • 207
  • 1
    If securing one key is easier than multiple keys, than using a KDF with the master key might solve the issue. [Derive multiple an encryption key with HKDF](https://crypto.stackexchange.com/q/76588/18298) based on the master key and user-related info. – kelalaka Mar 09 '20 at 21:54
  • 1
    @kelalaka I do not think the OP is doing any encryption by himself, but rather just using the automatic S3 encryption feature provided by AWS. He never gets to see the encryption key. – mat Mar 10 '20 at 08:07
  • The scenario of a compromised application you are describing can and should be mitigated by using the proper access controls to the S3 buckets. Using mutliple keys won't help you here. – mat Mar 10 '20 at 08:10
  • @mat Do you mean that you keep a separate S3 bucket per customer; the app server looks up the S3 access credentials for CustomerA, and then even in the case of an SSRF, those credentials won't be able to access CustomerB's S3 bucket? – Mike Ounsworth Mar 10 '20 at 13:34
  • 1
    @MikeOunsworth If you give some AWS service automatic access to a bucket via a role, it doesn't matter if the data is encrypted with KMS or not. Application A should not have access to the data of Application B. That seperation can be achieved by using different buckets or difference policies on the object level. The standard S3 encryption provided by AWS protects you from one threat: If the physical hard drives fall into the wrong hands (theft, second hand market), your data remains secure. As long as the bucket is online, it is available to anyone having the necessary permissions. – mat Mar 10 '20 at 13:50
  • @mat We might be talking about two different things. I'm talking about isolating the data of two different customers / tenants / users *within the same application* – Mike Ounsworth Mar 10 '20 at 13:54
  • 1
    @MikeOunsworth That's just a semantical, not a technical difference. If you need to protect some data from some AWS service you need to apply proper access control. KMS encryption won't help you. Actual E2EE might, but that's a different topic. – mat Mar 10 '20 at 14:01
  • @mat The next time I see a developer say _"I think I'll write broken access control today"_ I'll make sure to tell them :P I stand by my answer: _"While in general, using per-customer encryption keys doesn't do a lot, there are some specific cases where it could save your butt."_ – Mike Ounsworth Mar 10 '20 at 14:25
  • Can you explain one such case? – mat Mar 10 '20 at 14:34
  • @mat See my answer. If there's a SSRF vuln in your app that bypasses your authorization layer., then per-client encryption could add extra defense in depth. – Mike Ounsworth Mar 10 '20 at 15:46
  • @schroeder I think this comment thread is going in circles. Clean up pls? – Mike Ounsworth Mar 10 '20 at 15:47
4

Unfortunately, the answer is "It depends".

But first, we need to clear up that KMS keys and Buckets are mutually independent, one KMS key (called a CMK) can be tied to multiple buckets, and one bucket can have objects encrypted by multiple CMKs.

Secondly, because of the tight integration between KMS and S3, the only real access control we have is via key grants or IAM permissions (i.e. In order to get an encrypted object in S3, the IAM role must have permission for s3:GetObject and kms:decrypt) there is no way to obtain either the key material or the encrypted cipher-text of the object and perform the decryption/encryption outside of AWS.

Now, what are the factors that would make a single or multi-key strategy a better fit?

If you're storing this data for manual retrieval, keeping them in different buckets makes perfect sense. Buckets are free, and different buckets can be protected by different bucket policies to limit access to certain users/roles. From there, it's not too complex to create a dedicated CMK for each bucket, further isolating the data between customers.

If you're storing data for access by multiple applications (one per customer), then also separate buckets and CMKs for each customer is a good approach. By segregating both buckets and CMKs you're able to isolate each customers data from each other, but more importantly, keep the applications isolated as well.

If you're storing this data for access by one single application, then keeping multiple buckets adds overhead. By definition that application requires access to all CMKs and all buckets, and a compromise on the application would compromise them all. Under this scenario, I wouldn't suggest multi-CMKs, simply because of the additional overhead maintaining the buckets brings little added benefit.

Unless your application grants different IAM roles to different users on login.This is rare, as most apps have an application-level IAM role, rather than a per-user IAM role.But, If you're doing this, then encrypting one bucket with different KMS keys, and providing key-grants to individual IAM roles make perfect sense. This is pretty sophisticated territory, and chances are you wouldn't be asking this question if your app was already doing this :)

keithRozario
  • 3,571
  • 2
  • 12
  • 24
1

IMHO, you should examine the whole thing in terms of costs/benefits and risk/mitigation.

As you store data in non controled storage, you store it in encrypted form. Ok:

  • the risk is that someone (possibly a staff member of the hosting service) can access the data
  • the mitigation is to encrypt the data
  • the cost is to implement encryption and maintain the encryption key on your server
  • the benefit is that without the key the data cannot be read

You now considere using one key per client. What is the risk not covered by the previous scenario that you want to mitigate? Someone manages to steal one key but not all the keys while they will probably be stored the same way and in the same place? If you really want to harden the task for an attacker, you would probably need to use different ways to store and access the keys, which will represent a serious cost in development and maintenance. Unsure that it is worth it here, unless you have identified a different risk.

Generally speaking, using a different key per client is commonly used when the key is owned client side. Said differently, when you want to protect the client data even against an admin of the server platform. It does have a complexity cost but is required for highly sensitive data.

Only my advice, but you should not try to just use random security technics, but really think in terms of threat/risk/mitigation...

Serge Ballesta
  • 25,636
  • 4
  • 42
  • 84