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:
- 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.
- 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).
- Manage CMKs. By allowing you to control who has access to use the CMKs, list all the CMKs in KMS under an account, etc.
- 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.
- 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:
- Backup the data
- Get KMS to generate a DK for you
- Encrypt the back-up with the DK, and throw away the plain-text.
- Store the back-up data with the encrypted DK somewhere (which can be insecure)
When you want to restore, you just reverse the process:
- You download the backups, retrieving the encrypted DK
- Decrypt the DK using KMS
- Use the decrypted DK to decrypt the data
- 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.