Zeros and OnesLLC
Migration6 min read

Migrating from AWS Cognito to TitaniumVault

Complete guide to moving your authentication from AWS Cognito to TitaniumVault. Escape AWS lock-in with predictable pricing and better UX.

By Zeros and Ones Team

title: "Migrating from AWS Cognito to TitaniumVault" description: "Complete guide to moving your authentication from AWS Cognito to TitaniumVault. Escape AWS lock-in with predictable pricing and better UX." date: "2025-01-08" author: "Zeros and Ones Team" category: "Migration" tags: ["AWS", "Cognito", "Migration", "TitaniumVault", "Cloud", "Identity"]

AWS Cognito is convenient if you're all-in on AWS, but many teams find its complexity and AWS-centric design limiting. This guide walks you through migrating to TitaniumVault for a more flexible, user-friendly identity solution.

Why Teams Leave Cognito

Common frustrations:

  1. Complex Configuration: Simple tasks require multiple AWS services
  2. Confusing Pricing: MAU calculations and federation charges surprise teams
  3. Limited Customization: Email templates and UI are restrictive
  4. AWS Lock-in: Tight coupling makes multi-cloud difficult
  5. Poor Admin UX: The console is powerful but overwhelming

Pre-Migration Planning

Document Your Cognito Setup

User Pools:

  • User count and attributes
  • Custom attributes
  • Groups and permissions
  • MFA configuration
  • Password policies

Identity Pools:

  • Federated identities configuration
  • IAM role mappings
  • Authentication providers

App Clients:

  • OAuth/OIDC settings
  • Callback URLs
  • Token expiration settings
  • Hosted UI configuration

Lambda Triggers:

  • Pre-signup
  • Post-confirmation
  • Pre/post-authentication
  • Custom message
  • Token generation

API Dependencies

Identify where Cognito is used:

# Search codebase for Cognito references
grep -r "cognito" --include="*.js" --include="*.ts" --include="*.py"
grep -r "aws-amplify" --include="*.json"

Migration Approach

Strategy Options

Option 1: Parallel Running (Recommended)

Run both systems simultaneously during transition.

  • Lower risk
  • Easy rollback
  • Gradual user migration

Option 2: Big Bang

Complete switchover in maintenance window.

  • Clean cutover
  • Shorter transition
  • Higher risk

Step-by-Step Migration

Phase 1: TitaniumVault Setup

  1. Create your organization

    # Via CLI or API
    curl -X POST "https://api.titanium-vault.com/v1/organizations" \
      -H "Authorization: Bearer $TOKEN" \
      -d '{"name": "Your Company", "domain": "your-company"}'
    
  2. Configure authentication settings

    • Match Cognito password policies
    • Set up equivalent MFA options
    • Configure session settings
  3. Set up social/enterprise providers

    • Replicate Cognito identity provider settings
    • Test each connection

Phase 2: Export Users from Cognito

Cognito doesn't allow password export, but you can export user data:

const AWS = require('aws-sdk');
const cognito = new AWS.CognitoIdentityServiceProvider();

async function exportUsers(userPoolId) {
  const users = [];
  let paginationToken;

  do {
    const result = await cognito.listUsers({
      UserPoolId: userPoolId,
      PaginationToken: paginationToken,
    }).promise();

    users.push(...result.Users);
    paginationToken = result.PaginationToken;
  } while (paginationToken);

  return users;
}

Phase 3: Import Users to TitaniumVault

Transform Cognito users:

const transformCognitoUser = (cognitoUser) => {
  const attrs = {};
  cognitoUser.Attributes.forEach(attr => {
    attrs[attr.Name] = attr.Value;
  });

  return {
    email: attrs.email,
    emailVerified: attrs.email_verified === 'true',
    phoneNumber: attrs.phone_number,
    firstName: attrs.given_name,
    lastName: attrs.family_name,
    username: cognitoUser.Username,
    status: cognitoUser.UserStatus === 'CONFIRMED' ? 'active' : 'pending',
    metadata: {
      cognitoSub: attrs.sub,
      // Map custom attributes
    }
  };
};

Import to TitaniumVault:

curl -X POST "https://api.titanium-vault.com/v1/users/bulk" \
  -H "Authorization: Bearer $TV_TOKEN" \
  -H "Content-Type: application/json" \
  -d @transformed_users.json

Phase 4: Password Handling

Since Cognito doesn't export passwords, options:

Option A: Force Password Reset

// Send password reset to all users
for (const user of users) {
  await titaniumVault.sendPasswordReset(user.email);
}

Option B: Lazy Migration During a transition period, if TitaniumVault login fails:

  1. Try authenticating against Cognito
  2. If successful, set password in TitaniumVault
  3. User continues seamlessly

Option C: Custom Lambda Bridge Use a Lambda function to verify against Cognito during transition:

// TitaniumVault webhook -> Lambda -> Cognito
exports.handler = async (event) => {
  const { username, password } = event;

  try {
    await cognito.adminInitiateAuth({
      AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',
      UserPoolId: USER_POOL_ID,
      ClientId: CLIENT_ID,
      AuthParameters: {
        USERNAME: username,
        PASSWORD: password,
      }
    }).promise();

    return { verified: true };
  } catch (e) {
    return { verified: false };
  }
};

Phase 5: Update Applications

React with Amplify → TitaniumVault

Before:

import { Amplify, Auth } from 'aws-amplify';

Amplify.configure({
  Auth: {
    region: 'us-east-1',
    userPoolId: 'us-east-1_xxxxx',
    userPoolWebClientId: 'xxxxxxxxx',
  }
});

// Login
const user = await Auth.signIn(username, password);

After:

import { TitaniumVaultClient } from '@titaniumvault/client';

const auth = new TitaniumVaultClient({
  domain: 'your-org.titanium-vault.com',
  clientId: 'your-client-id',
});

// Login
const user = await auth.signIn(username, password);

Backend Token Verification

Before (Cognito):

const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

const client = jwksClient({
  jwksUri: `https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxx/.well-known/jwks.json`
});

After (TitaniumVault):

const client = jwksClient({
  jwksUri: `https://your-org.titanium-vault.com/.well-known/jwks.json`
});

Phase 6: Migrate Lambda Triggers

Map Cognito triggers to TitaniumVault webhooks:

| Cognito Trigger | TitaniumVault Equivalent | |-----------------|--------------------------| | Pre Sign-up | user.pre_signup webhook | | Post Confirmation | user.confirmed webhook | | Pre Authentication | auth.pre_login webhook | | Post Authentication | auth.success webhook | | Custom Message | Email template customization | | Pre Token Generation | Token claims configuration |

Example webhook migration:

// Cognito Lambda (before)
exports.handler = async (event) => {
  if (event.triggerSource === 'PostConfirmation_ConfirmSignUp') {
    await createUserInDatabase(event.request.userAttributes);
  }
  return event;
};

// TitaniumVault webhook (after)
app.post('/webhooks/user-confirmed', async (req, res) => {
  const { user } = req.body;
  await createUserInDatabase(user);
  res.sendStatus(200);
});

Phase 7: Testing

Comprehensive test plan:

  • [ ] User registration
  • [ ] Email verification
  • [ ] Login (username/email)
  • [ ] Social login (Google, Facebook, etc.)
  • [ ] MFA setup and verification
  • [ ] Password reset
  • [ ] Token refresh
  • [ ] Logout
  • [ ] API authorization
  • [ ] Federated login (SAML)
  • [ ] Custom attributes

Phase 8: Cutover

  1. Update DNS/routing
  2. Monitor authentication metrics
  3. Keep Cognito running for 30 days (fallback)
  4. Disable Cognito after successful migration

Cost Comparison

| Users | Cognito Cost | TitaniumVault | |-------|-------------|---------------| | 10,000 MAU | ~$275/mo | Flat rate | | 50,000 MAU | ~$1,275/mo | Flat rate | | 100,000 MAU | ~$2,525/mo | Flat rate | | SAML Federation | +$0.015/MAU | Included | | Advanced Security | +$0.050/MAU | Included |

Common Issues

Issue: SRP Authentication

Cognito uses SRP (Secure Remote Password). TitaniumVault uses standard OAuth/OIDC.

Solution: Update client code to use standard authentication flows.

Issue: Custom Attributes

Cognito custom attributes have specific naming (custom:attribute).

Solution: Map to TitaniumVault user metadata during import.

Issue: Identity Pool IAM Roles

If using identity pools for AWS resource access:

Solution: Use TitaniumVault tokens with AWS STS AssumeRoleWithWebIdentity or implement a token exchange service.


Ready to escape AWS lock-in? Start your free trial and our team will help you plan and execute your Cognito migration.

Tags

AWSCognitoMigrationTitaniumVaultCloudIdentity