3

I'd like to have a secret that can be access by all lambdas with different roles in an AWS account. One option would be to attach a policy that allows access to the secret to all the lambdas, but given that we have large number of lambdas, I was wondering if I could do the reverse with resource permissions with in secrets manager.

I've attached the following policy to the secret.

{
  "Version" : "2012-10-17",
  "Statement" : [ {
    "Effect" : "Allow",
    "Principal" : {
      "Service" : "lambda.amazonaws.com"
    },
    "Action" : "secretsmanager:GetSecretValue",
    "Resource" : "arn:aws:secretsmanager:us-east-1:{AWS_ACCOUNT_ID}:secret:dummy-secret-46DfjO",
    "Condition" : {
      "StringEquals" : {
        "aws:sourceAccount" : "{AWS_ACCOUNT_ID}"
      }
    }
  } ]
}

I'd expect the following policy to allow reads from all the lambdas that is in the AWS_ACCOUT_ID, but I am still getting following error:

ERROR | Error while trying to read an API Key from Secrets Manager: Secrets Manager read error: AccessDeniedException: User: arn:aws:sts::AWS_ACCOUNT_ID:assumed-role/dummy-role-name is not authorized to perform: secretsmanager:GetSecretValue on resource: arn:aws:secretsmanager:us-east-1:AWS_ACCOUNT_ID:secret:dummy-secret-46DfjO because no identity-based policy allows the secretsmanager:GetSecretValue action

What am I missing here?

Maurice
  • 11,482
  • 2
  • 25
  • 45
q_kim
  • 45
  • 5

1 Answers1

6

Lambda functions leverage an IAM execution role (dummy-role-name). This implies that when the permissions are evaluated against the resource-based policy of the secret, there is no service principal (lambda.amazonaws.com), but instead there is an assumed-role session principal.

As outlined in the documentation, the syntax for this principal is:

"Principal": { "AWS": "arn:aws:sts::AWS-account-ID:assumed-role/role-name/role-session-name" }

where the role-session-name corresponds to the name of the lambda function.

So your resource-based policy would be:

{
  "Version" : "2012-10-17",
  "Statement" : [ {
    "Effect" : "Allow",
    "Principal": { 
      "AWS": "arn:aws:sts::AWS_ACCOUNT_ID:assumed-role/dummy-role-name/role-session-name" 
    },
    "Action" : "secretsmanager:GetSecretValue",
    "Resource" : "arn:aws:secretsmanager:us-east-1:{AWS_ACCOUNT_ID}:secret:dummy-secret-46DfjO"
  } ]
}

since you mentioned that you would like multiple lambdas to be able to read from this secret, you would have to change the policy to allow the secret retrieval from the other lambda functions.


Alternatively, you could ditch the resource-based policy entirely and leverage an identity-based policy. This would require you to modify the dummy-role-name role to include a policy that allows the secretsmanager:GetSecretValue action.

This might be a better solution if you have many lambda functions, since you could have each lambda function have its own role with its own finegrained permissions. This would be easier than having to manage a single resource-based policy for all of the lambdas.

You can read more about the differences between identity-based and resource-based policies here: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_identity-vs-resource.html

Paolo
  • 21,270
  • 6
  • 38
  • 69
  • There are two valid Principal forms here: (1) the STS `assumed-role` ARN as in the edited answer and (2) the regular IAM `role` ARN (i.e. `arn:aws:iam::123456789012:role/MyLambdaRole`) – fedonev Jan 04 '23 at 17:40
  • @fedonev are you sure about (2)? It didn't work when I tried – Paolo Jan 04 '23 at 17:56
  • Yes. I tested both forms before I commented initially and again now. Perhaps OP can break the tie :) – fedonev Jan 04 '23 at 18:56
  • @fedonev regarding your comment about the regular IAM role, when would the lambda use that? I checked cloudtrail and as far as I can tell, it's always `assumed-role` that is used – Paolo Jan 06 '23 at 12:06
  • Always. It's standard to use the role ARN directly. See this [SO question](https://stackoverflow.com/questions/56192833/setting-aws-lambda-as-principal-in-permission-policy). See also the EC2 example in the Secrets Manager [docs](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_examples.html#auth-and-access_examples_read) (Like Lambda Functions, EC2 instances also use execution roles). Lambda Role ARNs principals are accepted in all services with resource-based policies, [such as S3](https://stackoverflow.com/questions/45282492/s3-policy-to-allow-lambda). – fedonev Jan 06 '23 at 12:38
  • @fedonev if it's standard to use the role ARN, then why is cloudtrail showing assumed-role? – Paolo Jan 06 '23 at 13:21
  • I can't answer for AWS's design choices. But I'm glad it works this way! I hadn't even come across the `assumed-role` format until now. It's great that works, too. But can you find a canonical example? All I ever recall seeing is the Role ARN format. More examples [here](https://aws.amazon.com/blogs/security/iam-policy-types-how-and-when-to-use-them/) and [here](https://aws.amazon.com/blogs/security/how-to-use-resource-based-policies-aws-secrets-manager-console-to-securely-access-secrets-aws-accounts/) from AWS security blogs. – fedonev Jan 06 '23 at 13:49
  • @fedonev as far as I can tell, looking at the cloudtrail logs, lambda *always* assumes the execution role and as a result, the request is made via the assume-role session principal. – Paolo Jan 06 '23 at 13:55