<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>iam on MD/Blog</title>
    <link>https://www.ducea.com/tag/iam/</link>
    <description>Recent content in iam on MD/Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Sat, 07 Mar 2026 10:20:55 +0000</lastBuildDate>
    
	<atom:link href="https://www.ducea.com/tag/iam/rss.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>HowTo give Kiro safe access to your AWS environment</title>
      <link>https://www.ducea.com/2026/03/07/howto-give-kiro-safe-access-to-your-aws-environment/</link>
      <pubDate>Sat, 07 Mar 2026 10:20:55 +0000</pubDate>
      
      <guid>https://www.ducea.com/2026/03/07/howto-give-kiro-safe-access-to-your-aws-environment/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://kiro.dev&#34;&gt;Kiro&lt;/a&gt; is AWS&amp;rsquo;s agentic coding tool, available both as an IDE and a CLI. I&amp;rsquo;ve been using the CLI a lot lately, including for AWS work where I let it run &lt;code&gt;aws&lt;/code&gt; commands on my behalf. It works well. But the moment you point it at a real AWS account from a laptop that already has prod credentials configured locally, there&amp;rsquo;s a gap nobody talks about.&lt;/p&gt;
&lt;p&gt;You probably have a dozen profiles in &lt;code&gt;~/.aws/config&lt;/code&gt;. Setting up a dedicated IAM role for Kiro and pointing &lt;code&gt;AWS_PROFILE&lt;/code&gt; at it doesn&amp;rsquo;t actually stop Kiro from running &lt;code&gt;aws --profile prod-admin ec2 terminate-instances&lt;/code&gt;. The CLI reads the whole config file and that profile is right there. &lt;code&gt;AWS_PROFILE&lt;/code&gt; only sets a default. It restricts nothing.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This post is CLI-first. The IDE works the same way for steps 1 and 2, and I&amp;rsquo;ll note the differences at the end. Production accounts only — if you&amp;rsquo;re playing in a sandbox, none of this matters much.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;step-1-a-read-only-iam-role-for-kiro&#34;&gt;Step 1: A read-only IAM role for Kiro&lt;/h3&gt;
&lt;p&gt;Start from the AWS managed policy &lt;code&gt;ReadOnlyAccess&lt;/code&gt; and strip what you don&amp;rsquo;t want the agent reading. At minimum, deny reads on &lt;strong&gt;Secrets Manager&lt;/strong&gt;, &lt;strong&gt;SSM SecureString parameters&lt;/strong&gt;, and anything storing customer data.&lt;/p&gt;
&lt;p&gt;Use &lt;strong&gt;IAM Identity Center&lt;/strong&gt; to access the role via SSO. No long-lived access keys. Credentials are short-lived, they expire on their own, and CloudTrail records the actual user who assumed the role.&lt;/p&gt;
&lt;p&gt;A permission boundary on top of this role is a good idea, but out of scope for this post. The role&amp;rsquo;s permissions policy is your ceiling for now.&lt;/p&gt;
&lt;h3 id=&#34;step-2-isolate-kiros-aws-config-from-your-shells&#34;&gt;Step 2: Isolate Kiro&amp;rsquo;s AWS config from your shell&amp;rsquo;s&lt;/h3&gt;
&lt;p&gt;This is the part that matters.&lt;/p&gt;
&lt;p&gt;The AWS CLI and SDK read &lt;code&gt;~/.aws/config&lt;/code&gt; and &lt;code&gt;~/.aws/credentials&lt;/code&gt; by default. Both file locations can be overridden with environment variables:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AWS_CONFIG_FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=~/.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aws&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kiro&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AWS_SHARED_CREDENTIALS_FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=~/.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aws&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kiro&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;credentials&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When these are set, the SDK ignores the default files entirely. Profiles that aren&amp;rsquo;t in the file you specified simply do not exist as far as &lt;code&gt;aws&lt;/code&gt; is concerned. &lt;strong&gt;This is the only mechanism that actually prevents Kiro from seeing your other profiles.&lt;/strong&gt; Filtering file reads at the agent level (which we&amp;rsquo;ll add in step 3) is not enough on its own, because the AWS SDK reads &lt;code&gt;~/.aws/config&lt;/code&gt; directly without going through the agent&amp;rsquo;s &lt;code&gt;fs_read&lt;/code&gt; tool.&lt;/p&gt;
&lt;p&gt;Create the isolated config. Put every Kiro profile you&amp;rsquo;ll need in here. Start with read-only and add a write role for the dev account. Add a prod read-only role too if you want Kiro to be able to look at prod without being able to change it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# ~/.aws/kiro/config
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[profile kiro-readonly]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_session = my-sso
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_account_id = 123456789012
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_role_name = KiroReadOnly
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;region = us-east-1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[profile kiro-dev-write]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_session = my-sso
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_account_id = 123456789012
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_role_name = KiroDevWrite
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;region = us-east-1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[profile kiro-prod-readonly]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_session = my-sso
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_account_id = 999999999999
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_role_name = KiroReadOnly
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;region = us-east-1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[sso-session my-sso]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_start_url = https://my-org.awsapps.com/start
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_region = us-east-1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sso_registration_scopes = sso:account:access
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Touch an empty credentials file alongside it so the SDK doesn&amp;rsquo;t fall back to anything else:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;touch ~/.aws/kiro/credentials
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chmod 600 ~/.aws/kiro/credentials
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now you need to make sure Kiro is launched with these env vars set, plus a default profile. Kiro doesn&amp;rsquo;t have a way to set env vars for its shell tool yet (&lt;a href=&#34;https://github.com/kirodotdev/Kiro/issues/40&#34;&gt;kirodotdev/Kiro#40&lt;/a&gt;), so the vars have to be set in the parent process. The cleanest way I&amp;rsquo;ve found is a shell alias in &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;alias kiro-aws=&amp;#39;AWS_CONFIG_FILE=~/.aws/kiro/config \
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  AWS_SHARED_CREDENTIALS_FILE=~/.aws/kiro/credentials \
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  AWS_PROFILE=kiro-readonly \
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  kiro-cli chat --agent aws-readonly&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Always launch Kiro for AWS work with &lt;code&gt;kiro-aws&lt;/code&gt; instead of &lt;code&gt;kiro-cli&lt;/code&gt; directly. From inside the session, ask it to run &lt;code&gt;aws configure list-profiles&lt;/code&gt;. You should see only the kiro-* profiles. If &lt;code&gt;prod-admin&lt;/code&gt; shows up, the isolation didn&amp;rsquo;t take.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This step alone takes Kiro from &amp;ldquo;could touch anything you have credentials for&amp;rdquo; to &amp;ldquo;physically cannot see your other accounts&amp;rdquo;.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;step-3-a-custom-agent-and-a-steering-document&#34;&gt;Step 3: A custom agent and a steering document&lt;/h3&gt;
&lt;p&gt;Kiro CLI lets you define custom agents in &lt;code&gt;~/.kiro/agents/&amp;lt;n&amp;gt;.json&lt;/code&gt; with their own tool settings. The CLI has a dedicated &lt;code&gt;use_aws&lt;/code&gt; tool that calls AWS APIs directly, separate from the general &lt;code&gt;shell&lt;/code&gt; tool. Define a custom agent for AWS work:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws-readonly&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS infrastructure assistant. Default read-only access via kiro-* profiles. Write operations require explicit user confirmation and a profile switch. Never attempt to use credentials outside the isolated AWS config.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;shell&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;use_aws&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;thinking&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;grep&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;glob&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;delegate&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;toolsSettings&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;shell&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;autoAllowReadonly&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;resources&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;hooks&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;includeMcpJson&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;model&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A few things going on here. The &lt;code&gt;description&lt;/code&gt; field doubles as a system-level hint, so I put the key constraints right in there. I dropped &lt;code&gt;write&lt;/code&gt; from the tools list — this agent is for AWS investigation, not editing your codebase. If you need file edits in the same session, add it back. &lt;code&gt;delegate&lt;/code&gt; is included so Kiro can spin up sub-tasks for longer investigations (e.g., &amp;ldquo;check all Lambda functions in this account for public URLs&amp;rdquo;). The &lt;code&gt;shell&lt;/code&gt; tool with &lt;code&gt;autoAllowReadonly&lt;/code&gt; lets read-only shell commands run without prompting every time.&lt;/p&gt;
&lt;p&gt;The isolated config from step 2 is doing the heavy lifting regardless. Since it only contains kiro-* profiles, any &lt;code&gt;aws --profile something-else&lt;/code&gt; would just fail with &amp;ldquo;profile not found.&amp;rdquo; The whole point of isolating the config is so we don&amp;rsquo;t have to filter every shell command for safety.&lt;/p&gt;
&lt;p&gt;The steering document lives at &lt;code&gt;~/.kiro/steering/AGENTS.md&lt;/code&gt;. This is where you give the agent enough context to make good decisions on its own, not just a list of don&amp;rsquo;ts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;# AWS Access Rules for Kiro
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Context
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;This environment uses isolated AWS credentials. The only profiles available
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;are in &lt;span class=&#34;sb&#34;&gt;`~/.aws/kiro/config`&lt;/span&gt;, set via &lt;span class=&#34;sb&#34;&gt;`AWS_CONFIG_FILE`&lt;/span&gt;. The standard
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;`~/.aws/config`&lt;/span&gt; is not visible. Do not assume other profiles exist.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Available profiles
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| Profile                | Account     | Access level | Use case                          |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|------------------------|-------------|--------------|-----------------------------------|
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| &lt;span class=&#34;sb&#34;&gt;`kiro-readonly`&lt;/span&gt;        | dev         | read-only    | Default. Inspecting resources.    |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| &lt;span class=&#34;sb&#34;&gt;`kiro-dev-write`&lt;/span&gt;       | dev         | read-write   | Making changes in dev.            |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| &lt;span class=&#34;sb&#34;&gt;`kiro-prod-readonly`&lt;/span&gt;   | production  | read-only    | Investigating prod issues.        |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;`kiro-readonly`&lt;/span&gt; is the default (set via &lt;span class=&#34;sb&#34;&gt;`AWS_PROFILE`&lt;/span&gt;). You do not need to
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pass &lt;span class=&#34;sb&#34;&gt;`--profile`&lt;/span&gt; for it.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Rules
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;### Read operations
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`describe`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`get`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`list`&lt;/span&gt;, and similar read calls can run without asking.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; If you need to look at prod, use &lt;span class=&#34;sb&#34;&gt;`--profile kiro-prod-readonly`&lt;/span&gt; and tell
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  the user you&amp;#39;re switching to the prod account before running the command.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;### Write operations
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Any mutating call (`create`, &lt;span class=&#34;sb&#34;&gt;`update`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`delete`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`put`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`modify`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;sb&#34;&gt;`terminate`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`stop`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`start`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`reboot`&lt;/span&gt;, &lt;span class=&#34;sb&#34;&gt;`invoke`&lt;/span&gt;) requires explicit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  user confirmation before execution.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Before asking for confirmation, state: what you intend to do, which
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  resources will be affected (ARN or name), and which profile you&amp;#39;ll use.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Only use profiles ending in &lt;span class=&#34;sb&#34;&gt;`-write`&lt;/span&gt; for mutations. Never attempt a write
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  call with a read-only profile.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;### Credential boundaries
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; If a call returns &lt;span class=&#34;sb&#34;&gt;`AccessDenied`&lt;/span&gt; or &lt;span class=&#34;sb&#34;&gt;`UnauthorizedAccess`&lt;/span&gt;, stop and ask
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  the user. Do not:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Try a different profile hoping it has more permissions
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Look for credentials in the filesystem
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Suggest the user re-authenticate or assume a different role
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Attempt to modify IAM policies to grant yourself access
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; The permissions you have are intentional. Treat access errors as a signal
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  to check with the user, not a problem to solve.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;### General behavior
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; When running multiple AWS commands in sequence, prefer combining related
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  reads into a single investigation before presenting findings.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; If a task requires both read and write operations, do all the reads first
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  with the read-only profile, present your plan, then switch to the write
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  profile only after the user confirms.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Always include &lt;span class=&#34;sb&#34;&gt;`--output json`&lt;/span&gt; for programmatic parsing. Use `--output
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  table` only when the user asks for a summary view.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &amp;ldquo;credential boundaries&amp;rdquo; section is what prevents the drift behavior. Without it, when Kiro hits an &lt;code&gt;AccessDenied&lt;/code&gt; it will try to find another way around it. The agent is helpful to a fault.&lt;/p&gt;
&lt;h3 id=&#34;step-4-verify-activity-in-cloudtrail&#34;&gt;Step 4: Verify activity in CloudTrail&lt;/h3&gt;
&lt;p&gt;Every API call the agent makes shows up in CloudTrail, tied to the SSO user who assumed the role. The role session name looks something like &lt;code&gt;KiroReadOnly/your_user&lt;/code&gt; or &lt;code&gt;KiroDevWrite/your_user&lt;/code&gt;, so you can tell at a glance which role was used and by whom.&lt;/p&gt;
&lt;p&gt;You can filter for this in the CloudTrail console under &lt;strong&gt;Event history&lt;/strong&gt; by searching for the username &lt;code&gt;KiroReadOnly&lt;/code&gt; (or whatever your role is named). No extra setup required — standard CloudTrail covers this.&lt;/p&gt;
&lt;p&gt;If you have &lt;strong&gt;CloudTrail Lake&lt;/strong&gt; set up, a saved query makes this even faster:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestParameters&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;your_event_data_store&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;userIdentity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sessionContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sessionIssuer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;userName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;LIKE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Kiro%&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventTime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;current_timestamp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;24&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ORDER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventTime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DESC&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Either way, when something looks off in the account, you want CloudTrail to answer &amp;ldquo;what did the agent do&amp;rdquo; without having to ask the agent itself.&lt;/p&gt;
&lt;h3 id=&#34;working-with-write-access&#34;&gt;Working with write access&lt;/h3&gt;
&lt;p&gt;When you actually need Kiro to make changes, just tell it to use the write profile:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Use &lt;code&gt;--profile kiro-dev-write&lt;/code&gt; to update the IAM policy attached to the lambda role.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The steering doc kicks in. Kiro asks for confirmation, explains what it&amp;rsquo;s about to do, and only then runs the command. The IAM role enforces what &lt;code&gt;kiro-dev-write&lt;/code&gt; can actually touch, so even if the agent misreads your prompt the blast radius is bounded by the role&amp;rsquo;s permissions.&lt;/p&gt;
&lt;p&gt;For prod writes, the same pattern. Make a &lt;code&gt;KiroProdWrite&lt;/code&gt; IAM role with very narrow permissions, add a &lt;code&gt;kiro-prod-write&lt;/code&gt; profile to the isolated config, and ask Kiro to use it explicitly when you need it. Roles are cheap. Blast radius is not.&lt;/p&gt;
&lt;h3 id=&#34;a-note-on-the-ide&#34;&gt;A note on the IDE&lt;/h3&gt;
&lt;p&gt;The Kiro IDE doesn&amp;rsquo;t have a &lt;code&gt;use_aws&lt;/code&gt; tool. All AWS commands go through the shell tool, which means the config isolation from step 2 and the steering document are your primary guardrails. Steps 1 and 2 apply identically: create the role, isolate the config, then launch the IDE from a terminal where the env vars are already exported so the IDE&amp;rsquo;s agent inherits them. Step 3&amp;rsquo;s custom agent JSON is CLI-only, but the steering doc at &lt;code&gt;~/.kiro/steering/AGENTS.md&lt;/code&gt; is read by both.&lt;/p&gt;
&lt;h3 id=&#34;thats-it&#34;&gt;That&amp;rsquo;s it&lt;/h3&gt;
&lt;p&gt;The IAM role gets all the airtime, but the config isolation in step 2 is what actually keeps Kiro from drifting into the wrong account when you&amp;rsquo;re moving fast.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
