Я работаю над программой, которая будет работать в Google Cloud Run и имеет файлы, хранящиеся в хранилище Google Cloud.
Проблема, с которой я столкнулся, возникает при попытке создать подписанный URL-адрес для загрузки файла из облачного хранилища, которое обычно является частным. На моем локальном компьютере он работает нормально, но при работе в Cloud Run - нет.
Локально я использую учетную запись службы, которой назначена роль Администратора объекта хранения
. Я загружаю разрешения с помощью переменной среды с именем GOOGLE_APPLICATION_CREDENTIALS
, в которой указывается абсолютный путь к ключевому файлу .json, который я загрузил из облачной консоли.
В Cloud Run я назначил ту же роль учетной записи службы, от которой она работает. Однако, когда я пытаюсь подписать что-либо там, я получаю исключение:
java.io.IOException: код ошибки 403 при попытке подписать предоставленные байты: у вызывающего абонента нет разрешения
В моем коде я не явно выберите любую учетную запись службы, поскольку документация SDK убеждает меня в том, что это делается автоматически. В Cloud Run у меня нет установленной переменной GOOGLE_APPLICATION_CREDENTIALS
, потому что я думал, что это тоже делается автоматически.
Что меня смущает, так это то, что приложение, работающее в Cloud Run, может нормально выгружать файлы в Cloud Storage, поэтому я думаю, что у него откуда-то есть учетные данные.
Что я делаю не так?
TL; DR: Убедитесь, что учетная запись службы имеет разрешение iam.serviceAccounts.signBlob
.
После дальнейшего изучения метода, который я использовал для получения учетных данных в Cloud Run:
GoogleCredentials credentials = ComputeEngineCredentials.create();
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
Я прочитал javadoc для ComputeEngineCredentials
:
Учетные данные OAuth2, представляющие встроенную службу учетная запись для виртуальной машины Google Compute Engine. Получает токены доступа с сервера метаданных Google Compute Engine. Эти учетные данные используют IAM API для подписи данных. Смотрите знак (byte []) для более подробной информации.
После этого я прочитал javadoc для знака (byte [])
(выделено мной):
Подписывает предоставленные байты, используя закрытый ключ, связанный с учетной записью службы. Проект Compute Engine должен включать API управления идентификацией и доступом (IAM), а учетная запись службы экземпляра должна иметь разрешение iam.serviceAccounts.signBlob .
Таким образом, я создал новую роль только с iam.serviceAccounts.signBlob
и назначил его учетной записи службы, которую использует моя конфигурация Cloud Run. После этого проблема сразу исчезла (повторное развертывание не требуется)