AWS IAM — глубоко
IAM — единственная стена между атакующим и твоей инфрой в AWS. 70% инцидентов в облаке — IAM-misconfig. Это must-master.
Сущности
- User — для человека (или legacy сервиса с access keys)
- Group — собирает users. Дают права группе, не каждому отдельно
- Role — временная identity. Для AWS-сервисов, cross-account, OIDC. Используй везде где можно вместо access keys.
- Policy — JSON документ с разрешениями. Прикрепляется к user/group/role
- Identity Provider — внешний (Google, Okta, GitHub OIDC)
Структура 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
Allow— разрешитьDeny— запретить. Deny всегда выигрывает у Allow.
Action
Wildcards: s3:Get*. Минимальные — точечно.
Resource
ARN формата arn:aws:<service>:<region>:<account>:<resource>.
Condition — секрет мастерства
Через conditions ты делаешь policy безопасной без перегиба:
aws:MultiFactorAuthPresent— требуй MFAaws:RequestedRegion— только в твоих регионахaws:SourceIp— только с офисных IPaws:PrincipalTag— ABAC (attribute-based)aws:SourceVpc— только из конкретного VPCaws:CurrentTime— временные ограничения
Типы 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 вычисляет разрешение
- По умолчанию — deny
- Если есть явный Deny где-либо — финал, deny
- SCP должен разрешать (если есть)
- Resource-based policy ИЛИ identity policy должны allow
- Permissions boundary должен allow (если есть)
- 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+), проще в настройке.
Типичные ошибки
- ❌ Использовать root account для daily работы
- ❌ Без MFA на root и admin аккаунтах
- ❌ AdministratorAccess по умолчанию
- ❌ Access keys в коде (часто остаются в git history после удаления)
- ❌ Wildcard
"Resource": "*"для опасных actions - ❌ Все в одном AWS account
- ❌ Не включён CloudTrail
- ❌ S3 buckets с public access
Инструменты аудита IAM
- IAM Access Analyzer — публично доступные ресурсы, unused permissions
- IAM Last Accessed — какие действия использовались за период
- Prowler — open source compliance scanner
- Steampipe — SQL поверх IAM API
- CloudSplaining — анализ overly permissive policies
- pmapper — поиск privilege escalation путей
Best practices чек-лист
- ☐ Root account только для billing, с MFA на железном ключе
- ☐ Multi-account через Organizations
- ☐ IAM Identity Center (SSO) для людей
- ☐ Roles вместо users везде где можно
- ☐ OIDC для CI/CD (никаких long-lived keys)
- ☐ IRSA/Pod Identity для EKS workloads
- ☐ MFA через Condition для чувствительных действий
- ☐ Permissions boundary для dev-доступа
- ☐ SCPs на уровне Organization
- ☐ Access Analyzer регулярно проверяется
- ☐ CloudTrail включён, логи в S3 в logging account
- ☐ Регулярный audit unused permissions