Устранение ошибки Forbidden при работе от имени сервисного аккаунта
Описание проблемы
При работе от имени сервисного аккаунта возникают ошибки 403 Forbidden или Permission Denied.
Решение
Вероятно, выбранная роль назначена сервисному аккаунту на себя как на ресурс. В этом случае права касаются только самого аккаунта (кто может его видеть и изменять) и не дают ему доступа к ВМ, бакетам и другим ресурсам — из-за этого возникает ошибка доступа.
Чтобы исправить ошибку, нужно выдать сервисному аккаунту права на облако или каталог. Для этого используйте инструкцию из следующего раздела.
Назначение роли на ресурс
Права доступа наследуются от родительского ресурса к дочерним. Например, если сервисному аккаунту назначить роль на облако, этот сервисный аккаунт получит нужные разрешения на все ресурсы во всех каталогах этого облака.
Чтобы назначить роль на ресурс, нужна роль admin или service-name.admin, где service-name— название сервиса, на ресурс которого назначается роль.
Узнайте, на какие ресурсы можно назначать роли.
Чтобы назначить роль на ресурс:
Роли сервисному аккаунту назначаются так же, как пользовательскому аккаунту.
Чтобы назначить сервисному аккаунту роль на облако или каталог:
- В консоли управления
на панели сверху нажмите или и выберите облако или каталог. - Перейдите на вкладку Права доступа.
- Нажмите кнопку Настроить доступ.
- В открывшемся окне выберите раздел Сервисные аккаунты.
- Выберите нужный сервисный аккаунт из списка или воспользуйтесь поиском.
- Нажмите кнопку
Добавить роль и выберите роль из списка или воспользуйтесь поиском. - Нажмите кнопку Сохранить.
Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.
Чтобы назначить сервисному аккаунту роль на облако или каталог, выполните команду:
yc resource-manager <категория_ресурса> add-access-binding <имя_или_идентификатор_ресурса> \
--role <идентификатор_роли> \
--subject serviceAccount:<идентификатор_сервисного_аккаунта>
Где:
<категория_ресурса>—cloud, чтобы назначить роль на облако, илиfolder, чтобы назначить роль на каталог.<имя_или_идентификатор_ресурса>— имя или идентификатор ресурса, на который назначается роль.--role— идентификатор роли, напримерviewer.--subject serviceAccount— идентификатор сервисного аккаунта, которому назначается роль.
Например, чтобы назначить сервисному аккаунту роль viewer на каталог my-folder:
-
Выберите роль, которую хотите назначить сервисному аккаунту. Описание ролей можно найти в документации Yandex Identity and Access Management в справочнике ролей Yandex Cloud.
-
Узнайте идентификатор сервисного аккаунта по его имени:
yc iam service-account get my-robotРезультат:
id: aje6o61dvog2******** folder_id: b1gvmob95yys******** created_at: "2018-10-15T18:01:25Z" name: my-robotЕсли вы не знаете имя сервисного аккаунта, получите список сервисных аккаунтов с их идентификаторами:
yc iam service-account listРезультат:
+----------------------+------------------+-----------------+ | ID | NAME | DESCRIPTION | +----------------------+------------------+-----------------+ | aje6o61dvog2******** | my-robot | my description | +----------------------+------------------+-----------------+ -
Назначьте роль
viewerсервисному аккаунтуmy-robot, используя его идентификатор:yc resource-manager folder add-access-binding my-folder \ --role viewer \ --subject serviceAccount:aje6o61dvog2********
Если у вас еще нет Terraform, установите его и настройте провайдер Yandex Cloud.
-
Опишите в конфигурационном файле параметры ресурсов, которые необходимо создать:
Пример структуры конфигурационного файла:
resource "yandex_resourcemanager_folder_iam_member" "admin-account-iam" { folder_id = "<идентификатор_каталога>" role = "<роль>" member = "serviceAccount:<идентификатор_сервисного_аккаунта>" }Где:
folder_id— идентификатор каталога. Обязательный параметр.role— назначаемая роль. Описание ролей можно найти в документации Yandex Identity and Access Management в справочнике ролей Yandex Cloud. Обязательный параметр.member— идентификатор сервисного аккаунта, которому назначается роль. Указывается в видеserviceAccount:<идентификатор_сервисного_аккаунта>. Обязательный параметр.
Более подробную информацию о ресурсах, которые вы можете создать с помощью Terraform, см. в документации провайдера.
-
Проверьте корректность конфигурационных файлов.
-
В командной строке перейдите в папку, где вы создали конфигурационный файл.
-
Выполните проверку с помощью команды:
terraform plan
Если конфигурация описана верно, в терминале отобразится список создаваемых ресурсов и их параметров. Если в конфигурации есть ошибки, Terraform на них укажет.
-
-
Разверните облачные ресурсы.
-
Если в конфигурации нет ошибок, выполните команду:
terraform apply -
Подтвердите создание ресурсов: введите в терминал слово
yesи нажмите Enter.
После этого в указанном каталоге будут созданы все требуемые ресурсы. Проверить создание ресурса можно в консоли управления
или с помощью команды CLI:yc resource-manager folder list-access-bindings <имя_или_идентификатор_каталога> -
Чтобы назначить сервисному аккаунту роль на облако или каталог, воспользуйтесь методом REST API updateAccessBindings для ресурса Cloud или Folder:
-
Выберите роль, которую хотите назначить сервисному аккаунту. Описание ролей можно найти в документации Yandex Identity and Access Management в справочнике ролей Yandex Cloud.
-
Узнайте ID каталога с сервисными аккаунтами.
-
Получите IAM-токен для аутентификации в API Yandex Cloud.
-
Получите список сервисных аккаунтов в каталоге, чтобы узнать их идентификаторы:
export FOLDER_ID=b1gvmob95yys******** export IAM_TOKEN=CggaATEVAgA... curl \ --header "Authorization: Bearer ${IAM_TOKEN}" \ "https://iam.api.cloud.yandex.net/iam/v1/serviceAccounts?folderId=${FOLDER_ID}"Результат:
{ "serviceAccounts": [ { "id": "ajebqtreob2d********", "folderId": "b1gvmob95yys********", "createdAt": "2018-10-18T13:42:40Z", "name": "my-robot", "description": "my description" } ] } -
Сформируйте тело запроса, например в файле
body.json. В свойствеactionукажитеADD, в свойствеroleId— нужную роль, напримерeditor, а в свойствеsubject— типserviceAccountи идентификатор сервисного аккаунта:body.json:
{ "accessBindingDeltas": [{ "action": "ADD", "accessBinding": { "roleId": "editor", "subject": { "id": "ajebqtreob2d********", "type": "serviceAccount" } } }] } -
Назначьте роль сервисному аккаунту. Например, на каталог с идентификатором
b1gvmob95yys********:export FOLDER_ID=b1gvmob95yys******** export IAM_TOKEN=CggaAT******** curl \ --request POST \ --header "Content-Type: application/json" \ --header "Authorization: Bearer ${IAM_TOKEN}" \ --data '@body.json' \ "https://resource-manager.api.cloud.yandex.net/resource-manager/v1/folders/${FOLDER_ID}:updateAccessBindings"