Reputation: 2457
I'm using elastic beanstalk to run my server and am storing secret keys in key management system.
I can access KMS locally and can confirm they have the correct keys inside of them and that the local system is running fine. However when I upload it to elastic beanstalk it cannot retrieve the keys with the following error.
Jul 31 18:42:31 ip-10-1-0-199 web: (node:8766) UnhandledPromiseRejectionWarning: Error: Unable to decrypt data key and one or more KMS CMKs had an error.
Jul 31 18:42:31 ip-10-1-0-199 web: Error #1
Jul 31 18:42:31 ip-10-1-0-199 web: AccessDeniedException: The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access.
Since it works on local, the key does exist. And since they're in the same region, that also eliminates that one. So I assume it's or you are not allowed to access
. But I'm not sure how to check for this one or even grant access to my elastic beanstalk app.
Does anybody know how to grant access to KMS via an elastic beanstalk app? (i'm assuming this is the issue)
And for reference here's how my code currently pulls the info
// This is an async function that runs only on startup
// There is a potential chance that on first startup a user could call the server
// and the server still have local/dev credentials
// Should think of a solution for this
if(
Environment === Environments.Production ||
Environment === Environments.Release ||
Environment === Environments.Development
){
Config.Aws.BucketName = process.env.bucketName;
Config.Aws.BucketFilePath = process.env.bucketFilePath;
}
let useKms = true;
if(
Environment === Environments.Production ||
Environment === Environments.Release ||
Environment === Environments.Development
){
useKms = true;
}
if(useKms && Config.Aws.BucketName !== "" && Config.Aws.BucketFilePath !== ""){
try{
var getParams = {
Bucket: Config.Aws.BucketName,
Key: Config.Aws.BucketFilePath,
}
console.log("getParams",getParams);
s3.getObject(getParams, async function(err, data) {
// Handle any error and exit
// Need to properly handle this error
if (err){
console.log("err",err);
return false;
}
// No error happened
// Convert Body from a Buffer to a String
let objectData = data.Body.toString('utf-8'); // Use the encoding necessary
// Eval is safe to use here since we know what is saved in S3
let BucketKeys = eval(objectData);
let keyIds = BucketKeys.AwsKeyIds;
const keyring = new KmsKeyringNode({ keyIds });
let result = Buffer.from(JSON.parse(BucketKeys.BufferString).data);
const { plaintext } = await decrypt(keyring,result);
let foo = plaintext.toString('utf8');
let KmsObject = JSON.parse(foo);
Config.Db.Hostname = KmsObject.DatabaseHost;
Config.Db.Username = KmsObject.DatabaseUsername;
Config.Db.Password = KmsObject.DatabasePassword;
Config.Db.Name = KmsObject.DatabaseName;
Config.Db.Port = KmsObject.DatabasePort;
Config.Keys.ApiKey = KmsObject.ApiKey;
Config.Keys.ClientId = KmsObject.ClientId;
Config.Keys.FetchTokenUsername = KmsObject.FetchTokenUsername;
Config.Keys.FetchTokenPassword = KmsObject.FetchTokenPassword;
Config.Keys.GoogleClientId = KmsObject.GoogleClientId;
Config.Keys.GoogleClientSecret = KmsObject.GoogleClientSecret;
Config.Keys.FacebookAppId = KmsObject.FacebookAppId;
Config.Keys.FacebookAppSecret = KmsObject.FacebookAppSecret;
Config.Keys.PaypalApiUrl = "https://api.paypal.com";
Config.Keys.PaypalClientId = KmsObject.PaypalClientId;
Config.Keys.PaypalSecret = KmsObject.PaypalSecret;
Config.Keys.StripePublicKey = KmsObject.StripePublicKey;
Config.Keys.StripeSecretKey = KmsObject.StripeSecretKey;
Config.Email.Host = KmsObject.EmailHost;
Config.Email.Port = KmsObject.EmailPort;
Config.Email.Secure = false;
Config.Email.User = KmsObject.EmailUser;
Config.Email.Pass = KmsObject.EmailPass;
Config.Email.From = "Server";
});
}catch(e){
console.log("tried KMS. but errored out");
}
}
Upvotes: 1
Views: 801
Reputation: 238139
But I'm not sure how to check for this one or even grant access to my elastic beanstalk app.
To enable access for your EB instances to use your KMS you have to explicitly allow that.
This is done through key policies. Specifically you can add your EB instance role as a key user. To check your CMK access, you also inspect the key policies.
In KMS console, to add permissions to your EB instances to use the key,you can add ARN (or name) of the instance role to the key policies:
Upvotes: 1