#Признаки неисправности и область применимости
Приложение получает от Object Storage ответ AccessDenied при загрузке или чтении конкретного объекта. Ошибку 403 нужно отделить от несуществующего ключа, неверной подписи, запрещённого метода, политики бакета и отсутствующих разрешений сервисного аккаунта.
#Почему это происходит
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Недостаточные полномочияУ сервисного аккаунта нет необходимых разрешений на конкретный ресурс. | Не удаётся List/Get/Put только в нужном бакете | Сверьте IAM и политику бакета. |
| Неверные ключи или подписьКлюч, адрес S3 или подпись запроса не соответствует настройкам. | Ошибки SignatureDoesNotMatch или AccessDenied после смены ключа | Проверьте активный ключ и регион/endpoint клиента. |
| Дополнительные условия доступаПолитика бакета или ограничения доступа к KMS могут запрещать операцию. | Ошибка только при обращении с конкретной сети или к зашифрованным объектам | Проверяйте точное действие без расширения прав. |
#Пошаговая диагностика и устранение
- Запишите конкретную S3-операциюВ логах приложения зафиксируйте время, HTTP-код, код ошибки S3, имя бакета и тип операции GetObject/PutObject/ListBucket без отправки ключей и содержимого файлов. Если ошибка возникла при чтении одного объекта, проверьте его точный ключ с учётом регистра.
- Проверьте конечную точкуВ настройках клиента S3 должен использоваться адрес Yandex Object Storage, соответствующий выбранному способу обращения, а не URL другого облака или произвольного прокси. Проверьте правильность схемы HTTPS и способа адресации бакета, не отключая проверку сертификата.
- Установите личность приложенияОпределите, какой именно сервисный аккаунт выпускает токен или статический ключ. После ротации ключа конфигурация могла указывать на старый идентификатор. Не выводите секретный ключ в журнал и не передавайте его в переписку; используйте хранилище секретов.
- Сверьте разрешение на нужную операциюВ консоли откройте Object Storage → нужный бакет → настройки доступа и IAM. Для чтения и записи требуются разные разрешения; роль на самом объекте «сервисный аккаунт» не равна доступу к бакету. Попросите администратора выдать минимальную необходимую роль, а не общий admin.
- Изучите запреты бакетаЕсли назначенная роль достаточна, проверьте политики бакета, запреты использования статических ключей, а для шифрованных объектов — доступ к ключу KMS. Запрет по IP или условию политики может переопределить разрешение IAM. Перед изменением сохраните политику.
- Выполните безопасную пробуС рабочей машины с уже настроенным AWS CLI выполните чтение метаданных одного разрешённого небольшого объекта, указав endpoint; это не скачивает файл и не изменяет данные. Не ставьте реквизиты в командную строку.
- Дополнительная команда по темеLinux · Терминал (Bash)КомандаПодставьте существующий бакет и известный ключ; требуется заранее безопасно настроенный профиль AWS CLI. Успех — метаданные; 403 — продолжайте проверку доступа.
aws --endpoint-url https://storage.yandexcloud.net s3api head-object --bucket MY_BUCKET --key path/test.txt
- Разделите ошибку приложения и доступЕсли проба от того же сервисного аккаунта успешна, проверьте в приложении фактический профиль, endpoint, время системы и библиотеку подписи. Если тест проходит под личным администратором, но не под приложением, разница именно в учётных данных/правах.
- Повторите одну исходную операциюПосле точечного исправления выполните тот же GetObject или PutObject на тестовом ключе, убедитесь в успехе и удалите только свой тестовый объект штатным инструментом, если он был создан. Проверьте, что публичный доступ к бакету не включился.
#Как проверить, что проблема исправлена
Операция приложения завершается без AccessDenied с теми же учётными данными, которыми реально работает сервис. Остальные объекты остаются закрытыми; бакет не переведён в общий публичный доступ.
#Если проблема осталась
Если ошибка сохраняется, сравните XML-код S3, идентификатор использованного ключа, политику бакета, KMS и статус сервиса. Не обходите проблему параметром публичного чтения; передайте в поддержку обезличенный request ID и время.