Skip to content

CLI / Terraform cannot use kms:decrypt

0

Goal: Create Lambda functions with environment variables using Terraform or CLI I get an error that I am not authorized to perform kms:Decrypt on an aws managed key with an explicit deny in an identity based policy

the only policies attached to my user are AdministratorAccess and a require mfa one included here for completeness. "Sid": "DenyAllExceptListedIfNoMFA", "Effect": "Deny", "NotAction": [ "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:GetUser", "iam:ListUsers", "iam:ListMFADevices", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "iam:CreateLoginProfile", "iam:GetLoginProfile", "iam:UpdateLoginProfile", "iam:GetSessionToken", "iam:ChangePassword" ], "Resource": "*", "Condition": { "Bool": { "aws:MultiFactorAuthPresent": "false"

In my experience this policy only allows you to set up mfa and nothing else until you do so within the console. But that only applies to the console. Once you set up mfa and create long-term credentials for cli access; the cli does not require an mfa token.

I created several lambda functions using terraform. However they fail when trying to add environment variables with "Lambda was unable to decrypt your environment variables because the KMS access was denied. Please check your KMS permissions. KMS Exception: AccessDeniedException KMS Message: User:$MyUserARN is not authorized to perform: kms:Decrypt on resource: $AWSManagedKeyArn with an explicit deny in an identity-based policy". Similarly I cannot update or even list the environment variables using aws lambda get-function-configuration. It lists the entire configuration except for the environment variables. It shows that error message in the environment block and continues describing the rest of the function configuration.

I can destroy the functions and recreate them using cli; as well as countless other actions (vpc, ec2, ecr, ecs, iam, etc..) without hindrance. The IAM Policy simulator shows that i can do all kms actions (if i ignore the multifactorauthpresent field). It is my understanding the policy simulator simulates api/cli usage and not console usage.

2 Answers
1

The issue you're experiencing is related to how AWS KMS permissions work, which is different from most other AWS services. KMS is one of the few services that requires permissions to be explicitly granted in both identity-based policies (attached to your user) and resource-based policies (the KMS key policy).

Even though you have the AdministratorAccess policy, which generally grants permissions to all AWS services, KMS requires explicit permissions in the key policy as well. This is why you're seeing the "explicit deny" message - it's not necessarily that there's an explicit deny statement, but rather that there's no explicit allow in the key policy for your user.

To resolve this issue, you have several options:

  1. Modify the KMS key policy to explicitly allow your user ARN to perform the necessary actions (kms:Decrypt, kms:DescribeKey) on the key.

  2. If you're using a customer-managed KMS key, try switching to the default AWS-managed key for Lambda (aws/lambda).

  3. Create an IAM policy that explicitly grants your user or role the necessary KMS permissions and attach it to your user:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["kms:Decrypt", "kms:GenerateDataKey"],
"Resource": "arn-of-the-kms-key"
}
]
}
  1. If you're using Terraform, you might need to reapply your configuration after making these changes.

Remember that the MFA policy you mentioned shouldn't affect CLI operations once you've set up long-term credentials, as you correctly noted.
Sources
Lambda function KMS issue | AWS re:Post
Error: User not authorised to perform kms on AWS KMS Resource in Amazon S3 in my CodePipeline Codedeploy | AWS re:Post
Administrator user does not have access to KMS which created before | AWS re:Post

answered 8 months ago
EXPERT
reviewed 8 months ago
  • I am using an AWS-managed key for Lambda

0

Hello.

Can you share the Terraform code you're using?
Also, is it possible to create a Lambda from the management console and add environment variables?
AWS-managed KMS keys should be usable if AdministratorAccess is set in IAM within the same account, so if the same error occurs not only from IaC but also from the management console, there may be a problem with the AWS account.
By the way, just to be sure, is the IAM user you are using correct?
Also, have you set permission boundaries for the IAM user that are denying certain actions?
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html

EXPERT
answered 8 months ago
  • I have no permission boundary The user is correct I can interact and set my variables using the console; 15 functions does not scale well here is the relevant terraform code data "aws_iam_policy_document" "assume" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["lambda.amazonaws.com"] } }} resource "aws_iam_role" "exec" { name = "billing-report-${var.linked_account_id}" assume_role_policy = data.aws_iam_policy_document.assume.json } resource "aws_lambda_function" "reporter" { filename = "${path.module}/cost_reporter.zip" function_name = "billing-cost-reporter-${var.account_name}" handler = "handler.lambda_handler" runtime = "python3.12" role = aws_iam_role.exec.arn timeout = 60 memory_size = 512 kms_key_arn = null environment { variables = { SES_FROM_EMAIL = var.sender_email SES_TO_EMAIL = join(",", var.email_recipients) LINKED_ACCOUNT_ID = var.linked_account_id ACCOUNT_NAME = var.account_name } } } resource "aws_lambda_permission" "allow_events" { statement_id = "Allow${var.linked_account_id}FromEvents" action = "lambda:InvokeFunction" function_name = aws_lambda_function.reporter.function_name principal = "events.amazonaws.com" source_arn = aws_cloudwatch_event_rule.schedule.arn }

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.