The task of our handle_stream
function is to read the stream data from the stream,
and it should be permitted to do only that. One of the best practices when dealing with permissions is to only allow what
is absolutely needed; no more, no less. This is called the principle of least privilege.
So how can we implement the principle of least privilege with our functions?
Chalice allows us to specify certain configuration settings per stage or per function. Without going too much into what stages are, specifying permissions per function is supported and is pretty straight forward.
The results we want to achieve are:
TABLE_NAME
environment variablehandle_stream
function has the STREAM_ARN
environment variablehandle_stream
function has the permissions to read stream dataWe can achieve these results by splitting permissions into several files:
policy-dev.json
will contain Cloudwatch and DynamoDB permissionspolicy-handle-stream.json
will contain Cloudwatch and stream permissionspolicy-dev.json
cat > .chalice/policy-dev.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow"
},
{
"Action": [
"dynamodb:PutItem",
"dynamodb:DeleteItem",
"dynamodb:UpdateItem",
"dynamodb:GetItem",
"dynamodb:Scan",
"dynamodb:Query"
],
"Resource": [
"arn:aws:dynamodb:*:*:table/$WORKSHOP_NAME-savealife-$ENV"
],
"Effect": "Allow"
}
]
}
EOF
policy-handle-stream.json
cat > .chalice/policy-handle-stream.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow"
},
{
"Action": [
"dynamodb:DescribeStream",
"dynamodb:GetRecords",
"dynamodb:GetShardIterator",
"dynamodb:ListStreams"
],
"Resource": [
"arn:aws:dynamodb:eu-central-1:932785857088:table/$WORKSHOP_NAME-savealife-$ENV/stream/*"
],
"Effect": "Allow"
}
]
}
EOF
The config file .chalice/config.json
can be edited to assign policies and environment variables where they are needed:
cat > .chalice/config.json <<EOF
{
"version": "2.0",
"app_name": "$WORKSHOP_NAME-savealife",
"autogen_policy": false,
"automatic_layer": true,
"stages": {
"dev": {
"api_gateway_stage": "api",
"iam_policy_file": "policy-dev.json",
"environment_variables": {
"TABLE_NAME": "$WORKSHOP_NAME-savealife-$ENV"
},
"lambda_functions": {
"handle_stream": {
"iam_policy_file": "policy-handle-stream.json",
"environment_variables": {
"STREAM_ARN": "STREAM_ARN_HERE"
}
}
}
}
}
}
EOF
Don’t forget to replace the STREAM_ARN_HERE
with your actual stream ARN.