External Identity Provider (Federation)
External Identity Provider (Federation)
Section titled “External Identity Provider (Federation)”This guide covers how to configure an external SAML or OIDC identity provider to federate authentication through Amazon Cognito for the GenAI IDP solution. Federated users sign in through their organization’s identity provider and are automatically mapped to Cognito groups (Admin, Author, Reviewer, Viewer) based on group claims from the IdP.
Overview
Section titled “Overview”The GenAI IDP solution supports optional federation with external identity providers including:
- PingOne (SAML or OIDC)
- Okta (SAML or OIDC)
- Microsoft Entra ID (Azure AD) (SAML or OIDC)
When federation is enabled:
- Users see a “Sign in with [IdP Name]” button on the Cognito hosted UI
- Clicking it redirects to the external IdP for authentication
- After successful authentication, the IdP sends group claims back to Cognito
- A post-authentication Lambda automatically maps IdP groups to Cognito groups
- The user is redirected to the GenAI IDP web UI with appropriate permissions
Native Cognito username/password authentication remains available alongside federation.
SAML vs OIDC — Which to Choose?
Section titled “SAML vs OIDC — Which to Choose?”| Consideration | SAML | OIDC |
|---|---|---|
| Protocol maturity | Older, widely supported in enterprise | Modern, lightweight |
| Setup complexity | Slightly more involved (metadata XML, certificates) | Simpler (client ID/secret + issuer URL) |
| Group claims | Sent as SAML attributes in assertion | Sent as claims in ID token |
| Token format | XML-based assertions | JSON Web Tokens (JWT) |
| Best for | Enterprise SSO with existing SAML infrastructure | Modern apps, simpler integration |
Both work equally well with this solution. Choose based on what your IdP team prefers or what’s already configured in your organization.
CloudFormation Parameters
Section titled “CloudFormation Parameters”| Parameter | Required | Description |
|---|---|---|
ExternalIdPType | Yes | SAML or OIDC (leave empty to disable) |
ExternalIdPName | Yes | Display name (e.g., PingOne, Okta) — alphanumeric and hyphens only |
ExternalIdPMetadataURL | SAML only | SAML metadata document URL from your IdP |
ExternalIdPOIDCIssuer | OIDC only | OIDC issuer URL (e.g., https://auth.pingone.com/<env-id>/as) |
ExternalIdPOIDCClientId | OIDC only | OIDC client ID from your IdP |
ExternalIdPOIDCClientSecretArn | OIDC only | ARN of a Secrets Manager secret containing the OIDC client secret (see Storing the OIDC Client Secret below) |
ExternalIdPGroupAttributeName | Optional | Attribute/claim name carrying group membership |
ExternalIdPAdminGroupName | Optional | IdP group name that maps to Cognito Admin role |
ExternalIdPAuthorGroupName | Optional | IdP group name that maps to Cognito Author role |
ExternalIdPReviewerGroupName | Optional | IdP group name that maps to Cognito Reviewer role |
ExternalIdPViewerGroupName | Optional | IdP group name that maps to Cognito Viewer role |
ExternalIdPAutoLogin | Optional | true to auto-redirect to IdP, false (default) to show login page |
Storing the OIDC Client Secret
Section titled “Storing the OIDC Client Secret”For OIDC federation, the client secret must be stored in AWS Secrets Manager before deploying the stack. This ensures the secret never passes through CloudFormation parameters (which are visible via the describe-stacks API).
Create the secret:
aws secretsmanager create-secret \ --name "my-idp-oidc-client-secret" \ --description "OIDC client secret for GenAI IDP federation" \ --secret-string "YOUR_CLIENT_SECRET_HERE" \ --region us-east-1Note the ARN from the output — you’ll pass it as the ExternalIdPOIDCClientSecretArn parameter during deployment.
To rotate the secret later:
aws secretsmanager update-secret \ --secret-id "my-idp-oidc-client-secret" \ --secret-string "NEW_CLIENT_SECRET_HERE"Then redeploy the stack to pick up the new value.
Prerequisites (All Providers)
Section titled “Prerequisites (All Providers)”Before configuring any external IdP, you need:
- A deployed GenAI IDP stack (deploy first with Cognito-only, then update with federation parameters)
- From the stack outputs, note:
- User Pool ID — e.g.,
us-east-1_aBcDeFgHi - Cognito Domain — e.g.,
idp-1234567890.auth.us-east-1.amazoncognito.com
- User Pool ID — e.g.,
- Administrator access to your identity provider
The Cognito values you’ll need for IdP configuration:
- SAML ACS URL:
https://<cognito-domain>/saml2/idpresponse - SAML Entity ID:
urn:amazon:cognito:sp:<user-pool-id> - OIDC Redirect URI:
https://<cognito-domain>/oauth2/idpresponse
PingOne
Section titled “PingOne”Option A: PingOne SAML Setup
Section titled “Option A: PingOne SAML Setup”Step 1: Create a SAML Application in PingOne
Section titled “Step 1: Create a SAML Application in PingOne”- Log in to the PingOne Admin Console
- Navigate to Connections → Applications
- Click + Add Application
- Select Web App, then choose SAML
- Enter an application name (e.g.,
GenAI IDP) - Click Configure
Step 2: Configure SAML Settings
Section titled “Step 2: Configure SAML Settings”In the SAML configuration:
- ACS URL:
https://<cognito-domain>/saml2/idpresponse
- Entity ID:
urn:amazon:cognito:sp:<user-pool-id>
- Binding Type: Select
HTTP POST - Signing: Enable response signing
- Click Save
Step 3: Configure Attribute Mappings
Section titled “Step 3: Configure Attribute Mappings”In the application’s Attribute Mappings section, add:
| PingOne Attribute | SAML Attribute |
|---|---|
Email Address | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress |
Group Names | http://schemas.xmlsoap.org/claims/Group |
The Group Names attribute sends the user’s PingOne group memberships in the SAML assertion.
Step 4: Create Groups and Assign Users
Section titled “Step 4: Create Groups and Assign Users”- Navigate to Identities → Groups
- Create groups that will map to GenAI IDP roles:
IDP-AdminsIDP-AuthorsIDP-ReviewersIDP-Viewers
- Assign users to the appropriate groups
- Ensure the application has access to these groups (check Policies if needed)
Step 5: Enable and Get Metadata URL
Section titled “Step 5: Enable and Get Metadata URL”- Toggle the application to Enabled
- Go to Configuration → Connection Details
- Copy the SAML Metadata URL — it looks like:
https://auth.pingone.com/<environment-id>/saml20/metadata/<application-id>
Step 6: Deploy with SAML Parameters
Section titled “Step 6: Deploy with SAML Parameters”idp-cli deploy \ --stack-name my-idp-stack \ --from-code . \ --parameters "\ExternalIdPType=SAML,\ExternalIdPName=PingOne,\ExternalIdPMetadataURL=https://auth.pingone.com/<env-id>/saml20/metadata/<app-id>,\ExternalIdPGroupAttributeName=http://schemas.xmlsoap.org/claims/Group,\ExternalIdPAdminGroupName=IDP-Admins,\ExternalIdPAuthorGroupName=IDP-Authors,\ExternalIdPReviewerGroupName=IDP-Reviewers,\ExternalIdPViewerGroupName=IDP-Viewers" \ --waitOption B: PingOne OIDC Setup
Section titled “Option B: PingOne OIDC Setup”Step 1: Create an OIDC Application in PingOne
Section titled “Step 1: Create an OIDC Application in PingOne”- Log in to the PingOne Admin Console
- Navigate to Connections → Applications
- Click + Add Application
- Select Web App, then choose OIDC
- Enter an application name (e.g.,
GenAI IDP) - Click Configure
Step 2: Configure OIDC Settings
Section titled “Step 2: Configure OIDC Settings”- Grant Type: Select
Authorization Code - Redirect URI:
https://<cognito-domain>/oauth2/idpresponse
- Token Endpoint Authentication Method:
Client Secret PostorClient Secret Basic - Scopes: Enable
openid,email,profile - Click Save
Step 3: Add a Custom Groups Scope (if needed)
Section titled “Step 3: Add a Custom Groups Scope (if needed)”PingOne may not include group membership in tokens by default. To add it:
- Go to the application’s Resources tab
- Under Scopes, add a custom scope or enable the
groupsscope - Alternatively, configure a custom claim:
- Navigate to Resources → Custom Attributes or Token Customization
- Add a claim named
groupsthat maps to the user’s group memberships
Step 4: Create Groups and Assign Users
Section titled “Step 4: Create Groups and Assign Users”Same as SAML Step 4 above — create IDP-Admins, IDP-Authors, IDP-Reviewers, IDP-Viewers groups and assign users.
Step 5: Enable and Get OIDC Details
Section titled “Step 5: Enable and Get OIDC Details”- Toggle the application to Enabled
- From the application’s Configuration tab, note:
- Client ID
- Client Secret
- Issuer URL — typically:
https://auth.pingone.com/<environment-id>/as
https://auth.pingone.com/<environment-id>/as/.well-known/openid-configuration
Step 6: Deploy with OIDC Parameters
Section titled “Step 6: Deploy with OIDC Parameters”idp-cli deploy \ --stack-name my-idp-stack \ --from-code . \ --parameters "\ExternalIdPType=OIDC,\ExternalIdPName=PingOne,\ExternalIdPOIDCIssuer=https://auth.pingone.com/<env-id>/as,\ExternalIdPOIDCClientId=<your-client-id>,\ExternalIdPOIDCClientSecretArn=arn:aws:secretsmanager:us-east-1:123456789012:secret:my-pingone-oidc-secret-AbCdEf,\ExternalIdPGroupAttributeName=groups,\ExternalIdPAdminGroupName=IDP-Admins,\ExternalIdPAuthorGroupName=IDP-Authors,\ExternalIdPReviewerGroupName=IDP-Reviewers,\ExternalIdPViewerGroupName=IDP-Viewers" \ --waitOption A: Okta SAML Setup
Section titled “Option A: Okta SAML Setup”Step 1: Create a SAML Application in Okta
Section titled “Step 1: Create a SAML Application in Okta”- Log in to the Okta Admin Console
- Navigate to Applications → Applications
- Click Create App Integration
- Select SAML 2.0, click Next
- Enter an app name (e.g.,
GenAI IDP), click Next
Step 2: Configure SAML Settings
Section titled “Step 2: Configure SAML Settings”- Single sign-on URL:
https://<cognito-domain>/saml2/idpresponse
- Audience URI (SP Entity ID):
urn:amazon:cognito:sp:<user-pool-id>
- Name ID format:
EmailAddress - Application username:
Email
Step 3: Configure Attribute Statements
Section titled “Step 3: Configure Attribute Statements”Add the following attribute statements:
| Name | Value |
|---|---|
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress | user.email |
Add a Group Attribute Statement:
| Name | Filter |
|---|---|
http://schemas.xmlsoap.org/claims/Group | Matches regex: IDP-.* (or adjust to match your group naming) |
Step 4: Create Groups and Assign Users
Section titled “Step 4: Create Groups and Assign Users”- Navigate to Directory → Groups
- Create groups:
IDP-Admins,IDP-Authors,IDP-Reviewers,IDP-Viewers - Assign users to groups
- Go back to the application → Assignments tab → assign the groups to the app
Step 5: Get Metadata URL
Section titled “Step 5: Get Metadata URL”- Go to the application’s Sign On tab
- Under SAML Signing Certificates, find the Metadata URL — or use:
https://<your-okta-domain>/app/<app-id>/sso/saml/metadata
Step 6: Deploy with SAML Parameters
Section titled “Step 6: Deploy with SAML Parameters”idp-cli deploy \ --stack-name my-idp-stack \ --from-code . \ --parameters "\ExternalIdPType=SAML,\ExternalIdPName=Okta,\ExternalIdPMetadataURL=https://<okta-domain>/app/<app-id>/sso/saml/metadata,\ExternalIdPGroupAttributeName=http://schemas.xmlsoap.org/claims/Group,\ExternalIdPAdminGroupName=IDP-Admins,\ExternalIdPAuthorGroupName=IDP-Authors,\ExternalIdPReviewerGroupName=IDP-Reviewers,\ExternalIdPViewerGroupName=IDP-Viewers" \ --waitOption B: Okta OIDC Setup
Section titled “Option B: Okta OIDC Setup”Step 1: Create an OIDC Application in Okta
Section titled “Step 1: Create an OIDC Application in Okta”- Log in to the Okta Admin Console
- Navigate to Applications → Applications
- Click Create App Integration
- Select OIDC - OpenID Connect, then Web Application, click Next
- Enter an app name (e.g.,
GenAI IDP)
Step 2: Configure OIDC Settings
Section titled “Step 2: Configure OIDC Settings”- Grant type:
Authorization Code - Sign-in redirect URI:
https://<cognito-domain>/oauth2/idpresponse
- Sign-out redirect URI: Your web UI URL
- Assignments: Select the groups or users who should have access
Step 3: Configure Groups Claim
Section titled “Step 3: Configure Groups Claim”- Navigate to Security → API → Authorization Servers
- Select the
defaultauthorization server (or your custom one) - Go to the Claims tab → Add Claim:
- Name:
groups - Include in token type:
ID Token(Always) - Value type:
Groups - Filter: Matches regex
IDP-.*(or adjust to your naming)
- Name:
Step 4: Get OIDC Details
Section titled “Step 4: Get OIDC Details”From the application’s General tab:
- Client ID
- Client Secret
- Issuer URL:
https://<your-okta-domain>/oauth2/default
Step 5: Deploy with OIDC Parameters
Section titled “Step 5: Deploy with OIDC Parameters”idp-cli deploy \ --stack-name my-idp-stack \ --from-code . \ --parameters "\ExternalIdPType=OIDC,\ExternalIdPName=Okta,\ExternalIdPOIDCIssuer=https://<okta-domain>/oauth2/default,\ExternalIdPOIDCClientId=<your-client-id>,\ExternalIdPOIDCClientSecretArn=arn:aws:secretsmanager:us-east-1:123456789012:secret:my-okta-oidc-secret-AbCdEf,\ExternalIdPGroupAttributeName=groups,\ExternalIdPAdminGroupName=IDP-Admins,\ExternalIdPAuthorGroupName=IDP-Authors,\ExternalIdPReviewerGroupName=IDP-Reviewers,\ExternalIdPViewerGroupName=IDP-Viewers" \ --waitMicrosoft Entra ID (Azure AD)
Section titled “Microsoft Entra ID (Azure AD)”Option A: Entra ID SAML Setup
Section titled “Option A: Entra ID SAML Setup”Step 1: Create an Enterprise Application
Section titled “Step 1: Create an Enterprise Application”- Log in to the Azure Portal
- Navigate to Microsoft Entra ID → Enterprise applications
- Click New application → Create your own application
- Enter a name (e.g.,
GenAI IDP), select Integrate any other application, click Create
Step 2: Configure SAML SSO
Section titled “Step 2: Configure SAML SSO”- Go to Single sign-on → select SAML
- Edit Basic SAML Configuration:
- Identifier (Entity ID):
urn:amazon:cognito:sp:<user-pool-id>
- Reply URL (ACS URL):
https://<cognito-domain>/saml2/idpresponse
- Identifier (Entity ID):
- Click Save
Step 3: Configure Attributes and Claims
Section titled “Step 3: Configure Attributes and Claims”- Click Edit on Attributes & Claims
- Verify the email claim exists:
- Claim name:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress - Source attribute:
user.mail
- Claim name:
- Add a group claim:
- Click Add a group claim
- Select Security groups or Groups assigned to the application
- Under Advanced options, check Customize the name of the group claim
- Name:
http://schemas.xmlsoap.org/claims/Group - Source:
Group ID(orDisplay Nameif you prefer readable names)
Note: If using Group IDs, your
ExternalIdPAdminGroupNameetc. parameters must use the Entra group object IDs (GUIDs) rather than display names.
Step 4: Create Groups and Assign Users
Section titled “Step 4: Create Groups and Assign Users”- Navigate to Microsoft Entra ID → Groups
- Create groups:
IDP-Admins,IDP-Authors,IDP-Reviewers,IDP-Viewers - Add users to groups
- Go back to the Enterprise Application → Users and groups → assign the groups
Step 5: Get Metadata URL
Section titled “Step 5: Get Metadata URL”- Go to Single sign-on → SAML Certificates section
- Copy the App Federation Metadata Url — it looks like:
https://login.microsoftonline.com/<tenant-id>/federationmetadata/2007-06/federationmetadata.xml?appid=<app-id>
Step 6: Deploy with SAML Parameters
Section titled “Step 6: Deploy with SAML Parameters”idp-cli deploy \ --stack-name my-idp-stack \ --from-code . \ --parameters "\ExternalIdPType=SAML,\ExternalIdPName=EntraID,\ExternalIdPMetadataURL=https://login.microsoftonline.com/<tenant-id>/federationmetadata/2007-06/federationmetadata.xml?appid=<app-id>,\ExternalIdPGroupAttributeName=http://schemas.xmlsoap.org/claims/Group,\ExternalIdPAdminGroupName=IDP-Admins,\ExternalIdPAuthorGroupName=IDP-Authors,\ExternalIdPReviewerGroupName=IDP-Reviewers,\ExternalIdPViewerGroupName=IDP-Viewers" \ --waitOption B: Entra ID OIDC Setup
Section titled “Option B: Entra ID OIDC Setup”Step 1: Register an Application
Section titled “Step 1: Register an Application”- Log in to the Azure Portal
- Navigate to Microsoft Entra ID → App registrations
- Click New registration
- Enter a name (e.g.,
GenAI IDP) - Redirect URI: Select
Weband enter:https://<cognito-domain>/oauth2/idpresponse - Click Register
Step 2: Configure Client Secret
Section titled “Step 2: Configure Client Secret”- Go to Certificates & secrets → New client secret
- Add a description and expiration
- Copy the Value (this is your client secret — it’s only shown once)
Step 3: Configure Token Claims
Section titled “Step 3: Configure Token Claims”- Go to Token configuration → Add groups claim
- Select Security groups (or Groups assigned to the application)
- For ID token, select Group ID
- Click Add
Step 4: Configure API Permissions
Section titled “Step 4: Configure API Permissions”- Go to API permissions
- Ensure these are granted:
openidemailprofile
Step 5: Get OIDC Details
Section titled “Step 5: Get OIDC Details”- Client ID: From the app’s Overview page
- Client Secret: From Step 2
- Issuer URL:
https://login.microsoftonline.com/<tenant-id>/v2.0
Step 6: Deploy with OIDC Parameters
Section titled “Step 6: Deploy with OIDC Parameters”idp-cli deploy \ --stack-name my-idp-stack \ --from-code . \ --parameters "\ExternalIdPType=OIDC,\ExternalIdPName=EntraID,\ExternalIdPOIDCIssuer=https://login.microsoftonline.com/<tenant-id>/v2.0,\ExternalIdPOIDCClientId=<your-client-id>,\ExternalIdPOIDCClientSecretArn=arn:aws:secretsmanager:us-east-1:123456789012:secret:my-entraid-oidc-secret-AbCdEf,\ExternalIdPGroupAttributeName=groups,\ExternalIdPAdminGroupName=<admin-group-object-id>,\ExternalIdPAuthorGroupName=<author-group-object-id>,\ExternalIdPReviewerGroupName=<reviewer-group-object-id>,\ExternalIdPViewerGroupName=<viewer-group-object-id>" \ --waitNote: Entra ID OIDC sends group object IDs (GUIDs) by default, not display names. Use the group object IDs from the Azure Portal as your mapping values.
Verifying the Integration
Section titled “Verifying the Integration”After deploying with federation parameters:
- Navigate to the GenAI IDP web UI
- The Cognito hosted UI should show a button labeled with your IdP name (e.g., “PingOne”)
- Click it to be redirected to your IdP for authentication
- After signing in, you should be redirected back to the GenAI IDP web UI
- Verify your role matches your IdP group membership by checking the user profile
Removing Federation
Section titled “Removing Federation”To revert to Cognito-only authentication, update the stack and set ExternalIdPType back to empty:
idp-cli deploy \ --stack-name my-idp-stack \ --from-code . \ --parameters "ExternalIdPType=" \ --waitThis removes the external identity provider, the group mapping Lambda, and reverts the User Pool Client to Cognito-only. Existing Cognito-native users are unaffected.
Troubleshooting
Section titled “Troubleshooting”| Issue | Cause | Solution |
|---|---|---|
| ”Invalid saml_response” error | ACS URL or Entity ID mismatch | Verify they match exactly between your IdP and Cognito |
| User signs in but has no permissions | Group claim not mapped or group names don’t match | Check ExternalIdPGroupAttributeName matches the IdP attribute name, and group names are case-sensitive exact matches |
| Redirect loop after sign-in | Callback URL mismatch | Ensure the Cognito User Pool Client callback URL includes your web UI URL (with and without trailing slash) |
| “Invalid_grant” error (OIDC) | Client secret incorrect or expired | Regenerate the client secret in your IdP and update the stack parameter |
| Groups not appearing in token | IdP not configured to send groups | Check IdP group claim configuration (see provider-specific steps above) |
| “Application is not enabled” (PingOne) | PingOne app is disabled | Toggle the application to Enabled in PingOne admin console |
| ”Unsupported authentication method” (PingOne OIDC) | Token endpoint auth method mismatch | Set PingOne OIDC app to Client Secret Post |
| ”RedirectUri is not registered” | Callback URL trailing slash mismatch | Ensure both with and without trailing slash variants are registered |
| User disabled but can still sign in | IdP SSO session still active in browser | Revoke the user’s active sessions in the IdP admin console, or wait for the SSO session to expire |
| Sign out signs user back in (auto-login) | IdP SSO session persists after Cognito logout | Expected behavior with auto-login enabled — see Auto-Login Behavior below |
Auto-Login Behavior
Section titled “Auto-Login Behavior”When ExternalIdPAutoLogin is enabled:
- Users are automatically redirected to the external IdP when visiting the app
- Sign-out clears the Cognito session and redirects through Cognito’s logout endpoint
- If the IdP SSO session is still active, the user may be automatically signed back in on the next visit
- This is standard SSO behavior — the IdP controls session lifetime, not the app
- To fully sign out, users must also sign out of their IdP (e.g., PingOne, Okta, Entra ID)
- Organizations can control this by configuring SSO session timeouts in their IdP
- Set
ExternalIdPAutoLogintofalseif your organization requires explicit sign-in on each visit
Checking Lambda Logs
Section titled “Checking Lambda Logs”The ExternalIdPGroupMappingFunction logs every federated sign-in with group mapping details. Check CloudWatch Logs for the function to debug group mapping issues:
aws logs tail /aws/lambda/<stack-name>-ExternalIdPGroupMappingFunction-<id> --follow