Настройка Object Storage Access Policies (IAM/Bucket Policies)

Избыточные права доступа к объектному хранилищу — типовая причина утечек и бесконечных согласований внутри команды. Мы настраиваем строгие политики доступа под ключ: инвентаризация, разграничение по ролям, закрытие публичных путей и передача регламентов вашим специалистам. Выдачу и проверку доступов ускоряем в разы, а лишние права убираем полностью.
Часто задаваемые вопросы

Избыточные права доступа: где ломаются IAM-политики S3

Права, выданные под задачу «на время», почти никогда не отзывают. Сервисному аккаунту добавляют s3:GetObject на весь бакет, чтобы разово выгрузить отчёт: отчёт уехал, задача закрыта — а правило осталось в политике. Через несколько релизов таких «временных» записей десятки, и уже никто не помнит, какая из них чему служит.

Обычный мониторинг этого не поймает: он смотрит на коды ответов, время отклика и доступность, а избыточный доступ не даёт ни ошибок, ни всплесков. Запросы валидные, ответы успешные, графики ровные — тревог нет, хотя данные давно читает тот, кому они не предназначены. Публичный доступ к объектам опасен именно этим: хранилище работает штатно, а отказ уже случился.

Ломается всё на трёх типовых местах. Подстановочный знак в Resource или Action — политика выглядит узкой по названию, но покрывает весь бакет. Отсутствие Condition по источнику запроса: правило не привязано ни к сети, ни к конкретной роли. И ACL на уровне отдельного объекта, который расширяет доступ вопреки политике бакета, если нигде не стоит явный запрет.

Лечится это не разовой чисткой, а режимом: принцип наименьших привилегий плюс регулярный аудит доступа к хранилищу — сверка выданных прав с теми, что реально используются по логам обращений. Разбираем, как это выстроить так, чтобы «временное» перестало становиться постоянным.

Что перестаёт ломаться после строгих политик доступа

Явный запрет в политике корзины перебивает любое разрешение, поэтому контур сначала закрывается целиком, а доступ выдаётся точечно. Политика на корзине отвечает за то, что можно делать с объектами: по префиксу, из каких сетей, только по защищённому каналу. IAM-правила отвечают за то, кому это доступно. Пока уровни смешаны, права висят на аккаунте, а не на роли.

Класс отказа Как возникал Что стало после политик
Доступ живёт после увольнения права на личном аккаунте роль исключена из группы — доступ закрыт
Данные уходят из закрытого контура флаг публичного доступа на объекте публичный доступ запрещён на уровне корзины
Чтение чужих префиксов одна широкая политика на всех доступ выдан по префиксу и роли

Выдача доступа становится операцией на минуты: роль с нужным набором прав описана как код в Terraform, её остаётся назначить сотруднику. Отзыв прав при увольнении — одно исключение из группы, закрываются и долгоживущие ключи, и временные токены. Смена роли сотрудника внутри команды перестаёт требовать новой заявки: права пересобираются при переводе.

Доля данных в закрытом контуре растёт не за счёт ручных проверок, а потому что публичный доступ запрещён на самой корзине и обойти его случайным флагом нельзя. Уходят совсем: чтение чужих префиксов, доступ после увольнения, объект в открытом доступе из-за ошибки в скрипте.

Способы разграничения доступа: сравнение вариантов

Разграничение доступа в объектном хранилище решается на четырёх уровнях — от IAM-политик провайдера до собственной проверки перед выдачей ссылки. Выбор зависит от того, кто запрашивает объект: внутренний сервис, внешний партнёр или браузер конечного пользователя.

Ни один уровень не закрывает задачу целиком. Правила провайдера не знают вашей бизнес-логики, а собственная проверка не спасает от обхода через прямой адрес. Поэтому уровни комбинируют: снизу жёсткая основа, сверху точечные исключения.

Вариант Когда подходит Ограничения
Правила провайдера (IAM) Сервисные учётные записи внутри платформы, доступ на чтение или запись целиком Нет контекста приложения, права раздаются широкими группами
Правила уровня бакета Публичный или партнёрский обмен, один набор условий на весь контейнер Гранулярность до отдельного объекта ограничена, изоляция достигается дроблением бакетов
Правила уровня объекта и временные ссылки на файлы Выдача файла конкретному пользователю на короткий срок, без раскрытия ключей Ссылку нельзя отозвать до истечения срока: при утечке она работает у любого
Собственный слой авторизации перед выдачей ссылки Роли, владельцы, арендаторы, аудит каждого обращения Дополнительный сервис в критическом пути — нужен запас по отказоустойчивости

Как выбрать уровень

Если правило описывается одним условием, держите его на стороне провайдера. Если решение зависит от данных в вашей базе — выносите проверку в собственный слой, а временную ссылку делайте короткоживущей.

Порядок внедрения: от инвентаризации до передачи

Начинаем с фактов, а не с шаблона: инвентаризация показывает, кто реально обращается к хранилищу — сервисы, аналитика, внешние подрядчики. Без этой карты схема ролей строится наугад, а переключение политик превращается в поиск отказавшего доступа по логам.

  1. Инвентаризация прав доступа. Выгружаем действующие bucket policy, IAM-роли, публичные ACL и активные ссылки на объекты, сверяем с логами обращений. На выходе — карта «кто, к какому бакету, какие операции» и список лишних разрешений.
  2. Схема ролей. Роли проектируем под функции — чтение аналитики, запись из сервиса, обмен с подрядчиком по отдельному префиксу, — а не под конкретных людей. У каждой роли минимальный набор действий и условие применения.
  3. Настройка политик. Ограничение по префиксам, условие на источник запроса, обязательное шифрование, запрет публичного доступа. Явный запрет перекрывает случайно выданные разрешения.
  4. Проверка на копии данных. Тестовый контур на обезличенной копии: прогоняем чтение, запись, удаление, генерацию ссылок. Отдельно — негативные проверки: доступ закрыт там, где должен быть закрыт.
  5. Перевод без простоя. Старые и новые политики работают параллельно, переключаем по сервисам с окном наблюдения по логам отказов. Каждый шаг откатывается возвратом предыдущей версии конфигурации.
  6. Регламент. Фиксируем, кто выдаёт доступ, на какой срок, как проходит ревью и что делать при увольнении или смене подрядчика. Правила хранятся в репозитории, изменения — через проверку.
  7. Передача. Документация, схемы ролей, конфигурации в репозитории и мониторинг отказов в доступе — чтобы команда дальше работала самостоятельно.

Что остаётся у вас на руках: конфигурации и регламенты

Мы передаём не архив с настройками, а рабочий контур доступа, который ваша команда сможет читать и менять без нас. Конфигурации IAM-политик и bucket policies лежат в репозитории рядом с инфраструктурным кодом: изменение проходит проверку и остаётся в истории — видно, кто и когда расширил права.

  • Матрица доступа — таблица «субъект → ресурс → действие → условие»: по ней видно, почему конкретный сервис или сотрудник имеет право на нужный префикс бакета и где граница его полномочий.
  • Схема ролей — какие роли существуют, чем отличаются, какие выдаются людям через федерацию, а какие — сервисам; отдельно помечены роли с правом менять сами политики.
  • Рабочие конфигурации — версионированные файлы политик с осмысленными именами и комментариями вместо выгрузки из консоли.
  • Регламент выдачи прав — порядок: заявка, согласование владельцем данных, срок действия, автоматический отзыв; для постоянных ролей — периодический пересмотр.
  • Документация по доступу — имена бакетов, точки входа, порядок ротации учётных данных и типовые ошибки при обращении.
  • Описание интеграций — какие системы обращаются к хранилищу, с какими правами и что произойдёт с ними при смене политики.
  • Процедура проверки — набор обращений, который должен проходить, и набор, который должен получать отказ.

На выходе остаётся управляемая система, а не разовая настройка: доступ новому подрядчику выдаётся по регламенту, а при разборе инцидента есть журнал изменений и понятная точка отката.

Кейс: как закрыли публичный доступ к объектному хранилищу

Что было до изменений

Аудит начали с инвентаризации: прошли по всем бакетам во всех аккаунтах и сверили bucket policy, ACL и настройки блокировки публичного доступа. Результат — 17% бакетов отдавали объекты анонимно: часть открыли под быстрый запуск и не закрыли, часть — когда подрядчикам выдавали ссылки «на время». Отдельная беда — наследование: правка политики одного бакета незаметно открывала соседние, и в S3-совместимом хранилище MinIO это ловилось только ручной сверкой.

Процессы добавляли своё. Права выдавались через тикеты: 2-3 дня от заявки до рабочего доступа, а отзыв при увольнении затягивался до недели — ключи всё это время оставались активными. Поддержка получала несколько десятков обращений в месяц только по доступам, и половина — «дайте то же, что у коллеги».

Что изменили и что получили

Публичность закрыли на двух уровнях: на аккаунте включили блокировку публичных политик, а для сервисов с реальной внешней аудиторией оставили точечные условия — явный список источников и короткий срок жизни ссылок. Права перевели на роли с атрибутами: доступ определяется тегами пользователя и бакета, а не ручным перечислением. Новая команда получает нужный набор автоматически, при смене роли старые разрешения снимаются вместе с тегом.

Выдачу сделали самообслуживанием через каталог ролей. Метрики после: доля анонимно доступных бакетов — ноль, полный аудит прав занимает один прогон скрипта вместо недели ручной сверки, обращения в поддержку по доступам сократились в пять раз.

Чем IAM-политики S3 отличаются от правил бакета

У объектного хранилища, например Amazon S3, два независимых уровня доступа. Политика IAM крепится к субъекту — пользователю, роли, сервисной учётной записи — и отвечает, что этот субъект вправе делать: какие действия и над какими ресурсами. Правило бакета крепится к самому бакету, содержит указание на субъект и описывает обратную сторону — кто снаружи обращается к данным, включая другие аккаунты.

При пересечении модели складываются по логике: разрешено, если разрешено хотя бы где-то, запрещено — если запрещено хоть где-то. Разрешения объединяются, а у явного запрета высший приоритет: один Deny в IAM-политике или в правиле бакета перекрывает любое число Allow, в том числе выданных через группу. Это и есть приоритет запрета — барьер, который не обходится добавлением нового разрешения.

Отсюда практическое разделение. Внутри одного аккаунта хватает ролей IAM: команды и внутренние сервисы получают доступ через роль, а не через статичные ключи. Правило бакета нужно там, где обращение идёт извне — партнёрский аккаунт, внешний сервис, раздача статики. В смешанной схеме ограничения уровня организации работают верхней границей, которую не расширит ни одна из моделей.

Настраиваем от запретов: сначала закрываем публичный доступ и выгрузку без шифрования канала, затем добавляем разрешения по префиксам и ролям. Разбор отказа идёт в том же порядке — IAM, правило бакета, ограничения организации; чаще всего доступ блокирует не отсутствующий Allow, а явный Deny в одном из слоёв.

Технические сомнения по разграничению доступа

Сомнения по разграничению доступа обычно касаются не самой политики, а того, как она уживётся с уже работающими интеграциями и что произойдёт при ошибке в правилах. Ниже — пять технических вопросов, которые задают чаще всего перед стартом.

Не сломает ли новая IAM-политика действующие интеграции?

Сначала снимаем текущие обращения и собираем карту: кто к каким префиксам ходит. Затем выдаём явные разрешения и включаем запрет по умолчанию — сервис, не попавший в карту, отваливается на проверке, а не в проде.

Можно ли выдать доступ к отдельным объектам, а не ко всему хранилищу?

Можно: политика описывает и префиксы, и конкретные ключи. Для точечной выдачи разрешаем один объект, для выборок — префикс с условием по имени. Подрядчик получает ровно те файлы, которые нужны.

Как давать доступ внешним подрядчикам, чтобы не раздавать общий ключ?

Внешним выдаём отдельного пользователя или роль с ограничением по сроку и диапазону адресов. Доступ отзывается одной правкой, а история обращений остаётся в логах.

Как убедиться, что правила работают именно так, как задумано?

После применения прогоняем сценарии: служебные ключи, ключи подрядчика, анонимный запрос, запрос к соседнему префиксу. Ожидаемый ответ — разрешено или отказ — фиксируем, чтобы регресс ловился при следующем изменении.

Что будет с данными, если правило отзовёт нужные права?

Данные не пострадают: меняется только ответ на запрос. Откат — возврат предыдущей версии политики, это минуты, без повторной выгрузки и заливки объектов.

Обсудим задачу: разграничение доступа к хранилищу

Оценка работ по доступу к хранилищу строится не на общем описании, а на фактическом состоянии политик. Пока не видно, кто и через какую роль читает данные сегодня, любые сроки будут гаданием — поэтому просим прислать несколько артефактов, и на их основе собираем план:

  • выгрузку действующих правил: bucket-политики, IAM-политики ролей и пользователей, а также ACL, если они ещё применяются;
  • карту хранилищ: бакеты, их назначение, какие наборы данных и насколько чувствительные в них лежат;
  • перечень сервисов и приложений с указанием ролей, под которыми они обращаются к хранилищу, включая внешние интеграции;
  • требования по разграничению: кому и к какому префиксу нужен доступ, где важны ограничения по сети, времени или источнику запроса;
  • настройки логирования обращений: куда пишутся события доступа и как долго хранятся;
  • ограничения на вашей стороне: окна обслуживания, регламент согласования правок, кто подтверждает изменения в проде.

В ответ возвращаемся с планом внедрения: схема наследования доступов, разделение по ролям под реальные задачи сервисов, готовые черновики политик рядом с конфигурацией сервиса и порядок выката с точками отката.

Первый шаг занимает немного и сразу даёт результат:

  • Инвентаризация: сводим все правила в одну таблицу «кто — что — откуда».
  • Фиксация избыточных доступов и мест, где права шире необходимого.
  • Настройка логирования и тестового стенда, где правки проверяются без риска для прода.
  • Передача плана внедрения и согласование порядка выката.

Опишите задачу и приложите то, что есть под рукой, — вернёмся с оценкой и планом.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142