Cognito Authentication KMS Encryption: Secure AWS Apps

AWS Security: Cognito, KMS, Secrets Manager, and CloudTrail

Introduction

Security is fundamental to cloud applications. AWS provides comprehensive security services: Amazon Cognito for user authentication and authorization, AWS KMS for encryption key management, AWS Secrets Manager for secure credential storage and rotation, and AWS CloudTrail for audit logging and compliance.

This guide explores authentication flows with Cognito, encryption at rest and in transit with KMS, automatic secret rotation with Secrets Manager, and security event tracking with CloudTrail. We'll cover practical implementation patterns and production security best practices.


AWS Developer Certification Series

📚 View Complete AWS Developer Certification Guide - Master all 7 parts with our comprehensive learning path.

This is Part VI (Current Article) of our comprehensive 7-part AWS developer guide:

  1. Part I: IAM EC2 & Auto Scaling
  2. Part II: RDS Aurora & DynamoDB
  3. Part III: SQS SNS & Kinesis
  4. Part IV: Lambda API Gateway
  5. Part V: ECS Fargate & IaC
  6. Part VI: Cognito KMS Security (Current Article)
  7. Part VII: CodePipeline & Monitoring

← Part V: ECS Fargate & IaC | Part VII: CodePipeline & Monitoring →


Amazon Cognito

Cognito Architecture

Cognito provides user authentication, authorization, and user management for web and mobile applications.

   AWS Services   

   Identity Providers   

   Amazon Cognito   

   Client Application   

   sign in   

   social login   

   social login   

   enterprise   

   JWT token   

   exchange token   

   temp credentials   

   authorized   

   access   

   query   

  Web/Mobile App  

  User Pool  

  Authentication  

  Identity Pool  

  AWS Credentials  

  Google  

  Facebook  

  SAML  

  API Gateway  

  S3  

  DynamoDB  

Cognito User Pools:

  • User directory for sign-up and sign-in
  • Customizable UI hosted by AWS
  • MFA, password policies, account recovery
  • Social and enterprise identity federation
  • JWT tokens (ID, Access, Refresh)

Cognito Identity Pools:

  • Provide AWS credentials for direct AWS service access
  • Support authenticated and unauthenticated (guest) users
  • Integrate with User Pools, social providers, SAML

Cognito User Pool Authentication

Sign up and confirm user (AWS SDK):

const {
  CognitoIdentityProviderClient,
  SignUpCommand,
  ConfirmSignUpCommand,
} = require('@aws-sdk/client-cognito-identity-provider');

const client = new CognitoIdentityProviderClient({ region: 'us-east-1' });

async function signUp(username, password, email) {
  const command = new SignUpCommand({
    ClientId: 'your-app-client-id',
    Username: username,
    Password: password,
    UserAttributes: [{ Name: 'email', Value: email }],
  });

  const response = await client.send(command);
  console.log('User registered:', response.UserSub);
  return response;
}

async function confirmSignUp(username, confirmationCode) {
  const command = new ConfirmSignUpCommand({
    ClientId: 'your-app-client-id',
    Username: username,
    ConfirmationCode: confirmationCode,
  });

  await client.send(command);
  console.log('User confirmed');
}

Sign in and get tokens:

const {
  InitiateAuthCommand,
} = require('@aws-sdk/client-cognito-identity-provider');

async function signIn(username, password) {
  const command = new InitiateAuthCommand({
    AuthFlow: 'USER_PASSWORD_AUTH',
    ClientId: 'your-app-client-id',
    AuthParameters: {
      USERNAME: username,
      PASSWORD: password,
    },
  });

  const response = await client.send(command);

  // Returns JWT tokens
  const { IdToken, AccessToken, RefreshToken } = response.AuthenticationResult;

  return {
    idToken: IdToken, // User identity claims
    accessToken: AccessToken, // API Gateway authorization
    refreshToken: RefreshToken, // Get new tokens
  };
}

API Gateway + Cognito Authorization

Verify Cognito token in API Gateway:

API Gateway automatically validates JWT tokens from Cognito User Pools when configured as an authorizer.

Call API with token (curl):

# Get token from sign-in response
TOKEN="eyJraWQiOiJ..."

# Call protected API endpoint
curl https://api.example.com/users \
  -H "Authorization: Bearer $TOKEN"

Cognito Identity Pool for AWS Access

Exchange Cognito token for AWS credentials:

const {
  CognitoIdentityClient,
  GetIdCommand,
  GetCredentialsForIdentityCommand,
} = require('@aws-sdk/client-cognito-identity');
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');

const cognitoClient = new CognitoIdentityClient({ region: 'us-east-1' });

async function getAwsCredentials(idToken) {
  // Get Identity ID
  const getIdCommand = new GetIdCommand({
    IdentityPoolId: 'us-east-1:12345678-1234-1234-1234-123456789012',
    Logins: {
      'cognito-idp.us-east-1.amazonaws.com/us-east-1_ABC123': idToken,
    },
  });
  const { IdentityId } = await cognitoClient.send(getIdCommand);

  // Get temporary AWS credentials
  const getCredsCommand = new GetCredentialsForIdentityCommand({
    IdentityId,
    Logins: {
      'cognito-idp.us-east-1.amazonaws.com/us-east-1_ABC123': idToken,
    },
  });
  const { Credentials } = await cognitoClient.send(getCredsCommand);

  return Credentials; // AccessKeyId, SecretKey, SessionToken
}

// Use credentials to access S3
async function uploadToS3(credentials, fileName, fileContent) {
  const s3Client = new S3Client({
    region: 'us-east-1',
    credentials: {
      accessKeyId: credentials.AccessKeyId,
      secretAccessKey: credentials.SecretKey,
      sessionToken: credentials.SessionToken,
    },
  });

  const command = new PutObjectCommand({
    Bucket: 'my-user-uploads',
    Key: fileName,
    Body: fileContent,
  });

  await s3Client.send(command);
}

AWS KMS (Key Management Service)

KMS Architecture

KMS manages encryption keys for encrypting data at rest and in transit.

   Encrypted Storage   

   Application   

   AWS KMS   

   1. generate DEK   

   2. plaintext + encrypted DEK   

   3. encrypt data with DEK   

   4. store encrypted DEK   

   encrypts   

   encrypts   

  Customer Master Key  

  CMK  

  Data Encryption Key  

  DEK  

  Application Code  

  S3  

  EBS  

  RDS  

Key Types:

  • AWS Managed Keys: Automatic key rotation every year
  • Customer Managed Keys (CMK): Full control, manual or automatic rotation
  • AWS Owned Keys: Used by AWS services, not visible to customers

Envelope Encryption Pattern

Encrypt data with KMS:

const {
  KMSClient,
  GenerateDataKeyCommand,
  DecryptCommand,
} = require('@aws-sdk/client-kms');
const crypto = require('crypto');

const kmsClient = new KMSClient({ region: 'us-east-1' });

async function encryptData(plaintext, keyId) {
  // 1. Generate data encryption key (DEK)
  const command = new GenerateDataKeyCommand({
    KeyId: keyId, // CMK ARN or alias
    KeySpec: 'AES_256',
  });
  const { Plaintext: plaintextKey, CiphertextBlob: encryptedKey } =
    await kmsClient.send(command);

  // 2. Encrypt data with plaintext DEK
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv(
    'aes-256-cbc',
    Buffer.from(plaintextKey),
    iv,
  );
  let encrypted = cipher.update(plaintext, 'utf8', 'base64');
  encrypted += cipher.final('base64');

  // 3. Return encrypted data + encrypted DEK + IV
  return {
    encryptedData: encrypted,
    encryptedKey: encryptedKey.toString('base64'),
    iv: iv.toString('base64'),
  };
}

async function decryptData(encryptedData, encryptedKey, iv) {
  // 1. Decrypt DEK using KMS
  const command = new DecryptCommand({
    CiphertextBlob: Buffer.from(encryptedKey, 'base64'),
  });
  const { Plaintext: plaintextKey } = await kmsClient.send(command);

  // 2. Decrypt data with plaintext DEK
  const decipher = crypto.createDecipheriv(
    'aes-256-cbc',
    Buffer.from(plaintextKey),
    Buffer.from(iv, 'base64'),
  );
  let decrypted = decipher.update(encryptedData, 'base64', 'utf8');
  decrypted += decipher.final('utf8');

  return decrypted;
}

Enable S3 bucket encryption with KMS:

# Server-side encryption with KMS
aws s3api put-bucket-encryption \
  --bucket my-secure-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "aws:kms",
        "KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
      },
      "BucketKeyEnabled": true
    }]
  }'

AWS Secrets Manager

Secrets Manager Features

Secrets Manager stores and automatically rotates database credentials, API keys, and other secrets.

Store a secret:

# Create secret
aws secretsmanager create-secret \
  --name prod/db/password \
  --description "Production database password" \
  --secret-string '{"username":"admin","password":"MySecureP@ssw0rd"}'

Retrieve secret in application:

const {
  SecretsManagerClient,
  GetSecretValueCommand,
} = require('@aws-sdk/client-secrets-manager');

const client = new SecretsManagerClient({ region: 'us-east-1' });

async function getSecret(secretName) {
  const command = new GetSecretValueCommand({
    SecretId: secretName,
  });

  const response = await client.send(command);

  // Parse JSON secret
  const secret = JSON.parse(response.SecretString);
  return secret; // { username: 'admin', password: '...' }
}

// Use in database connection
async function connectToDatabase() {
  const dbCreds = await getSecret('prod/db/password');

  const connection = await mysql.createConnection({
    host: 'db.example.com',
    user: dbCreds.username,
    password: dbCreds.password,
    database: 'myapp',
  });

  return connection;
}

Automatic Secret Rotation

Enable rotation for RDS database:

aws secretsmanager rotate-secret \
  --secret-id prod/db/password \
  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSRotation \
  --rotation-rules AutomaticallyAfterDays=30

Rotation Lambda function (simplified):

exports.handler = async event => {
  const { Step, SecretId } = event;

  switch (Step) {
    case 'createSecret':
      // Generate new password
      const newPassword = generateRandomPassword();
      await putSecretValue(SecretId, newPassword, 'AWSPENDING');
      break;

    case 'setSecret':
      // Update database with new password
      const pending = await getSecretValue(SecretId, 'AWSPENDING');
      await updateDatabasePassword(pending);
      break;

    case 'testSecret':
      // Test new password
      const test = await getSecretValue(SecretId, 'AWSPENDING');
      await testDatabaseConnection(test);
      break;

    case 'finishSecret':
      // Mark new version as current
      await finishSecretRotation(SecretId);
      break;
  }
};

AWS CloudTrail

CloudTrail Architecture

CloudTrail logs all API calls for auditing, compliance, and security analysis.

Key Features:

  • Records API calls from Console, CLI, SDK, and services
  • Delivers logs to S3, CloudWatch Logs, and EventBridge
  • Supports multi-region and multi-account logging
  • Insights: Detect unusual API activity

CloudTrail Event Types

Management Events:

  • Control plane operations (CreateInstance, DeleteBucket)
  • Enabled by default
  • Read-only or write-only filtering

Data Events:

  • Data plane operations (GetObject, PutObject, Lambda invocations)
  • Disabled by default (high volume)
  • Configure per resource

Insights Events:

  • Detects unusual API call patterns
  • Uses machine learning
  • Requires paid feature

Query CloudTrail Logs

Create trail:

aws cloudtrail create-trail \
  --name my-trail \
  --s3-bucket-name my-cloudtrail-logs

aws cloudtrail start-logging --name my-trail

# Enable CloudWatch Logs integration
aws cloudtrail update-trail \
  --name my-trail \
  --cloud-watch-logs-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:/aws/cloudtrail \
  --cloud-watch-logs-role-arn arn:aws:iam::123456789012:role/CloudTrailRole

Query recent events:

# Get recent API calls
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteBucket \
  --max-results 10

# Query by user
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=alice

CloudWatch Insights query (find failed actions):

fields @timestamp, userIdentity.principalId, eventName, errorCode
| filter errorCode exists
| sort @timestamp desc
| limit 20

Production Best Practices

Cognito Best Practices

  1. MFA: Enable multi-factor authentication for sensitive applications
  2. Password Policy: Enforce strong passwords (min length, special chars)
  3. Token Expiration: Set appropriate token lifetimes (ID: 1h, Refresh: 30d)
  4. Advanced Security: Enable compromise credential detection
  5. Custom Domains: Use custom domain for hosted UI (branded experience)

KMS Best Practices

  1. Key Rotation: Enable automatic key rotation (yearly)
  2. Least Privilege: Grant minimal KMS permissions (kms:Decrypt only when needed)
  3. Envelope Encryption: Use for large data (>4KB limit)
  4. CloudTrail: Monitor key usage with CloudTrail logs
  5. Key Policies: Use both key policies and IAM policies for access control

Secrets Manager Best Practices

  1. Rotation: Enable automatic rotation for database credentials
  2. Versioning: Use version stages (AWSCURRENT, AWSPENDING)
  3. Caching: Cache secrets in application (avoid repeated API calls)
  4. Fine-grained Access: Use IAM policies to restrict secret access
  5. Encryption: All secrets encrypted with KMS by default

CloudTrail Best Practices

  1. Multi-Region: Enable trail in all regions
  2. Log File Validation: Enable to detect tampering
  3. S3 Lifecycle: Archive old logs to Glacier (cost optimization)
  4. EventBridge: Trigger alerts on critical API calls
  5. CloudWatch Alarms: Alert on suspicious activity patterns

Monitoring and Troubleshooting

Cognito Metrics:

  • SignInSuccesses / SignInFailures
  • TokenRefreshSuccesses
  • UserAuthentication

KMS Metrics:

  • NumberOfDecryptCalls
  • ThrottledRequests

CloudTrail:

  • Monitor S3 bucket for log delivery
  • Set CloudWatch Alarms on critical events (Root account usage, Console sign-in failures)

Exam Tips

Key Concepts:

  1. Cognito User Pool = Authentication (sign-in), Identity Pool = Authorization (AWS credentials)
  2. KMS encrypts data ≤4KB directly, use envelope encryption for larger data
  3. Secrets Manager auto-rotates secrets, Parameter Store (SSM) does not
  4. CloudTrail logs API calls, CloudWatch logs application logs
  5. CMK = Customer Master Key (never leaves KMS), DEK = Data Encryption Key (encrypts data)

Common Scenarios:

  • "Authenticate mobile app users" → Cognito User Pools
  • "Grant mobile app access to S3" → Cognito Identity Pools
  • "Encrypt database credentials" → Secrets Manager (with KMS)
  • "Rotate database password automatically" → Secrets Manager rotation
  • "Audit who deleted S3 bucket" → CloudTrail
  • "Detect compromised credentials" → Cognito Advanced Security

Frequently Asked Questions

Q: What is the difference between Cognito User Pools and Identity Pools?

Cognito User Pools handle authentication (sign-up, sign-in, password management) and issue JWT tokens for verifying user identity. Identity Pools handle authorization by exchanging authentication tokens for temporary AWS credentials to access services like S3 or DynamoDB. Use User Pools for authentication, Identity Pools for AWS resource access.

Q: How does AWS KMS encryption work?

KMS uses Customer Master Keys (CMKs) that never leave the service to encrypt data. For data under 4KB, KMS encrypts directly. For larger data, it uses envelope encryption: KMS generates a data key, encrypts your data with the data key, then encrypts the data key with the CMK. This provides secure, scalable encryption.

Q: When should I use Secrets Manager instead of Parameter Store?

Use Secrets Manager when you need automatic credential rotation for databases, built-in versioning, or cross-region replication. Secrets Manager costs $0.40/secret/month. Use Systems Manager Parameter Store for configuration values or secrets without rotation needs. Parameter Store is free for standard parameters, $0.05/month for advanced.

Q: What is AWS CloudTrail used for?

CloudTrail records all API calls made in your AWS account, providing complete audit trails for security analysis, compliance, and troubleshooting. It logs who made requests, from what IP, when, and what resources were affected. Enable multi-region trails and log file validation for comprehensive security monitoring.

Q: How does Cognito federated identity work?

Federated identity allows users to sign in through external providers like Google, Facebook, or SAML-based corporate directories. Cognito User Pools integrate with identity providers, authenticate users, and issue tokens. Identity Pools then exchange these tokens for temporary AWS credentials with appropriate IAM role permissions.

Q: What is envelope encryption in AWS?

Envelope encryption uses two keys: a data encryption key (DEK) encrypts your data, and a master key in KMS encrypts the DEK. This approach is faster for large files, reduces KMS API calls, and allows data keys to be stored with encrypted data. It's the standard pattern for S3, EBS, and RDS encryption.

Q: How do I rotate secrets automatically in AWS?

Secrets Manager automates rotation using Lambda functions that update credentials in both the secret and target service. Configure rotation intervals (30-365 days), and Secrets Manager creates AWSPENDING versions, updates credentials, validates them, then promotes to AWSCURRENT. This eliminates manual rotation and reduces security risks.


Conclusion

AWS security services provide comprehensive protection for authentication, encryption, secrets management, and audit logging. Cognito simplifies user authentication with built-in federation, KMS manages encryption keys with envelope encryption patterns, Secrets Manager automates credential rotation, and CloudTrail provides complete API audit trails.

Choose Cognito for user authentication, KMS for encryption key management, Secrets Manager for rotating credentials, and CloudTrail for compliance and security monitoring. Understanding authentication flows, encryption patterns, and audit logging is essential for both production security and the AWS Certified Developer Associate exam.