# Cross-Principal IAM Enumeration Model (CPIEM)

The original idea of Cross-Principal IAM Enumeration Model (CPIEM) came from the difficulty occurring with the single-principal IAM enumeration approach. In the enumeration phase of penetration testing process, penetration testers often gather multiple AWS credentials in the format: AccessKey, SecretKey, Session Token. But it could only perform separate-principal or single-principal IAM enumeration from each user session, leading to false negatives due to limitation of principal-specific IAM entitlement vision. To resolve this limitation, Cross-Principal IAM Enumeration Model (CPIEM) was proposed and developed to efficiently perform advanced IAM enumeration across multiple user principals within the AWS Account Id, to complement each user's IAM vision context. By coordinating available sessions of each valid credential simultaneously, it can:

* Discover hidden permissions
* Reveal a more accurate and complete IAM policy landscape for each IAM entity
* Minimize false negatives that typically occur with single-principal IAM enumeration

***

## 1. What is the limitation of the single-principal or separate-principal IAM enumeration model?

In this section, we will point out several scenarios where single-principal or separate-principal IAM enumeration model are highly restricted in enumerating a complete IAM vision context

### Scenario 1: Retrieval of inline policies for user principal

**Chain:** `iam:ListUserPolicies` → `iam:GetUserPolicy`

1. **User A** is permitted to perform `iam:ListUserPolicies` for a specified user, allowing them to list the names of all inline policies attached to that user. However, **User A** does not have `iam:GetUserPolicy`, so cannot retrieve the actual policy documents.
2. **User B** is permitted to perform `iam:GetUserPolicy`, allowing them to retrieve the policy document if given the user name and policy name. However, User B does not have `iam:ListUserPolicies`, so does not know which policy names exist for a user.
3. Therefore, **User A** can list the policy names but not see their content, and **User B** can retrieve policy content but not know which policies to request.

**Conclusion:** Due to the separation of IAM permissions across users, neither user operating independently can retrieve the complete set of inline policies (including detailed documents) for a user; both actions are required in sequence, but split across users. The lack of a single user's ability to execute the full chain - discovering policy name of user's inline policies and then enumerating and retrieving full policy document, prevents complete visibility

***

### Scenario 2: Retrieval of attached managed policies for user principal

**Chain:** `iam:ListAttachedUserPolicies` → `iam:ListPolicyVersions` or `iam:GetPolicy` → `iam:GetPolicyVersion`

1. **User B** has permissions to perform `iam:ListAttachedUserPolicies`, allowing **User B** to list all managed policies attached to a specified IAM user. However, **User B** cannot perform `iam:GetPolicy` or `iam:ListPolicyVersions` and `iam:GetPolicyVersion`, so cannot retrieve the detail documents or at least current version of those policies.
2. **User A** has permissions to perform `iam:ListPolicyVerion`, allowing **User A** to retrieve a managed policy's metadata and current version if provided with the policy ARN. However, **User A** cannot perform `iam:ListAttachedUserPolicies`, so cannot enumerate which policies are attached to any user, nor can **User A** retrieve complete documents if provided policy ARN along with its version due to the lack of `iam:GetPolicyVersion`.
3. **User C** has permission to perform `iam:GetPolicyVersion`, enabling **User C** to retrieve the complete documents of a specific policy version if provided with the policy ARN and version identifier. However, **User C** cannot enumerate attached policies or retrieve policy metadata to understand its current version.
4. As a result, **User B** can enumerate which managed policies are attached to a user, but cannot retrieve their contents or versions. **User A** can retrieve policy metadata and its current version, but cannot enumerate which policies are attached to users, nor retrieve complete documents of given policy ARN and its current version. **User C** can retrieve the contents of a specific managed policy version, but only if provided with both the policy ARN and current version ID. Therefore,  no single user can enumerate and retrieve the full content of all managed policies attached to the groups that a user belongs to.

**Conclusion:** Due to the separation of IAM permissions across users, neither user operating independently can enumerate and retrieve the complete set of all attached managed policies (including detailed documents) for a user. The lack of a single user's ability to execute the full chain - discovering ARN of managed policies attached to a given user, and retrieving full policy documents of those attached managed policies, prevents complete visibility.

***

### Scenario 3: Retrieval of inline policies for in-scope IAM groups

**Chain:** `iam:ListGroupsForUser`  or  `iam:ListGroups + iam:GetGroup`  →  `iam:ListGroupPolicies`  → `iam:GetGroupPolicy`

1. **User B** is permitted to perform `iam:ListGroupPolicies` and `iam:GetGroupPolicy`, enabling User B to enumerate the inline policies attached to a specified IAM group and retrieve the document of a specific inline policy embedded within that group. However, User B does **not** have permissions to perform `iam:ListGroupsForUser`, and therefore cannot determine the IAM groups that they themselves (or any other user) belong to.
2. **User A** is permitted to perform `iam:ListGroupsForUser`, allowing User A to enumerate all IAM groups that a specified IAM user belongs to. However, User A does **not** have permissions to perform `iam:ListGroupPolicies` or `iam:GetGroupPolicy`, so cannot list or retrieve the inline policies attached to any IAM group.
3. As a result, **User B** can enumerate and retrieve inline policies for any group, but does not know which groups they are belonging to (i.e., IAM groups a particular user is a member of). **User A**, on the other hand, can determine group membership for users, but cannot enumerate or retrieve inline policies (including complete documents) for those groups. Therefore, **User B** cannot retrieve any information about inline policies for the IAM groups that they themselves belong to, because they lack the ability to determine their own group membership. Similarly, **User A** can only determine which groups a user belongs to, but cannot retrieve the details of inline policies for those groups.

**Conclusion:** Due to the separation of IAM permissions across users, neither user operating independently can enumerate and retrieve the complete set of inline policies (including detailed documents) for all in-scope IAM groups (i.e., the groups that users they have access to belong to). The lack of a single user's ability to execute the full chain - discovering group membership and then enumerating policy names of in-scope groups' inline policies, and retrieving full policy documents, prevents complete visibility.

***

### Scenario 4: Retrieval of attached managed policies for in-scope IAM groups

**Chain:** `iam:ListGroupsForUser`  or  `iam:ListGroups + iam:GetGroup`  → `iam:ListAttachedGroupPolicies` → `iam:ListPolicyVersion` or `iam:GetPolicy` → `iam:GetPolicyVersion`

1. **User E** can perform `iam:ListGroupsForUser`, enabling them to list all IAM groups that a specified user belongs to. However, User E cannot perform `iam:ListAttachedGroupPolicies` and so cannot determine which managed policies are attached to those groups.
2. **User B** can perform `iam:ListAttachedGroupPolicies`, allowing them to list all managed policies attached to a specified group, but cannot enumerate which groups a user belongs to (`iam:ListGroupsForUser`).
3. **User A** can perform `iam:GetPolicy` and `iam:GetPolicyVersion`, enabling them to retrieve the policy document and its versions, but cannot enumerate which groups exist or which users belong to which groups.
4. As a result, **User E** can enumerate the IAM groups that a specified user belongs to, but cannot determine which managed policies are attached to those groups. **User B** can enumerate all managed policies attached to a specified group, but cannot identify which groups are associated with a specific user. **User A** can retrieve the complete documents and its current version of  managed policies if provided with the policy ARN, but cannot enumerate groups or determine group membership. Therefore, no single user can enumerate and retrieve the complete set of managed policy documents attached to the groups that a user belongs to.

**Conclusion:** Due to the separation of IAM permissions across users, neither user operating independently can enumerate and retrieve the complete set of attached managed policies (including detailed documents) for all in-scope IAM groups (i.e., the groups that users they have access to belong to). The lack of a single user's ability to execute the full chain - discovering group membership and then discovering ARN of managed policies attached to in-scope IAM groups, and retrieving full policy documents of those attached managed policies, prevents complete visibility.

***

### Scenario 5: Retrieval of inline policies for in-scope IAM roles

**Chain:** `iam:ListRoles` → `iam:ListRolePolicies` → `iam:GetRolePolicy`

1. **User A** can perform `iam:ListRoles`, allowing them to enumerate all IAM roles in the account, but cannot list or retrieve inline policies for those roles.
2. **User C** can perform `iam:ListRolePolicies`, allowing them to list the names of inline policies for a specific role, but cannot enumerate all roles (`iam:ListRoles`) or retrieve policy documents.
3. **User D** can perform `iam:GetRolePolicy`, enabling them to retrieve the document of a specific inline policy for a given role and policy name, but cannot list roles or policies.
4. As a result, **User A** can enumerate all in-scope IAM roles in the account, but cannot list or retrieve inline policies (including complete documents) for those roles. **User C** can list the names of inline policies attached to a specific role, but cannot enumerate all in-scope IAM roles or retrieve policy documents. **User D** can retrieve the complete document of inline policies for a given role and policy name, but cannot list roles or enumerate policy names. Therefore, no single user can enumerate and retrieve the complete content of all inline policies attached to all in-scope IAM roles.

**Conclusion:** Due to the separation of IAM permissions across users, neither user operating independently, can enumerate and retrieve the complete set of inline policies (including detailed documents) for all in-scope IAM roles (i.e., the roles that users they have access to can assume). The lack of a single user's ability to execute the full chain - discovering in-scope IAM roles that the user can assume, and then enumerating policy names of in-scope roles' inline policies, and retrieving full policy documents, prevents complete visibility.

***

### Scenario 6: Retrieval of attached managed policies for in-scope IAM roles

**Chain:** `iam:ListRoles` → `iam:ListAttachedRolePolicies` → `iam:ListPolicyVersion` or `iam:GetPolicy` → `iam:GetPolicyVersion`

1. **User B** can perform `iam:ListRoles`, allowing enumeration of all IAM roles. However, User B cannot list attached policies for those roles.
2. **User D** can perform `iam:ListAttachedRolePolicies`, enabling them to list all managed policies attached to a specified role, but cannot enumerate roles or retrieve policy documents.
3. **User A** can perform `iam:GetPolicy` and `iam:GetPolicyVersion`, empowering them to retrieve the document and versions of a managed policy if given the ARN, but cannot list roles or attached policies.
4. As a result, **User B** can enumerate all in-scope IAM roles in the account, but cannot list the managed policies attached to those roles, nor retrieve the complete documents of those managed policies. **User D** can list all managed policies attached to a specified role, but cannot enumerate all in-scope IAM roles or retrieve the complete documents of those managed policies. **User A** can retrieve the complete documents and its current version of managed policies if provided with the policy ARN, but cannot enumerate in-scope IAM roles or determine which policies are attached to in-scope IAM roles. Therefore, no single user can enumerate and retrieve the full content of all managed policies attached to all in-scope IAM roles.

**Conclusion:** Due to the separation of IAM permissions across users, neither user operating independently, can enumerate the complete set of attached managed policies (including detailed documents) for all in-scope IAM roles (i.e., the roles that users they have access to can assume). The lack of a single user's ability to execute the full chain - discovering in-scope IAM roles that the user can assume, and then discovering ARN of managed policies attached to in-scope IAM roles, and retrieving full policy documents of those attached managed policies, prevents complete visibility.

***

### Scenario 7: iam:GetAccountAuthorizationDetails to complement other users' IAM entitlement visibility

**Chain:** `iam:GetAccountAuthorizationDetails`

1. **User B** cannot perform any IAM actions to reveal its IAM entitlement visibility
2. **User C** cannot perform any IAM actions to reveal its IAM entitlement visibility
3. **User A** can perform `iam:GetAccountAuthorizationDetails` , empowering them to retrieve all information of IAMs in their AWS Account Id, including their IAM context.
4. As a result, **User A** can reveal its full IAM context, but **User B** and **User C** cannot reveal any information regarding permissions that they are allowed to perform, and resources that they are allowed to interact.&#x20;

**Conclusion:** Due to the separation of IAM permissions across users, if users are operating independently, **User A** cannot support **User B** and **User C** to enumerate the complete set of their IAM entitlement visibility. This illustrates the limitation of traditional single-user IAM scanning approaches in cloud environments.

***

These 7 scenarios illustrate the limitations of traditional single-principal IAM enumeration approach in cloud environment. By not having sufficient permissions in each phase of the IAM chain, it could lead to the failure of fully revealing any of the inline policies and attached managed policies for IAM users, in-scope IAM groups, in-scope IAM roles, in-scope IAM policies during enumeration process.

***

## 2. How SkyEye mitigates these limitations?

Instead of depending on the self-access IAM entitlement visibility of single user to reveal its IAM context, and to fully understand what permissions and what resources that the user is allowed to perform and interact with, sometimes leading to false negatives when user could perform some specific permissions to specific resources but could not have the self-awareness on that, the cross-entity scanning model which is the core capability of SkyEye is designed to tackle this limitation by involving and correlating simultaneously multiple valid credentials (separated by AWS Account Id) to continually reveal each user's IAM entitlement visibility.&#x20;

Initially, SkyEye will validate the provided AWS credentials, and split them into separate "AWS Account Id" clusters, ensuring that only the users from similar AWS&#x20;Account Id, will be involved in complementing other users’ IAM visibility from similar&#x20;account id.

SkyEye will then construct multi-threaded mechanism to run the enumeration&#x20;from each user’s session simultaneously and perform cross-principal enumerations across&#x20;ARNs of each user, and interact with the shared envIAMData objects - separated by&#x20;AWS Account Id, to store the IAM Users, IAM Groups, IAM Roles, IAM Policies&#x20;gathered from each user’s session in run-time.

Shared envIAMData objects will act as independently shared storage for multiple&#x20;users from each different AWS Account Id, to support each user’s session in adding new  IAM objects or complementing existing ones if missing components are identified in&#x20;those objects before initiating the complementation process.

<figure><img src="https://2776680781-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTLXx9wiMo4Qlo5PcjRAd%2Fuploads%2F7h5hRAxGTyqwHvRkl1d2%2F2.CPIEM-Model.svg?alt=media&#x26;token=a27509a2-11eb-47e3-bd27-847d9b4db30a" alt=""><figcaption><p>Core of SkyEye - Cross-Principal IAM Enumeration Model (CPIEM)</p></figcaption></figure>

<figure><img src="https://2776680781-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTLXx9wiMo4Qlo5PcjRAd%2Fuploads%2FSlmI0GOZYijqYspE5qRG%2F3.CPIEM-Model-2.svg?alt=media&#x26;token=193b44ef-479f-4e2b-8575-f18f63f13aaa" alt=""><figcaption><p>The Interconnection in Cross-Principal IAM Enumeration Model (CPIEM)</p></figcaption></figure>

In addition to the IAM chains to fully reveal inline policies and attached managed policies for IAM users, in-scope IAM groups, in-scope IAM roles, in-scope IAM policies, during the enumeration process, if the iam:GetAccountAuthorizationDetails permission is detected in run-time to be executable by at least one user’s session from similar AWS Account Id, the model will immediately terminate all user’s session come from that AWS Account Id, and utilize the iam:GetAccountAuthorizationDetails permission to retrieve full IAM context of that AWS Account Id, and distribute the correspondent result to the user principal that involved in the IAM enumeration for that AWS Account Id. This approach will reduce significantly 95% of the entire scanning process, and result in a most sufficient IAM output for each involved user principal while not producing redundant API invocation, potentially leading to detectable traces in logging.

The efficacy of the SkyEye CPIEM model is best demonstrated through a representative operational scenario, which underscores its utility in advanced IAM enumeration. Consider a context wherein the enumeration engine, such as SkyEye, processes active sessions for five distinct user principals: User\_A, User\_B, User\_C, User\_D, and User\_E, each instantiated with unique AWS credential pairs. Each principal is provisioned with a discrete, non-overlapping subset of IAM permissions:

* **User\_A:** Lacks explicit permissions to perform any IAM actions.
* **User\_B:** `iam:GetUserPolicy`, `iam:GetGroupPolicy`, `iam:GetRolePolicy`, `iam:GetPolicy`, and `iam:ListPolicyVersion`
* **User\_C:** `iam:ListUserPolicies`, `iam:ListAttachedUserPolicies`, `iam:ListGroupPolicies`, `iam:ListAttachedGroupPolicies`, `iam:ListRolePolicies`, and `iam:ListAttachedRolePolicies`
* **User\_D:** `iam:GetPolicyVersion`
* **User\_E:** `iam:ListRoles`, `iam:ListGroupsForUser`

In a traditional enumeration paradigm where each set of credentials is leveraged in isolation, and the enumeration process is constrained either to a single principal or to disjoint, parallel sessions per principal, the discoverability of the broader IAM topology becomes inherently limited. The inability to synthesize and correlate permissions across user boundaries leads to a fragmented security posture analysis, potentially obscuring critical relationships and privilege escalation vectors within the AWS environment.

The CPIEM model overcomes these limitations by enabling concurrent, synchronized enumeration sessions across all available user principals. This cooperative multi-principal framework facilitates the aggregation and cross-correlation of disparate permission sets, thereby augmenting the granularity and completeness of the overall IAM visibility. For instance, while User\_A cannot directly access or enumerate any IAM resources, the intersection and union of the permissions held by User\_B, User\_C, User\_D, and User\_E when orchestrated in concert, can collectively reconstruct a comprehensive access control map, not only for User\_A but for each principal under scrutiny.

<figure><img src="https://2776680781-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTLXx9wiMo4Qlo5PcjRAd%2Fuploads%2FGqtsHeq6DLYckLjLXur6%2FCPIEM-Example.svg?alt=media&#x26;token=ca66cd99-67d3-477c-8694-94ab991419dc" alt=""><figcaption><p>Cross-Principal IAM Enumeration Model - Example Scenario</p></figcaption></figure>

Furthermore, the model’s capability to dynamically integrate the results of each enumeration session ensures a holistic perspective, wherein the knowledge gleaned from one principal’s permissions enriches the contextual understanding of others. This approach significantly enhances the identification of implicit trust relationships, hidden privilege chains, and potential security misconfigurations, which are core concerns in advanced IAM threat modeling and defense. By operationalizing multi-principal enumeration and correlation, the CPIEM model advances the state of the art in IAM reconnaissance, supporting both offensive and defensive cybersecurity postures within complex cloud ecosystems.

At the end of this scenario, not only the complete IAM vision context of User\_A will be discovered, but also the complete IAM vision context of all the involving user principals: User\_B, User\_C, User\_D, User\_E; facilitating the capability of understanding the permissions and resources that they are allowed to interact with, opening to further privilege escalation vectors or AWS actions that can be abusable in the future attack vectors.
