AWS Cognito Unauthenticated Identity Pool Credentials Issued
Identifies AWS CloudTrail data events where an unauthenticated identity successfully retrieves temporary AWS credentials from a Cognito Identity Pool via GetCredentialsForIdentity. Cognito Identity Pools can be configured to allow unauthenticated (guest) access, intended for scenarios like anonymous app analytics, but a pool that grants those anonymous identities meaningful IAM permissions becomes a public, unauthenticated path to real AWS credentials. Adversaries who discover an identity pool ID (often embedded in mobile app binaries, web app JavaScript, or public source repositories) can call GetId followed by GetCredentialsForIdentity with no login token at all to obtain temporary credentials, then use them to access whatever the pool's unauthenticated role permits. This is a New Terms rule that limits alerting to identity pools that have not been observed issuing credentials to an unauthenticated caller before, since some applications intentionally and continuously use guest access as part of normal operation.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/07/13"
3integration = ["aws"]
4maturity = "production"
5updated_date = "2026/07/13"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies AWS CloudTrail data events where an unauthenticated identity successfully retrieves temporary AWS credentials
11from a Cognito Identity Pool via GetCredentialsForIdentity. Cognito Identity Pools can be configured to allow
12unauthenticated (guest) access, intended for scenarios like anonymous app analytics, but a pool that grants those
13anonymous identities meaningful IAM permissions becomes a public, unauthenticated path to real AWS credentials.
14Adversaries who discover an identity pool ID (often embedded in mobile app binaries, web app JavaScript, or public
15source repositories) can call GetId followed by GetCredentialsForIdentity with no login token at all to obtain
16temporary credentials, then use them to access whatever the pool's unauthenticated role permits. This is a New Terms
17rule that limits alerting to identity pools that have not been observed issuing credentials to an unauthenticated caller
18before, since some applications intentionally and continuously use guest access as part of normal operation.
19"""
20false_positives = [
21 """
22 Applications that intentionally allow unauthenticated Identity Pool access for legitimate purposes (for example,
23 anonymous usage analytics or unauthenticated content delivery) will trigger this rule the first time that pattern is
24 observed for a given identity pool. Confirm whether the pool's unauthenticated role grants only the minimal
25 permissions the application actually needs, and treat repeated alerts for the same pool as expected once validated.
26 """,
27]
28from = "now-6m"
29index = ["logs-aws.cloudtrail-*"]
30language = "kuery"
31license = "Elastic License v2"
32name = "AWS Cognito Unauthenticated Identity Pool Credentials Issued"
33note = """## Triage and analysis
34
35### Investigating AWS Cognito Unauthenticated Identity Pool Credentials Issued
36
37Amazon Cognito Identity Pools can be configured with `AllowUnauthenticatedIdentities`, letting a caller obtain a
38guest identity via `GetId` and then temporary AWS credentials via `GetCredentialsForIdentity`, with no login token or
39authentication of any kind. This is by design for use cases like anonymous app analytics, but if the pool's
40unauthenticated IAM role is overpermissioned, anyone who discovers the identity pool ID gets a free, unauthenticated
41path to real AWS credentials.
42
43This rule fires the first time a given identity pool is observed issuing credentials to an unauthenticated caller
44(`aws.cloudtrail.user_identity.type: "Unknown"`).
45
46#### Possible investigation steps
47
48- **Identify the pool**: review `aws.cloudtrail.resources.arn` to determine which identity pool issued the
49 credentials, and `aws.cloudtrail.request_parameters.identityId` for the specific guest identity.
50- **Confirm this is intentional guest access**: check whether the application this pool belongs to is designed for
51 anonymous/unauthenticated use (for example, a public mobile app or website with anonymous analytics).
52- **Review the unauthenticated role's permissions**: run
53 `aws cognito-identity get-identity-pool-roles --identity-pool-id <pool id>` and inspect the attached policy for the
54 unauthenticated role. Broad permissions (data store read/write, `iam:*`, cross-service access) on a role reachable
55 without authentication is a critical misconfiguration regardless of whether this specific call was malicious.
56- **Review source context**: check `source.ip`, `user_agent.original`, and `source.geo` for the calling identity. A
57 source unrelated to the application's expected client base (for example, a generic AWS SDK/CLI user agent instead
58 of a mobile/browser client) is a stronger indicator of discovery/abuse rather than normal app traffic.
59- **Look for follow-on activity**: search for subsequent API calls made using credentials tied to the same
60 `identityId` or the unauthenticated role's ARN, to determine what the caller actually did with the credentials.
61- **Look for pool enumeration**: check for `ListIdentityPools` or repeated `GetId`/`GetCredentialsForIdentity` calls
62 against multiple different identity pools from the same source in a short window, which suggests systematic
63 discovery rather than a single legitimate app session.
64
65### False positive analysis
66
67- Many applications intentionally use unauthenticated Identity Pool access for anonymous analytics or public content
68 delivery. This rule fires once per identity pool the first time this pattern is observed; if confirmed as
69 intentional and properly scoped (minimal unauthenticated role permissions), no further action is needed for that
70 pool.
71
72### Response and remediation
73
74- If the unauthenticated role is overpermissioned, scope it down immediately to the minimum required for legitimate
75 anonymous use, or disable `AllowUnauthenticatedIdentities` entirely if guest access is not required.
76- If credentials were abused, review all activity performed under the unauthenticated role's ARN during the
77 credential's validity window and revoke/rotate as appropriate (temporary credentials cannot be revoked directly,
78 but the role's trust policy or permissions can be tightened immediately).
79- Treat any identity pool ID found in client-side code (mobile app binaries, web JavaScript) as public information,
80 and ensure the unauthenticated role attached to it is scoped accordingly.
81
82"""
83references = [
84 "https://docs.aws.amazon.com/cognito/latest/developerguide/identity-pool-roles.html",
85 "https://docs.aws.amazon.com/cognito/latest/developerguide/logging-using-cloudtrail.html",
86 "https://hackingthe.cloud/aws/exploitation/cognito_identity_pool_excessive_privileges/",
87 "https://github.com/RhinoSecurityLabs/pacu/tree/master/pacu/modules/cognito__attack",
88]
89risk_score = 47
90rule_id = "c61fee20-4d00-4b39-a6e6-acddcc4433e2"
91setup = "Cognito Identity Pool data events must be enabled in CloudTrail to capture GetCredentialsForIdentity, GetId, GetOpenIdToken, GetOpenIdTokenForDeveloperIdentity, and UnlinkIdentity. Add an advanced event selector for eventCategory Data and resources.type AWS::Cognito::IdentityPool to the trail."
92severity = "medium"
93tags = [
94 "Domain: Cloud",
95 "Data Source: AWS",
96 "Data Source: Amazon Web Services",
97 "Data Source: AWS Cognito",
98 "Use Case: Asset Visibility",
99 "Resources: Investigation Guide",
100 "Tactic: Credential Access",
101 "Tactic: Initial Access",
102]
103timestamp_override = "event.ingested"
104type = "new_terms"
105
106query = '''
107data_stream.dataset: "aws.cloudtrail"
108 and event.provider: "cognito-identity.amazonaws.com"
109 and event.action: "GetCredentialsForIdentity"
110 and event.outcome: "success"
111 and aws.cloudtrail.user_identity.type: "Unknown"
112'''
113
114
115[[rule.threat]]
116framework = "MITRE ATT&CK"
117[[rule.threat.technique]]
118id = "T1552"
119name = "Unsecured Credentials"
120reference = "https://attack.mitre.org/techniques/T1552/"
121
122
123[rule.threat.tactic]
124id = "TA0006"
125name = "Credential Access"
126reference = "https://attack.mitre.org/tactics/TA0006/"
127[[rule.threat]]
128framework = "MITRE ATT&CK"
129[[rule.threat.technique]]
130id = "T1078"
131name = "Valid Accounts"
132reference = "https://attack.mitre.org/techniques/T1078/"
133[[rule.threat.technique.subtechnique]]
134id = "T1078.004"
135name = "Cloud Accounts"
136reference = "https://attack.mitre.org/techniques/T1078/004/"
137
138
139
140[rule.threat.tactic]
141id = "TA0001"
142name = "Initial Access"
143reference = "https://attack.mitre.org/tactics/TA0001/"
144
145[rule.investigation_fields]
146field_names = [
147 "@timestamp",
148 "user_agent.original",
149 "source.ip",
150 "aws.cloudtrail.resources.arn",
151 "aws.cloudtrail.resources.type",
152 "aws.cloudtrail.user_identity.type",
153 "aws.cloudtrail.request_parameters",
154 "event.action",
155 "event.outcome",
156 "cloud.account.id",
157 "cloud.region",
158]
159
160[rule.new_terms]
161field = "new_terms_fields"
162value = ["aws.cloudtrail.resources.arn"]
163[[rule.new_terms.history_window_start]]
164field = "history_window_start"
165value = "now-7d"
Triage and analysis
Investigating AWS Cognito Unauthenticated Identity Pool Credentials Issued
Amazon Cognito Identity Pools can be configured with AllowUnauthenticatedIdentities, letting a caller obtain a
guest identity via GetId and then temporary AWS credentials via GetCredentialsForIdentity, with no login token or
authentication of any kind. This is by design for use cases like anonymous app analytics, but if the pool's
unauthenticated IAM role is overpermissioned, anyone who discovers the identity pool ID gets a free, unauthenticated
path to real AWS credentials.
This rule fires the first time a given identity pool is observed issuing credentials to an unauthenticated caller
(aws.cloudtrail.user_identity.type: "Unknown").
Possible investigation steps
- Identify the pool: review
aws.cloudtrail.resources.arnto determine which identity pool issued the credentials, andaws.cloudtrail.request_parameters.identityIdfor the specific guest identity. - Confirm this is intentional guest access: check whether the application this pool belongs to is designed for anonymous/unauthenticated use (for example, a public mobile app or website with anonymous analytics).
- Review the unauthenticated role's permissions: run
aws cognito-identity get-identity-pool-roles --identity-pool-id <pool id>and inspect the attached policy for the unauthenticated role. Broad permissions (data store read/write,iam:*, cross-service access) on a role reachable without authentication is a critical misconfiguration regardless of whether this specific call was malicious. - Review source context: check
source.ip,user_agent.original, andsource.geofor the calling identity. A source unrelated to the application's expected client base (for example, a generic AWS SDK/CLI user agent instead of a mobile/browser client) is a stronger indicator of discovery/abuse rather than normal app traffic. - Look for follow-on activity: search for subsequent API calls made using credentials tied to the same
identityIdor the unauthenticated role's ARN, to determine what the caller actually did with the credentials. - Look for pool enumeration: check for
ListIdentityPoolsor repeatedGetId/GetCredentialsForIdentitycalls against multiple different identity pools from the same source in a short window, which suggests systematic discovery rather than a single legitimate app session.
False positive analysis
- Many applications intentionally use unauthenticated Identity Pool access for anonymous analytics or public content delivery. This rule fires once per identity pool the first time this pattern is observed; if confirmed as intentional and properly scoped (minimal unauthenticated role permissions), no further action is needed for that pool.
Response and remediation
- If the unauthenticated role is overpermissioned, scope it down immediately to the minimum required for legitimate
anonymous use, or disable
AllowUnauthenticatedIdentitiesentirely if guest access is not required. - If credentials were abused, review all activity performed under the unauthenticated role's ARN during the credential's validity window and revoke/rotate as appropriate (temporary credentials cannot be revoked directly, but the role's trust policy or permissions can be tightened immediately).
- Treat any identity pool ID found in client-side code (mobile app binaries, web JavaScript) as public information, and ensure the unauthenticated role attached to it is scoped accordingly.
References
Related rules
- AWS IAM User Console Login from Multiple Geolocations
- AWS IAM Long-Term Access Key First Seen from Source IP
- AWS IAM User Console Login Without MFA
- AWS Bedrock AgentCore Execution Role Used Outside Its Runtime
- AWS EC2 CreateKeyPair by New Principal from Non-Cloud AS Organization