4
votes

I am trying to use the NotPrincipal element in my bucket policy to explicitly deny access to my s3 bucket while whitelisting a particular lambda that accesses the bucket. I specified the role ARN and assumed role ARN for the lambda's role in the NotPrincipal element:

"arn:aws:iam::{Account ID}:role/service-role/{Lambda role name}",

"arn:aws:sts::{Account ID}:assumed-role/{Lambda role name}/{role session name}"

This doc explains the structure of the assumed role ARNs: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids

I can't seem to get the assumed role ARN correct. The bucket policy is valid, but it seems I can provide anything for the role session name (the last part of the assumed-role ARN), and the ARN is considered valid. What does AWS set this role session name to when Lambda or other service assumes a service role? Is it possible to list active sessions for a role or list the assumed-role ARNs? I am currently using the Lambda function name for the role session name, but this is not working (the Lambda still cannot access the bucket).

Since I can't use wildcards in the NotPrincipal element, I need the full assumed-role ARN of the Lambda once it assumes the role.

UPDATE:

I tried using two conditions to deny all requests where the ARN does not match the ARN of the Lambda role or assumed role. The Lambda role is still denied from writing to S3 using the IAM policy simulator. Here is the policy:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "WhitelistRegistryAPILambdaRole",
        "Effect": "Deny",
        "Principal": "*",
        "Action": [
            "s3:PutObject",
            "s3:DeleteObject",
            "s3:DeleteObjectVersion",
            "s3:GetObjectVersion",
            "s3:GetObject"
        ],
        "Resource": [
            "arn:aws:s3:::{bucket name}",
            "arn:aws:s3:::{bucket name}/*"
        ],
        "Condition": {
            "ArnNotLike": {
                "AWS:SourceARN": "arn:aws:iam::{account ID}:role/{lambda role name}"
            }
        }
    },
    {
        "Sid": "WhitelistRegistryAPILambdaAssumedRole",
        "Effect": "Deny",
        "Principal": "*",
        "Action": [
            "s3:PutObject",
            "s3:DeleteObject",
            "s3:DeleteObjectVersion",
            "s3:GetObjectVersion",
            "s3:GetObject"
        ],
        "Resource": [
            "arn:aws:s3:::{bucket name}",
            "arn:aws:s3:::{bucket name}/*"
        ],
        "Condition": {
            "ArnNotLike": {
                "AWS:SourceARN": "arn:aws:sts::{account ID}:assumed-role/{lambda role name}/{lambda function name}"
            }
        }
    }
]

}

1

1 Answers

6
votes

TL;DR:

The Assumed Role ARN of a Lambda Function is constructed as this:

arn:aws:sts::{AccountID}:assumed-role/{RoleName}/{FunctionName}

Details:

So the "role session name" is, in your case, the lambda function name. You can easily verify this, by trying to call an API from your Lambda (DynamoDB ListTables for example) for which you do not have permissions. The error message in the callback will also contain the assumed role ARN (note that some service such as S3 do not provide detailed error messages when an operation is denied. DynamoDB, Lambda, and most of the recently launched services, will.)

I'm not sure to understand why you need a NotPrincipal, as probably there is a better way to handle the scenario you described :) More info would be useful to provide a more precise answer.
From the AWS IAM Documentation:

Important: Very few scenarios require the use of NotPrincipal, and we recommend that you explore other authorization options before you decide to use NotPrincipal.