Using attribute-based access control in Lambda
With attribute-based access control (ABAC), you can use tags to control access to your Lambda functions. You can attach tags to a Lambda function, pass them in certain API requests, or attach them to the AWS Identity and Access Management (IAM) principal making the request. For more information about how AWS grants attribute-based access, see Controlling access to AWS resources using tags in the IAM User Guide.
You can use ABAC to grant least privilege without specifying an Amazon Resource Name (ARN) or ARN pattern in the IAM policy. Instead, you can specify a tag in the condition element of an IAM policy to control access. Scaling is easier with ABAC because you don't have to update your IAM policies when you create new functions. Instead, add tags to the new functions to control access.
In Lambda, tags work at the function level. Tags aren't supported for layers, code signing configurations, or event source mappings. When you tag a function, those tags apply to all versions and aliases associated with the function. For information about how to tag functions, see Using tags on Lambda functions.
You can use the following condition keys to control function actions:
-
aws:ResourceTag/tag-key: Control access based on the tags that are attached to Lambda functions.
-
aws:RequestTag/tag-key: Require tags to be present in a request, such as when creating a new function.
-
aws:PrincipalTag/tag-key: Control what the IAM principal (the person making the request) is allowed to do based on the tags that are attached to their IAM user or role.
-
aws:TagKeys: Control whether specific tag keys can be used in a request.
For a complete list of Lambda actions that support ABAC, see Supported function actions and check the Condition column in the table.
The following steps demonstrate one way to set up permissions using ABAC. In this example scenario, you'll create four IAM permissions policies. Then, you'll attach these policies to a new IAM role. Finally, you'll create an IAM user and give that user permission to assume the new role.
Topics
- Prerequisites
- Step 1: Require tags on new functions
- Step 2: Allow actions based on tags attached to a Lambda function and IAM principal
- Step 3: Grant list permissions
- Step 4: Grant IAM permissions
- Step 5: Create the IAM role
- Step 6: Create the IAM user
- Step 7: Test the permissions
- Step 8: Clean up your resources
Prerequisites
Make sure that you have a Lambda execution role. You'll use this role when you grant IAM permissions and when you create a Lambda function.
Step 1: Require tags on new functions
When using ABAC with Lambda, it's a best practice to require that all functions have tags. This helps ensure that your ABAC permissions policies work as expected.
Create an IAM policy similar to the following example. This policy uses the aws:RequestTag/tag-key, aws:ResourceTag/tag-key, and aws:TagKeys condition keys to require that new functions and the IAM principal creating the functions both have the project
tag. The ForAllValues
modifier ensures that project
is the only allowed tag. If you don't include the ForAllValues
modifier, users can add other tags to the function as long as they also pass project
.
Example – Require tags on new functions
{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": [ "lambda:CreateFunction", "lambda:TagResource" ], "Resource": "arn:aws:lambda:*:*:function:*", "Condition": { "StringEquals": { "aws:RequestTag/
project
": "${aws:PrincipalTag/project
}", "aws:ResourceTag/project
": "${aws:PrincipalTag/project
}" }, "ForAllValues:StringEquals": { "aws:TagKeys": "project
" } } } }
Step 2: Allow actions based on tags attached to a Lambda function and IAM principal
Create a second IAM policy using the aws:ResourceTag/tag-key condition key to require the principal's tag to match the tag that's attached to the function. The following example policy allows principals with the project
tag to invoke functions with the project
tag. If a function has any other tags, the action is denied.
Example – Require matching tags on function and IAM principal
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "lambda:InvokeFunction", "lambda:GetFunction" ], "Resource": "arn:aws:lambda:*:*:function:*", "Condition": { "StringEquals": { "aws:ResourceTag/
project
": "${aws:PrincipalTag/project
}" } } } ] }
Step 3: Grant list permissions
Create a policy that allows the principal to list Lambda functions and IAM roles. This allows the principal to see all Lambda functions and IAM roles on the console and when calling the API actions.
Example – Grant Lambda and IAM list permissions
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllResourcesLambdaNoTags", "Effect": "Allow", "Action": [ "lambda:GetAccountSettings", "lambda:ListFunctions", "iam:ListRoles" ], "Resource": "*" } ] }
Step 4: Grant IAM permissions
Create a policy that allows iam:PassRole. This permission is required when you assign an execution role to a function. In the following example policy, replace the example ARN with the ARN of your Lambda execution role.
Note
Do not use the ResourceTag
condition key in a policy with the iam:PassRole
action. You cannot use the tag on an IAM role to control access to who can pass that role. For more information about permissions required to pass a role to a service, see Granting a user permissions to pass a role to an AWS service.
Example – Grant permission to pass the execution role
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": "
arn:aws:iam::111122223333:role/lambda-ex
" } ] }
Step 5: Create the IAM role
It's a best practice to use roles to delegate permissions. Create an IAM role called abac-project-role
:
-
On Step 1: Select trusted entity: Choose AWS account and then choose This account.
-
On Step 2: Add permissions: Attach the four IAM policies that you created in the previous steps.
-
On Step 3: Name, review, and create: Choose Add tag. For Key, enter
project
. Don't enter a Value.
Step 6: Create the IAM user
Create an IAM user called abac-test-user
. In the Set permissions section, choose Attach existing policies directly and then choose Create policy. Enter the following policy definition. Replace 111122223333
with your AWS account ID. This policy allows abac-test-user
to assume abac-project-role
.
Example – Allow IAM user to assume ABAC role
{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::
111122223333
:role/abac-project-role
" } }
Step 7: Test the permissions
-
Sign in to the AWS console as
abac-test-user
. For more information, see Sign in as an IAM user. -
Switch to the
abac-project-role
role. For more information, see Switching to a role (console). -
-
Under Permissions, choose Change default execution role, and then for Execution role, choose Use an existing role. Choose the same execution role that you used in Step 4: Grant IAM permissions.
-
Under Advanced settings, choose Enable tags and then choose Add new tag. For Key, enter
project
. Don't enter a Value.
-
-
Create a second Lambda function and add a different tag, such as
environment
. This operation should fail because the ABAC policy that you created in Step 1: Require tags on new functions only allows the principal to create functions with theproject
tag. -
Create a third function without tags. This operation should fail because the ABAC policy that you created in Step 1: Require tags on new functions doesn't allow the principal to create functions without tags.
This authorization strategy allows you to control access without creating new policies for each new user. To grant access to new users, simply give them permission to assume the role that corresponds to their assigned project.
Step 8: Clean up your resources
To delete the IAM role
-
Open the Roles page
of the IAM console. -
Select the role that you created in step 5.
-
Choose Delete.
-
To confirm deletion, enter the role name in the text input field.
-
Choose Delete.
To delete the IAM user
-
Open the Users page
of the IAM console. -
Select the IAM user that you created in step 6.
-
Choose Delete.
-
To confirm deletion, enter the user name in the text input field.
-
Choose Delete user.
To delete the Lambda function
-
Open the Functions page
of the Lambda console. -
Select the function that you created.
-
Choose Actions, Delete.
-
Type
delete
in the text input field and choose Delete.