LocalStack 63,725 stores users, roles, policies and boundaries faithfully but never evaluates them. ENFORCE_IAM belongs to the paid plans (Hobby Plan); in 4.13.1's source it appears only in a list of settings reported to analytics. So a user with no policies deploys a stack, even with enforcement requested:
docker stop l1-localstack >/dev/null && docker rm -v l1-localstack >/dev/null
docker run -d --name l1-localstack -p 127.0.0.1:31566:4566 \
-e MAIN_CONTAINER_NAME=l1-localstack -e ENFORCE_IAM=1 \
-v /var/run/docker.sock:/var/run/docker.sock localstack/localstack:4.13.1 >/dev/null
until curl -fs localhost:31566/_localstack/health >/dev/null; do sleep 2; done
aws iam create-user --user-name intern --query User.Arn --output text
read -r AK SK < <(aws iam create-access-key --user-name intern \
--query 'AccessKey.[AccessKeyId,SecretAccessKey]' --output text)
export AWS_ACCESS_KEY_ID=$AK AWS_SECRET_ACCESS_KEY=$SK
aws cloudformation deploy --stack-name booknest-catalog --template-file catalog.yaml
aws dynamodb list-tables --query TableNames --output textOutput
arn:aws:iam::000000000000:user/intern ... Successfully created/updated stack - booknest-catalog booknest-books
On AWS 24 (not run here), intern fails at the first call with AccessDenied. Treat every policy here as untested until it runs on AWS, where aws iam simulate-custom-policy checks it offline (LocalStack: "not been implemented").