<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://devopsmike.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://devopsmike.com/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-05-24T13:15:20+02:00</updated><id>https://devopsmike.com/feed.xml</id><title type="html">DevOpsMike</title><subtitle>AWS and DevOps Tips &amp; Best Practices.</subtitle><entry><title type="html">AWS IAM Unique Identifiers: What Are Those Weird IDs in IAM Policies?</title><link href="https://devopsmike.com/posts/aws-iam-unique-identifiers-security-guide/" rel="alternate" type="text/html" title="AWS IAM Unique Identifiers: What Are Those Weird IDs in IAM Policies?" /><published>2026-01-02T15:00:00+01:00</published><updated>2026-01-02T15:00:00+01:00</updated><id>https://devopsmike.com/posts/aws-iam-unique-identifiers-security-guide</id><content type="html" xml:base="https://devopsmike.com/posts/aws-iam-unique-identifiers-security-guide/"><![CDATA[<p>Hey buddy, how’s it going? Today I want to talk about something that gave me a headache some time ago. I had cross-account access set up between two AWS accounts. After a while I deleted some IAM roles in Account A and recreated them with the exact same names. Everything looked fine, but suddenly my cross-account access stopped working.</p>

<p>I couldn’t find anything wrong in <code class="language-plaintext highlighter-rouge">Account A</code> - the roles were there with the right names. So I checked <code class="language-plaintext highlighter-rouge">Account B</code>, thinking there was no way anything could be wrong there since I hadn’t even touched it. When I looked at the assume role policy, I expected to see something normal like:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nl">"Principal"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"AWS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"arn:aws:iam::123456789012:role/MyRole"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>Instead, I found this cryptic mess:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nl">"Principal"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"AWS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AROADBQP57FF2AEXAMPLE"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>What the hell is <code class="language-plaintext highlighter-rouge">AROADBQP57FF2AEXAMPLE</code>? Let me explain what happened and save you from the same headache.</p>

<h2 id="what-are-iam-unique-identifiers">What Are IAM Unique Identifiers?</h2>

<p>Behind every IAM resource (users, roles, groups, policies) is a unique identifier that AWS assigns automatically. You can’t see these IDs in the AWS web console, but they’re there. Here’s how to find them using the CLI:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>aws iam get-role <span class="nt">--role-name</span> MyAppRole
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Output:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre><span class="p">{</span><span class="w">
    </span><span class="nl">"Role"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"RoleName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"MyAppRole"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"RoleId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AROA1234567890EXAMPLE"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"Arn"</span><span class="p">:</span><span class="w"> </span><span class="s2">"arn:aws:iam::123456789012:role/MyAppRole"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"CreateDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2024-01-15T10:30:00Z"</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>See that <code class="language-plaintext highlighter-rouge">RoleId</code>? That’s the unique identifier - <code class="language-plaintext highlighter-rouge">AROA1234567890EXAMPLE</code>.</p>

<p>The key point: when you delete and recreate a role with the same name, the ARN stays identical but the unique ID changes completely. That’s why you end up with orphaned unique IDs in your policies.</p>

<p>Here’s what happens when you create and recreate roles using the same names:</p>

<table>
  <thead>
    <tr>
      <th>Role ARN</th>
      <th>Unique ID</th>
      <th>Date</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">arn:aws:iam::123456789012:role/MyAppRole</code></td>
      <td><code class="language-plaintext highlighter-rouge">AROA1234567890EXAMPLE</code></td>
      <td>2024-01-15</td>
      <td>Original role</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">arn:aws:iam::123456789012:role/MyAppRole</code></td>
      <td><code class="language-plaintext highlighter-rouge">AROA1234567890EXAMPLE</code></td>
      <td>2024-02-10</td>
      <td><strong>DELETED</strong></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">arn:aws:iam::123456789012:role/MyAppRole</code></td>
      <td><code class="language-plaintext highlighter-rouge">AROA9876543210EXAMPLE</code></td>
      <td>2024-02-14</td>
      <td>Recreated (new ID!)</td>
    </tr>
  </tbody>
</table>

<h2 id="the-cross-account-problem">The Cross-Account Problem</h2>

<p>Here’s where this really bites you. When you create a cross-account trust policy, AWS automatically converts ARNs to unique IDs behind the scenes:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="rouge-code"><pre>Account A (111111111111)                    Account B (222222222222)
┌─────────────────────────────┐             ┌─────────────────────────────┐
│                             │             │                             │
│  MyAppRole                  │             │  MyServiceRole              │
│  AROA1234567890EXAMPLE      │&lt;────────────┤  Trust Policy:              │
│                             │             │  "Principal": {             │
└─────────────────────────────┘             │    "AWS": "arn:aws:iam::    │
                                            │     111111111111:role/      │
                                            │     MyAppRole"              │
                                            │  }                          │
                                            └─────────────────────────────┘
</pre></td></tr></tbody></table></code></pre></div></div>

<p><strong>What AWS actually stores in Account B:</strong></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="p">{</span><span class="w">
  </span><span class="nl">"Principal"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"AWS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AROA1234567890EXAMPLE"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p><strong>After you delete and recreate MyAppRole in Account A:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="rouge-code"><pre>Account A (111111111111)                    Account B (222222222222)
┌─────────────────────────────┐             ┌─────────────────────────────┐
│                             │             │                             │
│  MyAppRole                  │             │  MyServiceRole              │
│  AROA9876543210EXAMPLE      │&lt;-- BROKEN -─┤  Trust Policy:              │
│  (NEW UNIQUE ID!)           │             │  "Principal": {             │
└─────────────────────────────┘             │    "AWS": "AROA1234567890   │
                                            │     EXAMPLE"                │
                                            │  }  (OLD ID!)               │
                                            └─────────────────────────────┘
</pre></td></tr></tbody></table></code></pre></div></div>

<p><strong>The fix:</strong> You must update the trust policy in Account B to reference the new unique ID or recreate it with the ARN (which will get converted to the new ID).</p>

<h2 id="understanding-the-prefixes">Understanding the Prefixes</h2>

<p>The first few letters tell you what type of resource it is:</p>

<table>
  <thead>
    <tr>
      <th>Prefix</th>
      <th>What It Is</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">AIDA</code></td>
      <td>IAM User</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">AROA</code></td>
      <td>IAM Role</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">AGPA</code></td>
      <td>IAM Group</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ANPA</code></td>
      <td>Managed Policy</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">AKIA</code></td>
      <td>Access Key</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ASIA</code></td>
      <td>Temporary Access Key</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">AIPA</code></td>
      <td>Instance Profile</td>
    </tr>
  </tbody>
</table>

<h2 id="when-youll-see-these-ids">When You’ll See These IDs</h2>

<h3 id="in-cloudtrail-logs">In CloudTrail Logs</h3>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre><span class="p">{</span><span class="w">
  </span><span class="nl">"userIdentity"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"principalId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AIDACKCEVSQ6C2EXAMPLE"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"userName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="in-aws-cli-output">In AWS CLI Output</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre>aws sts get-caller-identity
<span class="o">{</span>
    <span class="s2">"UserId"</span>: <span class="s2">"AIDACKCEVSQ6C2EXAMPLE"</span>,
    <span class="s2">"Account"</span>: <span class="s2">"123456789012"</span>,
    <span class="s2">"Arn"</span>: <span class="s2">"arn:aws:iam::123456789012:user/John"</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="in-policies">In Policies</h3>
<p>Sometimes AWS services or tools create policies using unique IDs instead of friendly names:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="p">{</span><span class="w">
  </span><span class="nl">"Principal"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"AWS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AIDACKCEVSQ6C2EXAMPLE"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="should-you-use-these-in-your-policies">Should You Use These in Your Policies?</h2>

<p><strong>Generally, no.</strong> Stick with names and ARNs - they’re much more readable and maintainable, look at these two examples below.</p>

<p>Good - readable and clear</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nl">"Principal"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"AWS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"arn:aws:iam::123456789012:user/John"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>Bad - who is this person?</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nl">"Principal"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"AWS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AIDACKCEVSQ6C2EXAMPLE"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>Sure both of them work, but if you want your colleagues not to hate you - go with the first option.</p>

<h2 id="the-bottom-line">The Bottom Line</h2>

<p>Next time you see a weird string like <code class="language-plaintext highlighter-rouge">AROADBQP57FF2AEXAMPLE</code> in your policies, don’t panic - it’s just AWS’s internal ID for a resource that got deleted.</p>

<p><strong>Quick fix</strong>: Update the policy with the current ARN, and AWS will convert it to the new unique ID automatically.</p>

<p>This simple knowledge can save you hours of debugging broken cross-account access.</p>

<p>Hope this helps, see you next time buddy!</p>

<hr />

<p><strong>Source</strong>: <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids">AWS IAM Identifiers Documentation</a></p>]]></content><author><name></name></author><category term="AWS" /><category term="IAM" /><category term="aws" /><category term="iam" /><category term="deep-dive" /><summary type="html"><![CDATA[Ever seen mysterious IDs like AROADBQP57FF2AEXAMPLE in your IAM policies and wondered what they are? Here's the simple explanation.]]></summary></entry></feed>