Building Least-Privilege Architectures with Kiro Assistance

Published: (January 1, 2026 at 06:59 PM EST)
6 min read
Source: Dev.to

Source: Dev.to

Author

Angel

Introduction

I was wondering if I could create a simple example of a stack that applies the least‑privilege architecture principle using AWS. While brainstorming a practical example, what could be better than using Kiro?

What is Kiro?

Kiro is an AI‑powered assistant developed by AWS to help you reason about cloud architectures while you build them. Instead of just writing code and hoping for the best, Kiro works alongside you, explaining what you’re doing, why you’re doing it, and whether it follows best‑practice guidelines.

You can ask Kiro questions about:

  • IAM policies
  • CloudFormation templates
  • Security decisions
  • Architectural trade‑offs

Kiro replies with explanations, suggestions, and improvements—think of it as a knowledgeable AWS companion that helps you move faster while avoiding common mistakes.

Why this example?

For beginners, it’s useful to practice with the most‑used AWS services: S3, IAM, and EC2.

The objective of this practice is to build an EC2 Node.js (Express) application that:

  • Reads a configuration file from S3 at startup.
  • Writes application logs to a specific S3 prefix.
  • Uses an IAM role designed with least privilege from the beginning, assisted by AWS Kiro.

High‑Level Architecture

ComponentDescription
EC2 InstanceRuns Node.js + Express; uses an IAM Instance Profile
IAM RoleAttached to the EC2 instance; scoped S3 permissions
S3 Bucketconfig/app-config.json → read‑only
logs/ → write‑only
CloudFormation StackDefines all infrastructure

Setup

  1. Download & install Kiro IDEhttps://kiro.dev/downloads/
  2. Install the AWS CLI for your OS (the example uses Windows) – https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html

Screenshots

Kiro IDE installation screen

AWS CLI installation screen

Generating the CloudFormation Template with Kiro

After installing the tools, I crafted the first prompt for Kiro (or any LLM of your choice). Instead of starting with a permissive IAM role, I asked Kiro to generate a least‑privilege CloudFormation template directly from the application’s security requirements.

Prompt Sent to Kiro

You are helping me design infrastructure using AWS CloudFormation.

I am building an EC2‑based Node.js (Express) application with the following behavior:
- The application runs on a single EC2 instance.
- It reads a configuration file from Amazon S3 at startup:
  • Bucket: one application‑specific bucket  
  • Object key: config/app-config.json
- It writes application logs to the same S3 bucket under:
  • logs/

Security requirements:
- The EC2 instance must use an IAM role (no static credentials)
- IAM permissions must follow the principle of least privilege
- Do NOT use wildcard actions (e.g., s3:*)
- Do NOT use wildcard resources (*)
- Grant only the exact permissions required for the described behavior

Infrastructure requirements:
- Use AWS CloudFormation (YAML)
- Define:
  • An S3 bucket for application data
  • An IAM role and instance profile for EC2
  • An IAM policy attached to the role with least‑privilege S3 access
  • An EC2 instance
- The template should be clear, readable, and suitable for a security‑focused article

Please:
- Explain the purpose of each IAM permission you include
- Comment on why broader permissions are not required
- Avoid adding any unnecessary AWS services or permissions

Kiro’s Output

Kiro responded with a full set of files, including:

FileDescription
stack.yamlThe CloudFormation template
DEPLOYMENT.mdDocumentation on how to deploy the stack

Screenshots

Generated CloudFormation files
Figure 1 – The generated CloudFormation files.

Resulting file list
Figure 2 – The resulting file list.

Key Takeaways

  • Least‑privilege IAM – Only the s3:GetObject permission for config/app-config.json and s3:PutObject for logs/* are granted. No wildcards are used.
  • Kiro as a co‑pilot – It helps you translate security requirements into precise CloudFormation resources, saving time and reducing human error.
  • Infrastructure as code – All resources (S3 bucket, IAM role, instance profile, EC2 instance) are defined in a single, version‑controlled template, making the stack reproducible and auditable.

Next Steps

  1. Review the generated stack.yaml – adjust parameters (e.g., instance type, AMI) to match your environment.

  2. Deploy the stack with the AWS CLI

    aws cloudformation deploy \
        --template-file stack.yaml \
        --stack-name least-privilege-kiro-demo \
        --capabilities CAPABILITY_NAMED_IAM
  3. Verify the deployment

    • SSH into the EC2 instance.
    • Clone your Node.js application.
    • Confirm it can read the configuration file and write logs to S3.
  4. Iterate and expand – add more resources (e.g., a VPC, security groups) while preserving the least‑privilege principle.

Happy building! 🚀

Least‑Privilege S3 Access Policy

Kiro created the most restrictive policy possible, allowing the EC2 instance to:

  • Read the configuration file
    arn:aws:s3:::${ApplicationBucket}/config/app-config.json
  • Write log files under the logs/ prefix
    arn:aws:s3:::${ApplicationBucket}/logs/*
  • List objects under the logs/ prefix
    arn:aws:s3:::${ApplicationBucket}/logs/*

Policy diagram

IAM Role & Instance Profile

Kiro created an IAM Role named NodeJsAppRole.

  • Assume policy: Only EC2 instances can assume this role.
  • Attachment: The role is linked to an Instance Profile, allowing the EC2 instance to use the permissions granted by the role.

IAM role diagram

This setup enforces a least‑privilege architecture for the stack.

Important Notes from My Experience with Kiro

#Note
1Kiro writes a lot of code quickly. Be patient and read the generated text – it’s worth it!
2A DEPLOYMENT.md file is created with placeholder values. Locate and replace them before running deployment commands.
3Kiro may not know the correct AMI ID. Find the appropriate EC2 Image ID for your region before deployment.
4When Kiro troubleshoots, it will suggest many commands. Read each command first before allowing it to run.
5If Kiro gets stuck, it will ask whether to stop the current iteration and request more information.
6Feel free to log into the AWS console, collect logs, and share them with Kiro – the more context, the better the assistance.

Deployment Success

After debugging and fixing the code with Kiro’s help, the stack was finally created! 🎉

CloudFormation resources created

You can see the newly created CloudFormation resources in the screenshot above.

Testing the Deployment

  1. Run a health‑check

    curl http://<EC2_PUBLIC_IP>:3000/health

    Replace <EC2_PUBLIC_IP> with the public IP address of your EC2 instance.
    The response should be a JSON payload:

    {"status":"healthy"}

    Health‑check response

  2. Verify the log file in S3

    The EC2 instance writes a log entry to the S3 bucket using the attached IAM role.
    You should see a new object under the logs/ prefix with a name similar to app-2023-09-15.log.

    Log file created

  3. Inspect the log content

    Download the log file to view the timestamp of the health check:

    Log file content

    The file confirms that the EC2 instance successfully performed the health check and recorded the result.

Summary

  • A minimal S3 policy grants the EC2 instance only the permissions it truly needs.
  • An IAM role (NodeJsAppRole) limited to the EC2 assume‑action secures the instance.
  • Following the deployment steps and testing the health endpoint validates the entire stack.

Feel free to reuse this pattern for other services that require strict least‑privilege access!

Architecture Overview

Architecture diagram
Figure 1 – High‑level architecture of the EC2 ↔ S3 interaction.

As you saw throughout the process, Kiro can spin up a new stack with a simple EC2 instance that interacts with S3 while enforcing least‑privilege architectures in a user‑friendly way.

Cost Note

Note: This experiment consumed only 11.22 credits out of the 500 bonus credits granted to new Kiro users.

Kiro Dashboard

Kiro dashboard
Figure 2 – Kiro dashboard showing the deployed resources.

Closing Thoughts

I hope this article was interesting and useful, and that it inspires you to build your own project or stack with the help of our new friend, Kiro! 🤓

Thanks for reading, and stay tuned for upcoming articles 📚

Bye! 👋

Back to Blog

Related posts

Read more »

Google Cloud: la Gerarchia delle Risorse

TL;DR - Google Cloud è organizzato in una gerarchia a 4 livelli: Organizzazione → Cartelle → Progetti → Risorse. - Le policy sono ereditate: le regole impostate...