AWS IAM — глубоко

IAM — единственная стена между атакующим и твоей инфрой в AWS. 70% инцидентов в облаке — IAM-misconfig. Это must-master.

Сущности

Структура policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadOnlyToPrefix",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/data/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": "eu-west-1"
        },
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        },
        "IpAddress": {
          "aws:SourceIp": "203.0.113.0/24"
        }
      }
    }
  ]
}

Effect

Action

Wildcards: s3:Get*. Минимальные — точечно.

Resource

ARN формата arn:aws:<service>:<region>:<account>:<resource>.

Condition — секрет мастерства

Через conditions ты делаешь policy безопасной без перегиба:

Типы policies

ТипГде
Managed (AWS)AmazonS3FullAccess и т.д. — широкие, для тестов
Customer managedТвои policies, прикрепляются к разным сущностям
InlineВстроены в одну сущность. Когда policy уникальна для неё
Resource-basedНа ресурсе (S3 bucket policy, KMS key policy). Cross-account доступ
SCP (Service Control Policy)На OU/account в Organizations. Граница максимума
Permissions boundaryГраница для конкретного user/role
Session policyНа время одной сессии (AssumeRole)

Как AWS вычисляет разрешение

  1. По умолчанию — deny
  2. Если есть явный Deny где-либо — финал, deny
  3. SCP должен разрешать (если есть)
  4. Resource-based policy ИЛИ identity policy должны allow
  5. Permissions boundary должен allow (если есть)
  6. Session policy должен allow (если есть)

OIDC — must для CI/CD

Старая модель: создать IAM user, выпустить access key, положить в GitHub Secret. Антипаттерн.

Современная: GitHub Actions → OIDC → AWS даёт временные credentials.

# Trust policy для роли
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::123456789:oidc-provider/token.actions.githubusercontent.com"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
      },
      "StringLike": {
        "token.actions.githubusercontent.com:sub": "repo:myorg/myrepo:ref:refs/heads/main"
      }
    }
  }]
}
# GitHub Actions использует роль
permissions:
  id-token: write
  contents: read

steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789:role/gha-deploy
      aws-region: eu-west-1

IRSA — IAM Roles for Service Accounts (EKS)

В K8s pod получает AWS credentials через ServiceAccount, привязанный к IAM Role. Никаких credentials в pod.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: api-sa
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/api-role

EKS Pod Identity — новая альтернатива (2023+), проще в настройке.

Типичные ошибки

Инструменты аудита IAM

Best practices чек-лист