Jekyll2023-11-08T15:34:03+00:00https://danpilch.github.io/feed/community.xmlDan Pilch | CommunityPersonal and Professional blogDan PilchAWS CSM - Figuring out what permissions your app really needs2021-02-08T00:00:00+00:002021-02-08T00:00:00+00:00https://danpilch.github.io/community/2021/02/08/aws-csm-iam-permissions<p>I know the feeling all too well, trying to find the right balance of IAM permissions
without opening up your policy to <code class="language-plaintext highlighter-rouge">["ec2:*"]</code>. Figuring out every permission your
application requires can be an arduous process but there is a better way.</p>
<h2 id="aws-client-side-monitoring-csm">AWS Client Side Monitoring (CSM)</h2>
<p>CSM enables sending metrics via UDP connection to a CSM agent. The agent could
be anything, in this example I will use <a href="https://linux.die.net/man/1/nc">nc</a>.</p>
<p>You can enable CSM with your SDK of choice with:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">AWS_CSM_ENABLED</span><span class="o">=</span><span class="nb">true
export </span><span class="nv">AWS_CSM_PORT</span><span class="o">=</span>31000
<span class="nb">export </span><span class="nv">AWS_CSM_HOST</span><span class="o">=</span>127.0.0.1
</code></pre></div></div>
<p>Or by editing your <code class="language-plaintext highlighter-rouge">~/.aws/config</code> file:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[default]</span>
<span class="py">default_region</span> <span class="p">=</span> <span class="s">us-west-2</span>
<span class="py">csm_enabled</span> <span class="p">=</span> <span class="s">true</span>
</code></pre></div></div>
<p>You can use the <code class="language-plaintext highlighter-rouge">awscli</code> or with an SDK for example the <a href="https://docs.aws.amazon.com/sdk-for-go/api/aws/csm/">go sdk</a></p>
<p>Once you’ve configured your sdk/cli, you can start <code class="language-plaintext highlighter-rouge">nc</code> listening on the default
host and port:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nc <span class="nt">-kluvw</span> 0 127.0.0.1 31000
</code></pre></div></div>
<p>Now you can invoke an aws api call, I’ll use the <code class="language-plaintext highlighter-rouge">awscli</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>aws ec2 describe-instances
</code></pre></div></div>
<p>If we look at the <code class="language-plaintext highlighter-rouge">nc</code> in terminal:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"Version"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
</span><span class="nl">"ClientId"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
</span><span class="nl">"Type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ApiCallAttempt"</span><span class="p">,</span><span class="w">
</span><span class="nl">"Service"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EC2"</span><span class="p">,</span><span class="w">
</span><span class="nl">"Api"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DescribeInstances"</span><span class="p">,</span><span class="w">
</span><span class="nl">"Timestamp"</span><span class="p">:</span><span class="w"> </span><span class="mi">1612776146962</span><span class="p">,</span><span class="w">
</span><span class="nl">"AttemptLatency"</span><span class="p">:</span><span class="w"> </span><span class="mi">9206</span><span class="p">,</span><span class="w">
</span><span class="nl">"Fqdn"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ec2.us-west-2.amazonaws.com"</span><span class="p">,</span><span class="w">
</span><span class="nl">"UserAgent"</span><span class="p">:</span><span class="w"> </span><span class="s2">"aws-cli/1.18.155 Python/3.8.7 Darwin/19.6.0 botocore/1.18.14"</span><span class="p">,</span><span class="w">
</span><span class="nl">"AccessKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
</span><span class="nl">"Region"</span><span class="p">:</span><span class="w"> </span><span class="s2">"us-west-2"</span><span class="p">,</span><span class="w">
</span><span class="nl">"HttpStatusCode"</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span><span class="w">
</span><span class="nl">"XAmznRequestId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"08550f64-cd15-4dac-870e-3b5bd59a010b"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>We’re interested in:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"Service"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EC2"</span><span class="err">,</span><span class="w"> </span><span class="nl">"Api"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DescribeInstances"</span><span class="w">
</span></code></pre></div></div>
<p>From this we can surmise we require <code class="language-plaintext highlighter-rouge">EC2:DescribeInstances</code>.</p>
<h3 id="realtime-iam--policy-generation">Realtime IAM Policy Generation</h3>
<p>I found a great application called <a href="https://github.com/iann0036/iamlive">iamlive</a> which can build a policy in realtime from <code class="language-plaintext highlighter-rouge">csm</code> requests. Check it out!</p>Dan PilchI know the feeling all too well, trying to find the right balance of IAM permissions without opening up your policy to ["ec2:*"]. Figuring out every permission your application requires can be an arduous process but there is a better way.