I am investigating using AWS KMS (Amazon Web Services Key Management Service) to decrypt an encrypted symmetric key (i.e: envelope encryption). However, to use the KMS, I need to pass it my amazon access key and secret key.

So I am no longer storing a plaintext symmetric key on my server, but I am now storing an encrypted key and my AWS access keys... is this not essentially the same as storing the plaintext there? Someone with access to my server would only have to take the encrypted key and my Amazon access keys and ask Amazon to decrypt it?

  • 8
    I think the point of AWS KMS is a) to allow you to encrypt your data on AWS more easily (they integrate nicely with S3 and EBS) and b) centralize key management. This way you hand your application just one access key (or some other credential?) and it can (or cannot) arbitrarily request data-key decryption. This will then allow you to a) audit the key usage centrally b) allow you to scale easier (as syncing is now amazon's problem) and c) manage the keys more centrally (for example rotate them or destroy them). From a pure security standpoint there is little difference indeed.
    – SEJPM
    Commented Dec 23, 2016 at 22:39

2 Answers 2


If your server resides in EC2, you can use IAM to create a role for that server and allow it access to KMS without needing to have the AWS access keys on the server.



Indeed you're right, anyone with access to the server can get plain-text key.

Fundamentally your application needs to be able to get the plain-text key -- and hence any attack that fully compromises the application is also going to be able to get the plain-text key. But that's not what KMS is for.

KMS is for Key Management, and specifically the management, generation, encryption and decryption of keys. AWS do have a secrets manager for the management of secrets, and while all keys should be secret, not all secrets are keys.

You can use KMS to:

  1. Generate a Customer Master Key (CMK). CMKs are super special in KMS, as they are never retrievable in plain-text. KMS can only encrypt/decrypt plaintext for you using the CMK, but it will never reveal the CMK itself. KMS limits the amount of data that can be encrypted/decrypted with the CMK to under 4kB per request.
  2. Generate a Data Key (DK). DK can be a key of any length. When you generate a DK, KMS will provide you with both the plain-text key, and the encrypted key, that was encrypted using a specific CMK (specified during the request).
  3. Manage CMKs. By allowing you to control who has access to use the CMKs, list all the CMKs in KMS under an account, etc.
  4. Rotate CMKs. By default all CMKs are rotated on a yearly basis, but AWS will never delete CMKs. Deletion of CMKs is a cumbersome process, and for good reason, loss of a CMK can have potentially severe implications on your AWS resources.
  5. Disable CMKs. If you ever need to, you can disable the CMK, so that it can no longer be used, and any DK encrypted by it, would no longer be usable.

it's very important to differentiate a CMK (which will never be revealed in the clear), and a DK (which is revealed in both plaintext and encrypted form). A CMK is a key, that is used to encrypt another key -- while a DK is key you use to encrypt data. With this concept clear, let's move on.

What is KMS for?

KMS can generate keys in a secure fashion. OWASP recommend using a hardware module to generate keys instead of software, and KMS which is FIPS140-2 compliant does this. If you're generating keys manually on software, that's not the best way to do things.

Also, generating keys at scale isn't trivial. In some use-cases it's important to generate different key for each unique message/transaction, KMS offers an API to do precisely that.

KMS also keeps that key a secret, One of the difficulties with symmetric key encryption is keeping the keys a secret, thus Having a service like KMS, which will never reveal CMKs in the clear, makes that management simpler.

Finally, KMS helps with archiving keys. KMS by default keeps all CMKs perpetually, even if you rotate a key out, you can still decrypt older DKs within KMS -- as long as you didn't explicitly delete an old CMK.

How does it help you?

In your use case, an attacker compromising the server would still get access to whatever they need. So KMS doesn't address this specific threat.

But this would allow you to limit calls to KMS from just the EC2 server in question. So, if you accidentally backed up the files containing the sensitive data to an S3 bucket for example, it would help, as the data would be encrypted, and un-decryptable without access to the CMK on KMS.

However, that's probably not it's primary use-case.

A use case for KMS

KMS is great if you want something like encrypted back-ups. Where you:

  1. Backup the data
  2. Get KMS to generate a DK for you
  3. Encrypt the back-up with the DK, and throw away the plain-text.
  4. Store the back-up data with the encrypted DK somewhere (which can be insecure)

When you want to restore, you just reverse the process:

  1. You download the backups, retrieving the encrypted DK
  2. Decrypt the DK using KMS
  3. Use the decrypted DK to decrypt the data
  4. Access your backups!

In this use-case the encrypted data is stored on servers that have no access to KMS at all, and you're using KMS for the management of keys.

Try Secrets Manager

Going back to your use-case, might I recommend AWS Secrets Manager. It's a simpler API, which would be called and just return the key in question -- that way your key is not stored on the box even in encrypted form.

Your code would call the API, get the key, do it's work and end. If you needed to swap out keys, you could just change it centrally at in Secrets Manager, and continue.

Secrets Manager is cheaper than KMS, and arguably a simpler to use.

  • Thank you for a great answer at last. One question, would I be right in saying that AWS Secrets Manager is only useful for those immersed in the AWS ecosystem? My project is hosted on heroku and from my initial skim of the Secrets Managers docs, it looks like it's intended to manage secrets just for apps hosted on EC2/beanstalk/etc. Commented Nov 21, 2018 at 15:41
  • 1
    Of course if you're in AWS, usage of Secrets Manager is a no-brainer. If you're outside of AWS, you can still call secrets manager using Python + Boto3. Arguably using secrets manager is simpler than standing up your own instance of something like Hashicorp Vault. Commented Nov 21, 2018 at 15:50
  • 3
    But if I'm outside AWS, then....doesn't my server still need plaintext credentials to Secret Manager, which brings us back to square one? I apologize if I'm missing something, this is the central nut I'm trying to crack. I've read about Hashicorp Vault a bit and it seems they use a fairly complex temporary token system for access, but my understanding is not complete yet. Commented Nov 21, 2018 at 16:18
  • 4
    It's the same problem. If you're calling the secret and using the secret in the same place -- you'd need extra protections. But now imagine if you had 100 servers calling the same secret -- having a central secrets manager allows you to better manage secrets. e.g. removing a secret once it's been exposed, or rotating a secret, or even just figuring out which servers are using which secrets. Also, AWS keys can be easily revoked, which allows an extra layer of control. In short though, the problem doesn't go away, it just becomes a bit easier to respond to and manage. Commented Nov 22, 2018 at 2:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .