Post

AWS IAM Unique Identifiers: What Are Those Weird IDs in IAM Policies?

AWS IAM Unique Identifiers: What Are Those Weird IDs in IAM Policies?

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.

I couldn’t find anything wrong in Account A - the roles were there with the right names. So I checked Account B, 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:

1
2
3
"Principal": {
  "AWS": "arn:aws:iam::123456789012:role/MyRole"
}

Instead, I found this cryptic mess:

1
2
3
"Principal": {
  "AWS": "AROADBQP57FF2AEXAMPLE"
}

What the hell is AROADBQP57FF2AEXAMPLE? Let me explain what happened and save you from the same headache.

What Are IAM Unique Identifiers?

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:

1
aws iam get-role --role-name MyAppRole

Output:

1
2
3
4
5
6
7
8
{
    "Role": {
        "RoleName": "MyAppRole",
        "RoleId": "AROA1234567890EXAMPLE",
        "Arn": "arn:aws:iam::123456789012:role/MyAppRole",
        "CreateDate": "2024-01-15T10:30:00Z"
    }
}

See that RoleId? That’s the unique identifier - AROA1234567890EXAMPLE.

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.

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

Role ARNUnique IDDateStatus
arn:aws:iam::123456789012:role/MyAppRoleAROA1234567890EXAMPLE2024-01-15Original role
arn:aws:iam::123456789012:role/MyAppRoleAROA1234567890EXAMPLE2024-02-10DELETED
arn:aws:iam::123456789012:role/MyAppRoleAROA9876543210EXAMPLE2024-02-14Recreated (new ID!)

The Cross-Account Problem

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:

1
2
3
4
5
6
7
8
9
10
11
Account A (111111111111)                    Account B (222222222222)
┌─────────────────────────────┐             ┌─────────────────────────────┐
│                             │             │                             │
│  MyAppRole                  │             │  MyServiceRole              │
│  AROA1234567890EXAMPLE      │<────────────┤  Trust Policy:              │
│                             │             │  "Principal": {             │
└─────────────────────────────┘             │    "AWS": "arn:aws:iam::    │
                                            │     111111111111:role/      │
                                            │     MyAppRole"              │
                                            │  }                          │
                                            └─────────────────────────────┘

What AWS actually stores in Account B:

1
2
3
4
5
{
  "Principal": {
    "AWS": "AROA1234567890EXAMPLE"
  }
}

After you delete and recreate MyAppRole in Account A:

1
2
3
4
5
6
7
8
9
10
Account A (111111111111)                    Account B (222222222222)
┌─────────────────────────────┐             ┌─────────────────────────────┐
│                             │             │                             │
│  MyAppRole                  │             │  MyServiceRole              │
│  AROA9876543210EXAMPLE      │<-- BROKEN -─┤  Trust Policy:              │
│  (NEW UNIQUE ID!)           │             │  "Principal": {             │
└─────────────────────────────┘             │    "AWS": "AROA1234567890   │
                                            │     EXAMPLE"                │
                                            │  }  (OLD ID!)               │
                                            └─────────────────────────────┘

The fix: 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).

Understanding the Prefixes

The first few letters tell you what type of resource it is:

PrefixWhat It Is
AIDAIAM User
AROAIAM Role
AGPAIAM Group
ANPAManaged Policy
AKIAAccess Key
ASIATemporary Access Key
AIPAInstance Profile

When You’ll See These IDs

In CloudTrail Logs

1
2
3
4
5
6
{
  "userIdentity": {
    "principalId": "AIDACKCEVSQ6C2EXAMPLE",
    "userName": "John"
  }
}

In AWS CLI Output

1
2
3
4
5
6
aws sts get-caller-identity
{
    "UserId": "AIDACKCEVSQ6C2EXAMPLE",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/John"
}

In Policies

Sometimes AWS services or tools create policies using unique IDs instead of friendly names:

1
2
3
4
5
{
  "Principal": {
    "AWS": "AIDACKCEVSQ6C2EXAMPLE"
  }
}

Should You Use These in Your Policies?

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

Good - readable and clear

1
2
3
"Principal": {
  "AWS": "arn:aws:iam::123456789012:user/John"
}

Bad - who is this person?

1
2
3
"Principal": {
  "AWS": "AIDACKCEVSQ6C2EXAMPLE"
}

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

The Bottom Line

Next time you see a weird string like AROADBQP57FF2AEXAMPLE in your policies, don’t panic - it’s just AWS’s internal ID for a resource that got deleted.

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

This simple knowledge can save you hours of debugging broken cross-account access.

Hope this helps, see you next time buddy!


Source: AWS IAM Identifiers Documentation

This post is licensed under CC BY 4.0 by the author.

Trending Tags