Skip to content

AWS Cognito + Google SSO Migration Guide

Overview

This guide provides step-by-step instructions for migrating the architecture-docs site from AWS Amplify basic authentication to Amazon Cognito with Google as the identity provider (IdP).

Repository: architecture-docs Current Deployment: AWS Amplify - https://eng.adaction.com Tech Stack: mkdocs, Node.js 18+, Python Credentials Location: 1Password "Engineering" vault

Table of Contents

  1. Prerequisites
  2. Phase 1: Pre-Implementation Discovery
  3. Phase 2: Google OAuth Setup
  4. Phase 3: Create Cognito User Pool
  5. Phase 4: Domain Whitelist Configuration
  6. Phase 5: Google IdP Integration
  7. Phase 6: Amplify Integration
  8. Phase 7: Testing & Validation
  9. Phase 8: Migration Execution
  10. Rollback Procedures
  11. Troubleshooting

Prerequisites

  • AWS Console access with permissions to:
  • Amazon Cognito
  • AWS Amplify
  • AWS Lambda
  • CloudWatch Logs
  • IAM (for role creation)
  • Google Cloud Console access (for OAuth setup)
  • List of authorized email domains (@adaction.com, @adgem.com, etc.)
  • Access to 1Password "Engineering" vault

Phase 1: Pre-Implementation Discovery

1.1 Document Current Basic Auth Configuration

  1. Log into AWS Console and navigate to AWS Amplify
  2. Select the architecture-docs application
  3. Go to App settingsAccess control
  4. Take screenshots of the current basic auth configuration
  5. Note down:
  6. Username/password scheme (if applicable)
  7. Restricted branches
  8. Any IP allowlists or restrictions
  9. Store screenshots in a secure location for rollback reference

1.2 Identify Authorized Domains

Create a list of email domains that should have access: - @adaction.com - @adgem.com - (Add any additional domains as needed)

Document this list for use in the domain whitelist Lambda function.


Phase 2: Google OAuth Setup

2.1 Check for Existing Google OAuth Credentials

  1. Access 1Password "Engineering" vault
  2. Search for "Google OAuth" or "architecture-docs" entries
  3. Look for:
  4. Client ID
  5. Client Secret
  6. Project name

If credentials exist, proceed to 2.3 Verify Configuration. If not, continue to 2.2.

2.2 Create New Google OAuth Client (If Needed)

  1. Go to Google Cloud Console
  2. Create a new project or select existing project:
  3. Project name: architecture-docs-auth (or similar)
  4. Note the Project ID

  5. Enable Google+ API:

  6. Navigate to APIs & ServicesLibrary
  7. Search for "Google+ API"
  8. Click Enable

  9. Configure OAuth Consent Screen:

  10. Go to APIs & ServicesOAuth consent screen
  11. Select Internal (for organization-only access)
  12. Fill in application details:
    • App name: Architecture Docs
    • User support email: Your email
    • Developer contact email: Your email
  13. Add scopes:
    • email
    • profile
    • openid
  14. Save and continue

  15. Create OAuth 2.0 Client ID:

  16. Go to APIs & ServicesCredentials
  17. Click Create CredentialsOAuth client ID
  18. Application type: Web application
  19. Name: Architecture Docs - Cognito
  20. Authorized redirect URIs: (You'll update this after creating Cognito User Pool)
    • Format: https://<your-cognito-domain>.auth.<region>.amazoncognito.com/oauth2/idpresponse
    • You'll get this URL in Phase 3
  21. Click Create

  22. Save credentials:

  23. Copy the Client ID
  24. Copy the Client Secret
  25. Store both in 1Password "Engineering" vault under "Architecture Docs - Google OAuth"

2.3 Verify Configuration

Ensure you have: - ✅ Google Cloud project created - ✅ OAuth consent screen configured (Internal) - ✅ OAuth 2.0 Client ID and Secret - ✅ Credentials stored securely in 1Password


Phase 3: Create Cognito User Pool

3.1 Create User Pool

  1. Open AWS Console and navigate to Amazon Cognito
  2. Click Create user pool

3.2 Configure Sign-in Experience

Step 1: Configure sign-in experience - Authentication providers: - Select Federated identity providers - Check Google - Cognito user pool sign-in options: - Select Email - Click Next

3.3 Configure Security Requirements

Step 2: Configure security requirements - Password policy: - Select Cognito defaults or customize based on security requirements - Multi-factor authentication: - Select Optional MFA or No MFA (recommended: Optional) - If Optional: Enable Authenticator apps - User account recovery: - Check Email only - Click Next

3.4 Configure Sign-up Experience

Step 3: Configure sign-up experience - Self-service sign-up: - Disable self-service sign-up (we'll control access via domain whitelist) - Attribute verification: - Check Send email message, verify email address - Required attributes: - Keep default (email is already required) - Click Next

3.5 Configure Message Delivery

Step 4: Configure message delivery - Email provider: - Select Send email with Cognito (or configure SES if high volume expected) - SES Region: Choose appropriate region if using SES - FROM email address: no-reply@verificationemail.com (or your domain) - Click Next

3.6 Integrate Your App

Step 5: Integrate your app - User pool name: architecture-docs-user-pool - Hosted authentication pages: - Check Use the Cognito Hosted UI - Domain: - Domain type: Cognito domain - Cognito domain: architecture-docs-auth (or unique name) - Click Check availability - Initial app client: - App client name: architecture-docs-amplify - Client secret: Generate a client secret - Allowed callback URLs: https://eng.adaction.com/oauth2/callback - Also add: https://eng.adaction.com - Allowed sign-out URLs: https://eng.adaction.com - Advanced app client settings: - OAuth 2.0 grant types: - Check Authorization code grant - OpenID Connect scopes: - Check: openid, email, profile - Click Next

3.7 Review and Create

Step 6: Review and create - Review all settings - Click Create user pool

3.8 Note Important Values

After creation, note down: - User Pool ID: <region>_xxxxxxxxx - User Pool ARN: arn:aws:cognito-idp:<region>:<account-id>:userpool/<pool-id> - App Client ID: From app client settings - App Client Secret: From app client settings - Cognito Domain: https://architecture-docs-auth.auth.<region>.amazoncognito.com

Store these values securely in 1Password under "Architecture Docs - AWS Cognito".


Phase 4: Domain Whitelist Configuration

To restrict access to specific email domains, we'll create a Lambda trigger for pre-authentication.

4.1 Create Lambda Function

  1. Navigate to AWS Lambda in the console
  2. Click Create function
  3. Configure:
  4. Function name: architecture-docs-domain-whitelist
  5. Runtime: Python 3.12
  6. Permissions: Create new role with basic Lambda permissions
  7. Click Create function

4.2 Add Function Code

Replace the default code with:

import json

# List of allowed email domains
ALLOWED_DOMAINS = [
    'adaction.com',
    'adgem.com',
    # Add more domains as needed
]

def lambda_handler(event, context):
    # Get the user's email from the event
    email = event['request']['userAttributes'].get('email', '')

    # Extract domain from email
    domain = email.split('@')[-1].lower() if '@' in email else ''

    # Check if domain is in allowed list
    if domain not in ALLOWED_DOMAINS:
        raise Exception(f'Access denied: Email domain {domain} is not authorized')

    # If domain is allowed, return the event to continue the flow
    return event
  1. Click Deploy

4.3 Configure Lambda Permissions

  1. Go to ConfigurationPermissions
  2. Note the execution role name (e.g., architecture-docs-domain-whitelist-role-xxxxx)
  3. Click on the role name to open IAM
  4. Ensure the role has basic Lambda execution permissions (should be automatic)

4.4 Attach Lambda Trigger to Cognito

  1. Return to Amazon CognitoUser pools
  2. Select architecture-docs-user-pool
  3. Go to User pool propertiesLambda triggers
  4. Under Authentication, select Pre authentication trigger
  5. Select the Lambda function: architecture-docs-domain-whitelist
  6. Click Save changes

4.5 Test Domain Whitelist

Before proceeding, test with: - An email from an allowed domain (should succeed) - An email from a non-allowed domain (should be rejected)


Phase 5: Google IdP Integration

5.1 Add Google as Identity Provider

  1. In Amazon CognitoUser poolsarchitecture-docs-user-pool
  2. Go to Sign-in experienceFederated identity provider sign-in
  3. Click Add identity provider
  4. Select Google

5.2 Configure Google Identity Provider

  • Client ID: Paste the Google OAuth Client ID from Phase 2
  • Client secret: Paste the Google OAuth Client Secret from Phase 2
  • Authorized scopes: profile email openid
  • Attribute mapping:
  • Google attribute: email → User pool attribute: email
  • Google attribute: name → User pool attribute: name
  • Google attribute: sub → User pool attribute: username
  • Click Add identity provider

5.3 Update Google OAuth Redirect URI

  1. Go back to Google Cloud Console
  2. Navigate to APIs & ServicesCredentials
  3. Select your OAuth 2.0 Client ID
  4. Under Authorized redirect URIs, add:
  5. https://architecture-docs-auth.auth.<region>.amazoncognito.com/oauth2/idpresponse
  6. Replace <region> with your AWS region (e.g., us-east-1)
  7. Click Save

5.4 Update App Client to Use Google

  1. Return to Cognito User Pool
  2. Go to App integrationApp clients and analytics
  3. Select architecture-docs-amplify app client
  4. Under Hosted UI settings, click Edit
  5. Identity providers:
  6. Check Google
  7. Uncheck Cognito user pool (only allow Google login)
  8. Click Save changes

Phase 6: Amplify Integration

6.1 Configure Cognito in Amplify

  1. Navigate to AWS Amplify in the console
  2. Select the architecture-docs application
  3. Go to App settingsAccess control
  4. Click Manage access

6.2 Add Cognito Authentication

  1. Access control type:
  2. Select Restrict access with Cognito
  3. Select a Cognito user pool:
  4. Choose: architecture-docs-user-pool
  5. Apply access control to:
  6. Select All branches or specific branches as needed
  7. Recommended: Apply to main branch initially
  8. Keep basic authentication?
  9. Disable the current basic auth
  10. Note: Keep the configuration saved elsewhere for rollback
  11. Click Save

6.3 Verify Amplify Configuration

  1. Go to App settingsAccess control
  2. Verify:
  3. ✅ Cognito user pool is selected
  4. ✅ Branches are protected
  5. ✅ Basic auth is disabled

Phase 7: Testing & Validation

7.1 Test Authentication Flow

  1. Open the architecture-docs site in incognito/private window:
  2. URL: https://eng.adaction.com
  3. You should be redirected to Cognito Hosted UI
  4. Click Continue with Google
  5. Authenticate with a Google account from an allowed domain
  6. Verify you're redirected back to the docs site
  7. Verify the site loads correctly and all pages are accessible

7.2 Test Domain Whitelist

  1. Attempt to sign in with a Google account from a non-allowed domain
  2. Verify access is denied with an appropriate error message
  3. Check CloudWatch Logs for the Lambda function to verify the trigger fired

7.3 Test Sign-Out

  1. Sign out from the docs site (look for sign-out link or clear session)
  2. Verify you're redirected to the Cognito sign-in page
  3. Sign in again to verify re-authentication works

7.4 Test with Multiple Users

  1. Have 3-5 team members test authentication
  2. Test from different browsers and devices
  3. Collect feedback on user experience
  4. Verify all users from allowed domains can access

7.5 Verify CloudWatch Logs

  1. Navigate to CloudWatchLog groups
  2. Check logs for:
  3. Lambda function: /aws/lambda/architecture-docs-domain-whitelist
  4. Cognito: Look for authentication events
  5. Verify no unexpected errors

Phase 8: Migration Execution

8.1 Pre-Migration Checklist

Verify the following before migration: - [ ] Cognito User Pool created and configured - [ ] Google IdP integrated and tested - [ ] Domain whitelist Lambda tested with allowed/denied domains - [ ] Amplify configured to use Cognito (but not yet active in production) - [ ] Test users successfully authenticated - [ ] Rollback procedure documented and reviewed - [ ] Team notified of migration timing - [ ] Basic auth configuration backed up

8.2 Execute Migration

  1. Coordinate with team:
  2. Announce maintenance window (5-10 minutes expected)
  3. Have team members ready to test immediately after

  4. Enable Cognito in Amplify:

  5. Go to AWS Amplifyarchitecture-docsAccess control
  6. If not already done, configure Cognito as described in Phase 6
  7. Click Save

  8. Disable Basic Auth:

  9. Remove basic auth configuration from Amplify
  10. Save changes

  11. Monitor deployment:

  12. Watch CloudWatch logs for authentication events
  13. Check for any errors in Lambda function logs

8.3 Immediate Post-Migration Validation

  1. Have 3-5 team members test access immediately
  2. Verify all can authenticate successfully
  3. Check for any error messages or issues
  4. Monitor CloudWatch Logs for anomalies

8.4 Communication

  1. Notify team that migration is complete
  2. Share sign-in URL: https://eng.adaction.com
  3. Provide brief instructions:
  4. "Click 'Continue with Google'"
  5. "Use your @adaction.com or @adgem.com email"
  6. Share link to troubleshooting guide (see below)

Rollback Procedures

If issues occur during or after migration, follow these steps to rollback to basic authentication.

When to Rollback

  • Critical authentication failures affecting multiple users
  • Cognito service issues preventing access
  • Domain whitelist incorrectly blocking authorized users
  • Any P0 issue preventing team access to documentation

Rollback Steps

  1. Log into AWS ConsoleAmplifyarchitecture-docs

  2. Re-enable Basic Auth:

  3. Go to App settingsAccess control
  4. Click Manage access
  5. Select Restrict access with a username and password
  6. Enter the previous basic auth credentials (from Phase 1 screenshots)
  7. Apply to the same branches
  8. Click Save

  9. Disable Cognito:

  10. While in Access control settings
  11. Remove or disable Cognito authentication
  12. Click Save

  13. Verify Rollback:

  14. Open the docs site in incognito window
  15. Verify basic auth prompt appears
  16. Enter credentials and verify access

  17. Notify Team:

  18. Inform team that rollback was executed
  19. Provide basic auth credentials via secure channel
  20. Schedule post-mortem to review issues

Post-Rollback Actions

  1. Review CloudWatch Logs to identify root cause
  2. Fix identified issues in Cognito/Lambda configuration
  3. Re-test in a staging environment if possible
  4. Schedule new migration attempt after fixes are validated

User Management

Adding New Authorized Domains

  1. Navigate to AWS Lambdaarchitecture-docs-domain-whitelist
  2. Update the ALLOWED_DOMAINS list in the function code: python ALLOWED_DOMAINS = [ 'adaction.com', 'adgem.com', 'newdomain.com', # Add new domain here ]
  3. Click Deploy
  4. Test with a user from the new domain

Removing Domains

  1. Navigate to AWS Lambdaarchitecture-docs-domain-whitelist
  2. Remove the domain from the ALLOWED_DOMAINS list
  3. Click Deploy
  4. Existing sessions may remain active until they expire

Adding Individual Users (Outside Whitelisted Domains)

If you need to grant access to a specific user outside the allowed domains:

Option 1: Add their domain to the whitelist (if others from that domain should have access)

Option 2: Create a Cognito user directly (bypasses the Lambda trigger for pre-created users) 1. Go to Amazon Cognitoarchitecture-docs-user-pool 2. Go to Users tab 3. Click Create user 4. Enter email address 5. Set temporary password (user will be prompted to change) 6. Click Create user

Note: The domain whitelist Lambda only runs on federated (Google) authentication, not for direct Cognito users.

Removing User Access

For federated users (Google): - Access is controlled by domain whitelist - Simply remove their domain from the whitelist (affects all users from that domain)

For individual Cognito users: 1. Go to Amazon Cognitoarchitecture-docs-user-pool 2. Go to Users tab 3. Select the user 4. Click Disable user or Delete user


Troubleshooting

Issue: "Access denied: Email domain X is not authorized"

Cause: User's email domain is not in the whitelist

Resolution: 1. Verify the user's email domain should have access 2. Add the domain to the Lambda whitelist (see User Management) 3. Have user retry authentication

Issue: "Invalid redirect URI" or OAuth error

Cause: Mismatch between Cognito callback URLs and Google OAuth configuration

Resolution: 1. Verify Cognito domain and app client callback URLs match exactly 2. Check Google Cloud Console → OAuth Client → Authorized redirect URIs 3. Ensure the URI is: https://<cognito-domain>.auth.<region>.amazoncognito.com/oauth2/idpresponse 4. Update as needed and retry

Issue: User authenticated but gets "Access Denied" from Amplify

Cause: Amplify not properly configured to recognize Cognito user pool

Resolution: 1. Check Amplify Access Control settings 2. Verify the correct Cognito User Pool is selected 3. Ensure the branch is properly protected with Cognito 4. Check CloudWatch Logs for detailed error messages

Issue: "Client authentication failed" error

Cause: Google OAuth client secret mismatch or expiration

Resolution: 1. Verify Google OAuth client secret in Google Cloud Console 2. Update the secret in Cognito User Pool → Identity providers → Google 3. Retry authentication

Issue: Lambda function errors in CloudWatch

Cause: Lambda syntax error, permission issue, or unexpected event structure

Resolution: 1. Check CloudWatch Logs → /aws/lambda/architecture-docs-domain-whitelist 2. Review the error message 3. Common fixes: - Verify Lambda has correct execution role - Check for typos in ALLOWED_DOMAINS list - Ensure Lambda is attached to correct Cognito trigger

Issue: Users get signed out frequently

Cause: Short session timeout or token expiration

Resolution: 1. Go to Cognito User Pool → App integration → App client 2. Check Token expiration settings 3. Increase Access token and ID token expiration (e.g., 24 hours) 4. Increase Refresh token expiration (e.g., 30 days)


Monitoring and Maintenance

CloudWatch Dashboards

Consider creating a CloudWatch dashboard to monitor: - Cognito authentication success/failure metrics - Lambda invocation counts and errors - Amplify access logs

Regular Maintenance Tasks

  1. Quarterly: Review and update allowed domains list
  2. Monthly: Review CloudWatch Logs for authentication anomalies
  3. As needed: Rotate Google OAuth client secrets
  4. After major changes: Test authentication flow end-to-end

Additional Resources


Document Version History

Version Date Author Changes
1.0 2025-10-30 Initial Created comprehensive migration guide

Questions or Issues? Contact the Engineering team or refer to the troubleshooting section above.