I have been able to sign cloudfront URLs using private keys, but keeping private keys secure is difficult. I am thinking about using KMS to keep the private keys secure, is there a way to sign URLs using the keys stored in amazon KMS?
2 Answers
The answer is no, Cloud front does not provide an api to use key ID in KMS, also KMS does not provide an API to retrieve the private key.

- 6,412
- 3
- 20
- 43
As Amer mentioned, you don't get a dropdown box or option to pick a KMS key id in Cloudfront. However, it is still possible to use KMS to create and manage your RSA keys.
A. You can keep it all in KMS with https://docs.aws.amazon.com/kms/latest/APIReference/API_CreateKey.html and https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html So that the private key is not exposed.
OR
B. https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyPair.html could be used to generate an RSA 2048 public/private key pair, assuming you want to try to store the private key somewhere secure and outside KMS.
You say "KeyPairSpec" = "RSA_2048"
in the request, and they give you back a response which includes both the public and private keys:
{
"KeyId": "string",
"KeyPairSpec": "string",
"PrivateKeyCiphertextBlob": blob,
"PrivateKeyPlaintext": blob,
"PublicKey": blob
}
Either way it's then possible, but not fun, to upload the public key to cloudfront with the Public Keys / Key Groups deal and register them with your distribution. Basically follow the AWS instructions to set up private content in cloudfront, https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html, but use the KMS generated public key from A or B above instead of running openssl. Assuming you know all that stuff above, the fun part is how to keep your private key secure while signing cookies / urls.
It seems to me that you would somehow need your server side app to do the cookie signing by calling KMS.
We have basic workflow like:
- user requests private resource from a frontend js app,
- js app calls backend server that provides simple web endpoint to:
- verify user is authorized,
- sign URLs or cookies with KMS, referencing your key id from above (https://docs.aws.amazon.com/kms/latest/APIReference/API_Encrypt.html), and
- return a 303 see other redirect to the protected cloudfront distro
But this is not a super high traffic pathway. Maybe KMS latency or rate limiting makes this non-optimal for some applications. (500 RSA encrypt calls per second is ok for us, but maybe not for everyone: https://docs.aws.amazon.com/kms/latest/developerguide/requests-per-second.html)
AWS Secrets Manager could do 5000 gets per second, if you were so inclined to push private key info there (someone can argue it is less secure since the private key left KMS in the first place) : https://docs.aws.amazon.com/general/latest/gr/asm.html
I don't think I'll delve into how caching can help with rate limiting... hopefully the mechanics above make it clear that this is at least possible if you want or need to pursue it.

- 21
- 1