Cognito автентифікація KMS шифрування: Безпечні AWS додатки

AWS Безпека: Cognito, KMS, Secrets Manager та CloudTrail

Вступ

Безпека є фундаментальною для хмарних застосунків. AWS надає комплексні сервіси безпеки: Amazon Cognito для автентифікації та авторизації користувачів, AWS KMS для керування ключами шифрування, AWS Secrets Manager для безпечного зберігання та ротації облікових даних, та AWS CloudTrail для аудиту логів та відповідності вимогам.

Цей посібник досліджує потоки автентифікації з Cognito, шифрування в стані спокою та під час передачі з KMS, автоматичну ротацію секретів з Secrets Manager та відстеження подій безпеки з CloudTrail. Ми розглянемо практичні шаблони реалізації та production найкращі практики безпеки.

Серія AWS Developer Certification

📚 Переглянути повний посібник AWS Developer Certification - Опануйте всі 7 частин з нашим комплексним шляхом навчання.

Це Частина VI (Поточна стаття) нашого комплексного 7-частинного посібника для AWS розробників:

  1. Частина I: IAM EC2 та Auto Scaling
  2. Частина II: RDS Aurora та DynamoDB
  3. Частина III: SQS SNS та Kinesis
  4. Частина IV: Lambda API Gateway
  5. Частина V: ECS Fargate та IaC
  6. Частина VI: Cognito KMS Security (Поточна стаття)
  7. Частина VII: CodePipeline та Monitoring

← Частина V: ECS Fargate та IaC | Частина VII: CodePipeline та Monitoring →


Amazon Cognito

Архітектура Cognito

Cognito надає автентифікацію користувачів, авторизацію та керування користувачами для веб та мобільних застосунків.

   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:

  • Директорія користувачів для реєстрації та входу
  • Налаштовуваний UI, що розміщується AWS
  • MFA, політики паролів, відновлення облікового запису
  • Федерація соціальних та корпоративних ідентичностей
  • JWT токени (ID, Access, Refresh)

Cognito Identity Pools:

  • Надають облікові дані AWS для прямого доступу до сервісів AWS
  • Підтримка автентифікованих та неавтентифікованих (гостьових) користувачів
  • Інтеграція з User Pools, соціальними провайдерами, SAML

Автентифікація Cognito User Pool

Реєстрація та підтвердження користувача (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('Користувача зареєстровано:', 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('Користувача підтверджено');
}

Вхід та отримання токенів:

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);

  // Повертає JWT токени
  const { IdToken, AccessToken, RefreshToken } = response.AuthenticationResult;

  return {
    idToken: IdToken, // Дані ідентичності користувача
    accessToken: AccessToken, // Авторизація API Gateway
    refreshToken: RefreshToken, // Отримання нових токенів
  };
}

API Gateway + Cognito Авторизація

Перевірка токену Cognito в API Gateway:

API Gateway автоматично перевіряє JWT токени від Cognito User Pools, коли налаштований як authorizer.

Виклик API з токеном (curl):

# Отримати токен з відповіді входу
TOKEN="eyJraWQiOiJ..."

# Викликати захищений API endpoint
curl https://api.example.com/users \
  -H "Authorization: Bearer $TOKEN"

Cognito Identity Pool для доступу AWS

Обмін токену Cognito на облікові дані AWS:

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) {
  // Отримати 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);

  // Отримати тимчасові облікові дані AWS
  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
}

// Використання облікових даних для доступу до 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

KMS керує ключами шифрування для шифрування даних в стані спокою та під час передачі.

   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  

Типи ключів:

  • AWS Managed Keys: Автоматична ротація ключів щороку
  • Customer Managed Keys (CMK): Повний контроль, ручна або автоматична ротація
  • AWS Owned Keys: Використовуються сервісами AWS, не видимі клієнтам

Шаблон Envelope Encryption

Шифрування даних з 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. Згенерувати ключ шифрування даних (DEK)
  const command = new GenerateDataKeyCommand({
    KeyId: keyId, // CMK ARN або alias
    KeySpec: 'AES_256',
  });
  const { Plaintext: plaintextKey, CiphertextBlob: encryptedKey } =
    await kmsClient.send(command);

  // 2. Зашифрувати дані з відкритим 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. Повернути зашифровані дані + зашифрований DEK + IV
  return {
    encryptedData: encrypted,
    encryptedKey: encryptedKey.toString('base64'),
    iv: iv.toString('base64'),
  };
}

async function decryptData(encryptedData, encryptedKey, iv) {
  // 1. Розшифрувати DEK за допомогою KMS
  const command = new DecryptCommand({
    CiphertextBlob: Buffer.from(encryptedKey, 'base64'),
  });
  const { Plaintext: plaintextKey } = await kmsClient.send(command);

  // 2. Розшифрувати дані з відкритим 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;
}

Увімкнути шифрування S3 bucket з KMS:

# Шифрування на стороні сервера з 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

Secrets Manager зберігає та автоматично ротує облікові дані бази даних, API ключі та інші секрети.

Зберегти секрет:

# Створити секрет
aws secretsmanager create-secret \
  --name prod/db/password \
  --description "Production database password" \
  --secret-string '{"username":"admin","password":"MySecureP@ssw0rd"}'

Отримати секрет в застосунку:

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);

  // Парсити JSON секрет
  const secret = JSON.parse(response.SecretString);
  return secret; // { username: 'admin', password: '...' }
}

// Використання для з'єднання з базою даних
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;
}

Автоматична ротація секретів

Увімкнути ротацію для бази даних RDS:

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

Lambda функція ротації (спрощено):

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

  switch (Step) {
    case 'createSecret':
      // Згенерувати новий пароль
      const newPassword = generateRandomPassword();
      await putSecretValue(SecretId, newPassword, 'AWSPENDING');
      break;

    case 'setSecret':
      // Оновити базу даних новим паролем
      const pending = await getSecretValue(SecretId, 'AWSPENDING');
      await updateDatabasePassword(pending);
      break;

    case 'testSecret':
      // Протестувати новий пароль
      const test = await getSecretValue(SecretId, 'AWSPENDING');
      await testDatabaseConnection(test);
      break;

    case 'finishSecret':
      // Позначити нову версію як поточну
      await finishSecretRotation(SecretId);
      break;
  }
};

AWS CloudTrail

Архітектура CloudTrail

CloudTrail логує всі виклики API для аудиту, відповідності вимогам та аналізу безпеки.

Ключові функції:

  • Записує виклики API з Console, CLI, SDK та сервісів
  • Доставляє логи в S3, CloudWatch Logs та EventBridge
  • Підтримує багаторегіональне та багатоакаунтне логування
  • Insights: Виявлення незвичайної активності API

Типи подій CloudTrail

Management Events:

  • Операції площини управління (CreateInstance, DeleteBucket)
  • Увімкнено за замовчуванням
  • Фільтрація тільки для читання або тільки для запису

Data Events:

  • Операції площини даних (GetObject, PutObject, виклики Lambda)
  • Вимкнено за замовчуванням (великий об'єм)
  • Налаштування на ресурс

Insights Events:

  • Виявляє незвичайні шаблони викликів API
  • Використовує машинне навчання
  • Потрібна платна функція

Запити до логів CloudTrail

Створити trail:

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

aws cloudtrail start-logging --name my-trail

# Увімкнути інтеграцію CloudWatch Logs
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

Запит останніх подій:

# Отримати останні виклики API
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteBucket \
  --max-results 10

# Запит за користувачем
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=alice

CloudWatch Insights запит (знайти невдалі дії):

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

Production найкращі практики

Найкращі практики Cognito

  1. MFA: Увімкнути багатофакторну автентифікацію для чутливих застосунків
  2. Політика паролів: Примусово застосовувати сильні паролі (мін. довжина, спеціальні символи)
  3. Термін дії токенів: Встановити відповідні терміни дії токенів (ID: 1год, Refresh: 30д)
  4. Розширена безпека: Увімкнути виявлення скомпрометованих облікових даних
  5. Власні домени: Використовувати власний домен для hosted UI (брендований досвід)

Найкращі практики KMS

  1. Ротація ключів: Увімкнути автоматичну ротацію ключів (щороку)
  2. Найменші привілеї: Надавати мінімальні дозволи KMS (kms:Decrypt тільки коли потрібно)
  3. Envelope Encryption: Використовувати для великих даних (ліміт >4KB)
  4. CloudTrail: Моніторити використання ключів з логами CloudTrail
  5. Політики ключів: Використовувати і політики ключів, і політики IAM для контролю доступу

Найкращі практики Secrets Manager

  1. Ротація: Увімкнути автоматичну ротацію для облікових даних бази даних
  2. Версіювання: Використовувати стадії версій (AWSCURRENT, AWSPENDING)
  3. Кешування: Кешувати секрети в застосунку (уникати повторних викликів API)
  4. Детальний доступ: Використовувати політики IAM для обмеження доступу до секретів
  5. Шифрування: Всі секрети зашифровані з KMS за замовчуванням

Найкращі практики CloudTrail

  1. Багаторегіональний: Увімкнути trail у всіх регіонах
  2. Валідація файлів логів: Увімкнути для виявлення підробки
  3. S3 Lifecycle: Архівувати старі логи в Glacier (оптимізація витрат)
  4. EventBridge: Тригерити сповіщення на критичних викликах API
  5. CloudWatch Alarms: Сповіщати про підозрілі шаблони активності

Моніторинг та усунення неполадок

Метрики Cognito:

  • SignInSuccesses / SignInFailures
  • TokenRefreshSuccesses
  • UserAuthentication

Метрики KMS:

  • NumberOfDecryptCalls
  • ThrottledRequests

CloudTrail:

  • Моніторити S3 bucket для доставки логів
  • Встановити CloudWatch Alarms на критичні події (використання Root облікового запису, невдалі входи в Console)

Поради для іспиту

Ключові концепції:

  1. Cognito User Pool = Автентифікація (вхід), Identity Pool = Авторизація (облікові дані AWS)
  2. KMS шифрує дані ≤4KB безпосередньо, використовувати envelope encryption для більших даних
  3. Secrets Manager авто-ротує секрети, Parameter Store (SSM) не робить цього
  4. CloudTrail логує виклики API, CloudWatch логує логи застосунків
  5. CMK = Customer Master Key (ніколи не залишає KMS), DEK = Data Encryption Key (шифрує дані)

Поширені сценарії:

  • "Автентифікувати користувачів мобільного застосунку" → Cognito User Pools
  • "Надати мобільному застосунку доступ до S3" → Cognito Identity Pools
  • "Зашифрувати облікові дані бази даних" → Secrets Manager (з KMS)
  • "Автоматично ротувати пароль бази даних" → Ротація Secrets Manager
  • "Аудит хто видалив S3 bucket" → CloudTrail
  • "Виявити скомпрометовані облікові дані" → Cognito Advanced Security

Висновок

Сервіси безпеки AWS надають комплексний захист для автентифікації, шифрування, керування секретами та аудиту логів. Cognito спрощує автентифікацію користувачів з вбудованою федерацією, KMS керує ключами шифрування з шаблонами envelope encryption, Secrets Manager автоматизує ротацію облікових даних, а CloudTrail надає повні аудиторські сліди API.

Обирайте Cognito для автентифікації користувачів, KMS для керування ключами шифрування, Secrets Manager для ротації облікових даних та CloudTrail для моніторингу відповідності вимогам та безпеки. Розуміння потоків автентифікації, шаблонів шифрування та аудиту логів є важливим як для production безпеки, так і для іспиту AWS Certified Developer Associate.


Часті запитання

П: Чим відрізняються Cognito User Pools від Identity Pools?

User Pools забезпечують автентифікацію користувачів з реєстрацією, входом, MFA та федерацією, видаючи JWT токени. Identity Pools забезпечують авторизацію, обмінюючи токени (від User Pools або соціальних) на тимчасові AWS облікові дані через STS AssumeRole. Використовуйте User Pools для входу користувачів, Identity Pools для доступу до AWS ресурсів, як S3.

П: Як працює KMS envelope encryption?

Envelope encryption шифрує дані за допомогою Data Encryption Key (DEK), потім шифрує DEK за допомогою Customer Master Key (CMK). CMK ніколи не залишає KMS; тільки зашифрований DEK зберігається з даними. Для розшифрування: KMS розшифровує DEK використовуючи CMK, застосунок розшифровує дані за допомогою DEK. Це обмежує мережеві дані до невеликих ключів.

П: Чим відрізняється Secrets Manager від Parameter Store?

Secrets Manager автоматизує ротацію секретів з вбудованими функціями Lambda для RDS, Redshift, DocumentDB та створює унікальні секрети. Parameter Store (SSM) зберігає конфігурацію/секрети без вбудованої ротації, але дешевший (безкоштовний для стандартних параметрів). Використовуйте Secrets Manager для облікових даних бази даних з автоматичною ротацією, Parameter Store для конфігурацій застосунку.

П: Що реєструє CloudTrail?

CloudTrail реєструє всі виклики AWS API з деталями: хто (userIdentity), що (eventName), коли (eventTime), звідки (sourceIPAddress) та результат (errorCode). Створює аудиторський слід для безпеки, відповідності вимогам та усунення несправностей. Увімкніть багаторегіональні сліди з доставкою логів в S3, CloudWatch Logs для моніторингу та SNS для сповіщень.

П: Як працює федерація Cognito з SAML/OIDC?

Cognito User Pools підтримує федерацію з корпоративними IdP (SAML 2.0) та соціальними провайдерами (OAuth 2.0/OIDC). Налаштуйте федерацію провайдера з метаданими; користувачі входять через зовнішній IdP; Cognito створює або пов'язує облікові записи користувачів, видає JWT токени. Зіставте атрибути IdP на атрибути User Pool для персоналізації.

П: Що таке KMS key policies проти IAM policies?

Key policies - це основний метод контролю доступу для CMK, прив'язаний до ключа. IAM policies додатково надають дозволи користувачам/ролям. Обидва мають оцінюватися до дозволу. Використовуйте key policies для контролю на рівні ключа (хто може використовувати/керувати), IAM policies для дозволів на рівні користувачів/ролей. Key policies завжди потрібні; IAM policies опціональні.

П: Як працює автоматична ротація Secrets Manager?

Ротація використовує функцію Lambda для оновлення секрету та облікового даного цілі. AWS надає шаблони для RDS/Redshift/DocumentDB. Під час ротації: Lambda створює новий секрет, оновлює базу даних, тестує з'єднання, позначає як AWSCURRENT. Попередня версія стає AWSPREVIOUS для відкочування. Налаштуйте автоматичну ротацію з інтервалом; Secrets Manager викликає Lambda за розкладом.