IAM (Identity and Access Management) — это система AWS, которая отвечает на один вопрос: «кто и что может делать». Хотите прочитать файл из хранилища, запустить виртуальную машину, отправить сообщение в очередь — каждый раз AWS сверяется с IAM: а разрешено ли вам это вообще.
Звучит как скучная бюрократия, но именно тут происходит большинство аварий в облаке. Чаще всего ломают не сложным взломом, а потому что кому-то выдали слишком много прав или ключ доступа случайно попал в открытый репозиторий на GitHub. Поэтому потратить полчаса на понимание IAM выгоднее, чем потом разбирать инцидент. Давайте по порядку.
Пользователи против ролей
Это первое и главное различие, в котором новички путаются.
IAM-пользователь — это постоянная учётная запись. У неё есть имя и пара долгоживущих ключей доступа (access key и secret key) — что-то вроде логина и пароля, только для программ. Эти ключи не меняются сами по себе: создали один раз и пользуетесь, пока не отзовёте.
IAM-роль — это не учётная запись, а набор прав, который можно временно «надеть». Аналогия: пользователь — это ваш постоянный паспорт, а роль — гостевой бейдж на проходной, который выдают на пару часов и который сам по себе ничего не значит без вас. Процесс «надеть роль» называется assume role (принять роль), и в ответ вы получаете не вечные ключи, а временные креды (credentials), которые сами протухают через час-другой.
Ключевое правило, которое стоит запомнить сразу: для программ, серверов и автоматизации используют роли, а не пользователей с ключами.
Почему так:
- Ключи пользователя живут вечно, поэтому рано или поздно утекают — в код, в логи, в историю команд терминала, в скриншот. И утёкший ключ работает, пока кто-то вручную не спохватится.
- Креды роли выдаются на минуты-часы и обновляются автоматически. Даже если такой набор утечёт, через час он уже бесполезен.
На практике это выглядит так: ваше приложение крутится на виртуальной машине (EC2), в контейнере (ECS) или в Kubernetes (EKS). Вы привязываете к нему роль — и приложение получает права через неё. В коде и в конфигах нет ни одного ключа. Когда новичок спрашивает «а как моему сервису достучаться до хранилища S3?» — правильный ответ почти всегда «через роль», а не «положи ключи в переменные окружения».
Как устроены политики
Сами по себе права описываются политикой (policy) — это документ в формате JSON, перечисляющий, что можно, а что нельзя. Вот самая простая политика — «разрешить чтение объектов из конкретного бакета (контейнера хранилища) S3»:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
Разберём по полям:
Version— версия языка политик. Дата2012-10-17не значит, что документ устарел; это просто фиксированный идентификатор актуальной грамматики, его всегда пишут именно так.Effect—Allow(разрешить) илиDeny(запретить).Action— что именно:s3:GetObjectэто «скачать объект». У каждого сервиса свой список действий.Resource— над чем: здесь это ARN (Amazon Resource Name, глобальный адрес ресурса) конкретного бакета.
Политики бывают двух видов, и эта пара важна:
- Identity-based (политика на личности) — привязана к пользователю или роли. Читается как «этой роли можно читать из этого бакета».
- Resource-based (политика на ресурсе) — привязана к самому ресурсу. Читается наоборот: «этот бакет разрешает доступ такой-то роли или аккаунту». Такие политики нужны, например, чтобы открыть доступ из другого аккаунта или для сервисов вроде S3 и очередей SQS.
Как AWS принимает решение, можно свести к трём правилам:
- По умолчанию запрещено всё (это называется implicit deny, неявный запрет). Если ни одна политика явно не разрешила действие — оно запрещено.
- Доступ разрешается, только если есть явный
Allow. Внутри одного аккаунта хватает Allow в любой из политик — identity- или resource-, неважно в какой. А при доступе между аккаунтами разрешить должны обе стороны: и identity-политика на стороне того, кто обращается, и resource-политика на стороне ресурса. - Явный
Denyсильнее любогоAllow. Если хоть где-то стоит запрет на это действие — всё, доступа нет, и никакие разрешения это не перебьют.
Дополнительно у каждого правила можно задать блок Condition (условие), который ещё сильнее сужает доступ: «только если запрос пришёл из такой-то сети», «только с подтверждением через MFA (второй фактор)», «только с шифрованием».
Least privilege — минимум прав
Это главный принцип всей безопасности IAM: давать ровно столько прав, сколько нужно для задачи, и ни строчкой больше.
Самый частый дефект новичка — написать "Action": "*" и "Resource": "*", то есть «можно всё со всем». Так делают «чтобы не возиться» — и именно это потом превращается в инцидент: одна утёкшая такая роль открывает злоумышленнику весь аккаунт.
На практике least privilege — это итеративный процесс, а не разовая настройка:
- Начните узко — дайте минимум, который точно нужен.
- Запустите, посмотрите, чего не хватает (AWS показывает отказы в логах, а специальные анализаторы доступа подсказывают, какие права реально используются).
- Добавьте недостающее. Повторяйте.
Да, это дольше, чем выдать всё сразу. Но «узко и по факту» — это та граница, которая отделяет нормальную работу от заголовка про очередную утечку данных.
STS и временные креды
За всеми временными кредами стоит отдельный сервис — STS (Security Token Service, сервис выдачи токенов безопасности). Когда кто-то «принимает роль», под капотом вызывается операция AssumeRole, и STS возвращает короткоживущий набор: access key, secret key и токен сессии. По умолчанию они живут час, максимум можно настроить до 12 часов.
Команда вручную выглядит так:
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/my-app-role \
--role-session-name demo-session
Самое полезное для новичка — понять, что на этом механизме построено почти всё:
- Роль виртуальной машины (instance role) незаметно дёргает STS за вас — SDK сам получает и обновляет креды, вам не надо ничего писать.
- В Kubernetes (EKS) то же самое делают механизмы IRSA или более новый Pod Identity — они выдают поду временные креды роли.
- Доступ между аккаунтами — это assume роли в чужом аккаунте.
- Вход через корпоративную учётку (федерация) — тоже выдача временных креды.
Как только в голове укладывается «креды временные, и берутся они через assume» — большинство вопросов «а откуда сервис вообще берёт доступ без ключей в коде» отпадает само.
Доступ между аккаунтами
В AWS аккаунты — это основная граница изоляции: по умолчанию из одного аккаунта в другой не достучаться никак. Когда такой доступ всё же нужен (например, сервис из аккаунта A должен читать данные в аккаунте B), его делают через роль, а не через общие ключи.
Схема такая:
- В аккаунте-владельце ресурса (B) заводят роль.
- К роли цепляют trust policy (политику доверия) — она говорит «эту роль разрешено принимать аккаунту A».
- К той же роли цепляют identity-политику с нужными правами (например, чтение бакета).
- Сервис из аккаунта A вызывает
AssumeRoleдля этой роли, получает временные креды и работает с ними.
Важно: между аккаунтами не передают общие ключи. Доверие настраивается декларативно через trust policy, а реальный доступ всегда идёт через временные креды.
Где это применяется
IAM — это слой «кто что может делать» поверх сетевого слоя «кто до кого вообще может достучаться». Вместе они дают полноценную защиту: минимальная сеть плюс минимальные права. Поэтому осваивать их стоит в паре.
Где вы столкнётесь с IAM сразу:
- Любой ваш сервис в облаке (виртуальные машины, бессерверные функции, контейнеры) получает доступ к другим сервисам через роль.
- Конвейеры доставки кода (CI/CD) тоже работают через роли, а не через зашитые ключи — это разбирается в принципах конвейера доставки.
- В Kubernetes доступ подов к облачным сервисам настраивается через роли — см. деплой и конфигурацию.
Типичные ошибки новичков, которых стоит избегать с первого дня:
- Класть долгоживущие ключи пользователя в код или переменные окружения вместо использования роли.
- Выдавать
"*"вActionилиResource«чтобы заработало», а потом забыть сузить. - Удивляться, что доступа нет, хотя
Allowесть — почти всегда виноват явныйDenyгде-то выше или забытый implicit deny (нигде не разрешили). - Хранить ключи в общем доступе для связи между аккаунтами вместо настройки роли с trust policy.
Что учить дальше: как именно хранят секреты и шифруют данные — в безопасности и наблюдаемости; как роли описываются в инфраструктуре-как-коде, чтобы не кликать в консоли руками — в основах IaC и Terraform; общий взгляд на надёжную архитектуру — в Well-Architected.