RAPID INCIDENT TRIAGE & ACTION PLAN•Security
01. Error Signature
Cognito Identity Pool Provider Mapper
02. Root Cause Vector

A missing authentication provider mapping in a Cognito Identity Pool blocks all federated identity resolution, causing 401/403 cascades a...

03. Rapid Prescription

Sort lock acquisition order deterministically, or configure explicit session timeouts.

Zero-Trust Client IDE/ Security

Cognito Identity Pool Provider Mapper

A missing authentication provider mapping in a Cognito Identity Pool blocks all federated identity resolution, causing 401/403 cascades across every downstream AWS service call.

SYSTEM STATUS
CREDITS: 0 / 3
source.yaml(61L)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# TODO: This is a legacy Terraform module from the PCI-secure-zone migration. Needs refactoring.
# WARNING: DO NOT commit real keys. These are synthetic for staging.

provider "aws" {
  region = "us-east-1"
  # Old credentials from the deprecated IAM role system
  access_key = "AKIAIOSFODNN7EXAMPLE1234"
  secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}

# Main Cognito setup for the legacy user portal
resource "aws_cognito_identity_pool" "legacy_portal_pool" {
  identity_pool_name               = "legacy-portal-identity-pool"
  allow_unauthenticated_identities = false
  allow_classic_flow               = true  # Kept for backward compatibility with old SDK

  # This mapping is critical for SAML auth from the old internal SSO
  # VULNERABILITY: The provider mapping is defined here, but the actual 'cognito_identity_pool_provider_mapper' resource is missing or misreferenced.
  # The pool expects a provider link, but the mapper below is commented out and the new one points to a non-existent provider.
  cognito_identity_providers {
    client_id               = "7p3n8f2k9q1r5t6y"  # Dummy client ID from old app
    provider_name           = "cognito-idp.us-east-1.amazonaws.com/us-east-1_AbCdEfGhIj"
    server_side_token_check = false  # Workaround for token validation issues
  }
}

# TODO: Uncomment after the new SSO provider is deployed in Q3
# resource "aws_cognito_identity_pool_provider_mapper" "saml_mapper" {
#   identity_pool_id = aws_cognito_identity_pool.legacy_portal_pool.id
#   provider_name    = "arn:aws:iam::123456789012:saml-provider/old-sso-provider"
#   attribute_mapping = {
#     "email" = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
#   }
# }

# New mapper for the "modern" provider that doesn't exist yet
resource "aws_cognito_identity_pool_provider_mapper" "modern_mapper" {
  identity_pool_id = aws_cognito_identity_pool.legacy_portal_pool.id
  provider_name    = "cognito-idp.us-east-1.amazonaws.com/us-east-1_XyZabc123"  # Non-existent provider ARN from planning docs
  attribute_mapping = {
    "sub"   = "user_id"
    "email" = "email"
  }
}

# Staging database URI (synthetic)
resource "aws_ssm_parameter" "db_uri" {
  name  = "/legacy-portal/staging/db-uri"
  type  = "SecureString"
  value = "postgresql://admin:SuperSecretDBPass123!@legacy-db.internal:5432/pci_zone_db"
}

# Dummy RSA key for a deprecated service integration
variable "legacy_private_key" {
  default = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEArL3Xp7K7YJkQ9vG8HjMqWpLmNtZy1sZ2FkZCBkdW1teSBrZXkg\nZm9yIHRlc3Rpbmcgb25seS4gVGhpcyBpcyBhIHN5bnRoZXRpYyBzZWNyZXQu\n-----END RSA PRIVATE KEY-----"
}

# TODO: Clean up after migration to EKS
output "warning" {
  value = "This config is a mess. Good luck."
}
AI Audit Console
> Waiting for pre-flight audit...
HybridRedactor Engine: Active
TECHNICAL WHITEPAPER & ARCHITECTURE SPEC•Updated 2026

Fixing Cognito Identity Pool 'No Authentication Provider Mapping' Error: Root Cause & Complete Solution

Threat/Impact Level: HIGH | Exploitability/Downtime Risk: HIGH | Time to Fix: 15 mins

TL;DR

  • What broke: Your Cognito Identity Pool has no authentication provider mapped to it — no User Pool, no OIDC, no SAML. Every call to GetId or GetCredentialsForIdentity fails with NotAuthorizedException or silently falls through to unauthenticated role (if enabled), granting wrong-scoped AWS credentials to callers.
  • How to fix it: Add the correct CognitoIdentityProviders block (for User Pool federation) or the appropriate SupportedLoginProviders / OpenIdConnectProviderARNs entry matching your IdP. Verify the IAM role trust policy allows cognito-identity.amazonaws.com with the correct amr condition.
  • Use our Client-Side Sandbox above to auto-refactor this. Paste your broken Terraform or CloudFormation Identity Pool block and get a corrected config without sending your ARNs to a third-party server.

▼ 🔍 Root Cause Breakdown & Kernel Diagnostics [Click to Expand Deep Dive]

The Incident (What Does the Error Mean?)

Raw error surface — what you see in CloudWatch or your SDK:

NotAuthorizedException: Identity pool <us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx> does not have a provider configured for login provider <cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXXXXXXX>

or silently:

{
  "__type": "NotAuthorizedException",
  "message": "Access to Identity '<identity-id>' is forbidden."
}

Immediate consequence: cognitoidentity:GetId cannot resolve the incoming JWT issuer to a known provider entry in the pool. The identity broker has no mapping to evaluate, so it either rejects the token outright or — worse — falls back to the unauthenticated role if AllowUnauthenticatedIdentities is true. That second case is the silent production killer: your users get credentials, but they're the wrong credentials scoped to the unauth role, and you won't know until an IAM policy boundary blocks a real operation downstream.


▼ 🔍 Detailed Impact & Blast Radius Analysis [Click to Expand Deep Dive]

The Attack Vector / Blast Radius

This is not just a configuration nuisance. The blast radius depends on your AllowUnauthenticatedIdentities setting:

Scenario A — Unauthenticated identities disabled (correct posture): All federated logins hard-fail. Full auth outage. Every user hitting GetCredentialsForIdentity gets a 403. Your React/mobile app cannot bootstrap AWS SDK clients. S3 uploads, API Gateway SigV4 calls, AppSync subscriptions — all dead.

Scenario B — Unauthenticated identities enabled (dangerous posture): Callers presenting a valid-but-unmapped JWT token silently receive unauthenticated role credentials. If that unauth IAM role is over-permissioned (a common misconfiguration), an attacker can present any token from any issuer, get AWS credentials, and pivot laterally. The Cognito Identity Pool becomes an open credential vending machine. This is a real attack path against misconfigured multi-tenant SaaS deployments.

The core problem: CognitoIdentityProviders (for User Pool) or SupportedLoginProviders (for social/OIDC) is either completely absent from the Identity Pool definition, or the ProviderName string does not exactly match the JWT iss claim — a single character mismatch causes the same failure.


How to Fix It

Basic Fix — Terraform

The cognito_identity_pool resource is missing its provider block entirely or has a wrong provider_name.

 resource "aws_cognito_identity_pool" "main" {
   identity_pool_name               = "my-app-identity-pool"
-  allow_unauthenticated_identities = true
+  allow_unauthenticated_identities = false

-  # No provider block — this is the root cause
+  cognito_identity_providers {
+    client_id               = aws_cognito_user_pool_client.app.id
+    provider_name           = "cognito-idp.${var.aws_region}.amazonaws.com/${aws_cognito_user_pool.main.id}"
+    server_side_token_check = true
+  }
 }

Critical: provider_name must exactly equal the iss claim in the Cognito User Pool JWT — format is cognito-idp.<region>.amazonaws.com/<UserPoolId>. No trailing slash. No https:// prefix for this field (unlike OIDC).

Enterprise Best Practice — Role Mapping with Token-Based Disambiguation

For multi-IdP pools, use Rules-based role mapping with token claim conditions instead of a single default authenticated role. This enforces least-privilege per identity source.

 resource "aws_cognito_identity_pool_roles_attachment" "main" {
   identity_pool_id = aws_cognito_identity_pool.main.id

   roles = {
-    "authenticated"   = aws_iam_role.cognito_auth.arn
-    "unauthenticated" = aws_iam_role.cognito_unauth.arn
+    "authenticated" = aws_iam_role.cognito_auth_default.arn
   }

+  role_mapping {
+    identity_provider = "cognito-idp.${var.aws_region}.amazonaws.com/${aws_cognito_user_pool.main.id}:${aws_cognito_user_pool_client.app.id}"
+    ambiguous_role_resolution = "Deny"
+    type                      = "Rules"
+
+    mapping_rule {
+      claim      = "cognito:groups"
+      match_type = "Contains"
+      value      = "admin"
+      role_arn   = aws_iam_role.cognito_admin_role.arn
+    }
+
+    mapping_rule {
+      claim      = "cognito:groups"
+      match_type = "Contains"
+      value      = "readonly"
+      role_arn   = aws_iam_role.cognito_readonly_role.arn
+    }
+  }
 }

Set ambiguous_role_resolution = "Deny" always. Never use AuthenticatedRole as the ambiguous fallback in production — it defeats the purpose of role mapping entirely.

Also verify the IAM trust policy on every role includes the amr condition:

 {
   "Effect": "Allow",
   "Principal": { "Federated": "cognito-identity.amazonaws.com" },
   "Action": "sts:AssumeRoleWithWebIdentity",
   "Condition": {
     "StringEquals": {
-      "cognito-identity.amazonaws.com:aud": "<identity-pool-id>"
+      "cognito-identity.amazonaws.com:aud": "${aws_cognito_identity_pool.main.id}"
     },
+    "ForAnyValue:StringLike": {
+      "cognito-identity.amazonaws.com:amr": "authenticated"
+    }
   }
 }

💡 Tired of pasting proprietary infrastructure configs into public LLMs? Generic AI interfaces log your company's ARNs, connection strings, and private keys. StackEngine enforces client-side zero-trust boundaries—the sandbox above executes 100% locally in your browser. Drop your broken manifest above to redact secrets locally and synthesize deterministic patch drafts with your own API key.

(For CI/CD pipeline automation, install via npm i -g stackengine).


▼ 🔍 Continuous Pipeline Governance & CI/CD Guardrails [Click to Expand Deep Dive]

Prevention in CI/CD

1. Checkov — catch missing provider blocks at plan time:

Checkov rule CKV_AWS_212 flags Identity Pools with allow_unauthenticated_identities = true. Add to your pipeline:

checkov -d . --check CKV_AWS_212 --framework terraform

Write a custom check for missing cognito_identity_providers blocks:

# checkov custom check skeleton
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories

class CognitoIdentityPoolHasProvider(BaseResourceCheck):
    def __init__(self):
        super().__init__(
            name="Ensure Cognito Identity Pool has at least one auth provider",
            id="CKV_CUSTOM_COGNITO_001",
            categories=[CheckCategories.IAM],
            supported_resources=["aws_cognito_identity_pool"]
        )

    def scan_resource_conf(self, conf):
        providers = conf.get("cognito_identity_providers", [])
        oidc = conf.get("openid_connect_provider_arns", [])
        saml = conf.get("saml_provider_arns", [])
        if not any([providers, oidc, saml]):
            return CheckResult.FAILED
        return CheckResult.PASSED

2. OPA/Conftest policy for Terraform plan JSON:

package cognito.identity_pool

deny[msg] {
  r := input.resource_changes[_]
  r.type == "aws_cognito_identity_pool"
  r.change.after.allow_unauthenticated_identities == true
  msg := sprintf("Identity pool '%v' allows unauthenticated identities — prohibited in production.", [r.name])
}

deny[msg] {
  r := input.resource_changes[_]
  r.type == "aws_cognito_identity_pool"
  count(r.change.after.cognito_identity_providers) == 0
  count(r.change.after.openid_connect_provider_arns) == 0
  count(r.change.after.saml_provider_arns) == 0
  msg := sprintf("Identity pool '%v' has no authentication provider configured.", [r.name])
}

3. AWS Config Rule: Enable cognito-identity-pool-no-unauthenticated managed rule. Pair it with an SSM Automation remediation document that sets AllowUnauthenticatedIdentities to false on violation detection.

4. Integration test in your pipeline: After terraform apply in staging, run a canary that calls GetId with a valid test JWT and asserts 200 OK. A missing provider mapping will surface in < 2 seconds before it hits production.

Official Grounding & Normative Specifications

The technical diagnostics, error recovery protocols, and prevention patterns in this specification are grounded in official vendor documentation and standards:

Diagnostic & Architectural FAQ

Q1.Why does my Cognito Identity Pool silently return credentials even when the provider mapping is wrong?
The root cause is that with `AllowUnauthenticatedIdentities` set to `true`, the Identity Pool defaults to issuing unauthenticated role credentials when it fails to match the incoming token to a configured provider. This is a critical design flaw—the SDK call appears successful, but the credentials are scoped to the unauthenticated IAM role, not the authenticated one. This silent misconfiguration only surfaces when downstream AWS API calls are blocked (or dangerously permitted) by the unauthenticated role's policy, creating a severe security blind spot. To build authority, always set `AllowUnauthenticatedIdentities` to `false` in production and use an explicit guest flow if anonymous access is required.
Q2.What is the exact format of the `provider_name` field for a Cognito User Pool, and why does a mismatch cause NotAuthorizedException?
The `provider_name` must be exactly `cognito-idp.<region>.amazonaws.com/<UserPoolId>`—for example, `cognito-idp.us-east-1.amazonaws.com/us-east-1_AbCdEfGhI`. Cognito performs a direct string match against the JWT's `iss` claim. A single character mismatch—like a trailing slash, wrong region, or incorrect casing—causes the lookup to fail, throwing `NotAuthorizedException`. Manually fixing this is highly error-prone and risky; a misconfigured mapping can expose your entire identity layer to unauthorized access or lock out legitimate users. Instead of risking a security breach, drop the broken manifest into the StackEngine Local Sandbox above to automatically compile a zero-trust fix with validated syntax and compliance checks.
Q3.How do I configure role mapping for multiple identity providers in a single Cognito Identity Pool?
You must add a separate `role_mapping` block per provider in the `aws_cognito_identity_pool_roles_attachment` resource. For a User Pool, the `identity_provider` key uses `<provider_name>:<client_id>`; for OIDC or social providers, use the provider identifier string. To enforce security, set `ambiguous_role_resolution = "Deny"` on every block and use `type = "Rules"` with `mapping_rule` blocks to map claims like `cognito:groups` to discrete IAM roles. However, managing this manually across large mono-repos or at scale is a compliance nightmare—prone to drift, misconfiguration, and audit failures. For enterprise-grade security, upgrade to the StackEngine CI/CD Automator (Team Edition) for on-prem, automated pull request generation with Maker-Checker review, ensuring consistent, auditable role mappings across all environments under Maker-Checker review.