Как аутентифицировать Google Cloud Build для вызова службы Cloud Run, требующей аутентификации?

У меня есть проект NodeJS, для которого я хочу запустить несколько модульных тестов во время сборки в Google Cloud Build. Эти модульные тесты требуют отправки запроса в службу Cloud Run, которая требует аутентификации, поэтому мне нужно предоставить токен с запросом. Для аутентификации я использую библиотеку npm google-auth-library и использую следующий код для получения токена:

const { GoogleAuth } = require('google-auth-library');

const auth = new GoogleAuth();
const targetAudience = new URL(url);
const client = await auth.getIdTokenClient(targetAudience);
const clientHeaders = await client.getRequestHeaders();
const token = clientHeaders['Authorization'];

Когда я запускаю это локально, у меня есть учетные данные учетной записи службы JSON, и я устанавливаю местоположение этого файла JSON как GOOGLE_APPLICATION_CREDENTIALS в среде. Но при запуске этого модульного теста в Cloud Build файл учетной записи службы не включается, поскольку он не фиксируется в репозитории git. Насколько я понимаю, это не требуется, когда он работает в Google Cloud, поскольку он должен проходить аутентификацию с помощью связанной службы. учетная запись, указанная триггером Google Cloud Build (имеющим, кстати, роль Cloud Run Invoker).

Однако, когда я проверяю client.idTokenProvider.email локально, я получаю адрес электронной почты учетной записи службы, но в Cloud Build значение default.

Это мой облачный yaml:

steps:
# Install the Cloud SQL proxy
- id: proxy-install
  name: node:16
  entrypoint: sh
  args:
    - '-c'
    - 'wget  https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O /workspace/cloud_sql_proxy &&  chmod +x /workspace/cloud_sql_proxy'
  waitFor: ['-']
# Install npm packages
- id: npm-install
  name: node:16
  entrypoint: npm
  args: ['install', '--include=dev']
  waitFor: ['proxy-install']
# Run the tests
- id: npm-test
  name: node:16
  entrypoint: sh
  args: 
    - '-c'
    - '(/workspace/cloud_sql_proxy -dir=/cloudsql -instances=[INSTANCE-NAME] & sleep 2) && (npm test)'
  env: 
    - 'NODE_ENV=production'
    - 'URL=[CLOUD_RUN_SERVICE_URL]'
  waitFor: ['npm-install']
timeout: 600s

Итак, как мне пройти аутентификацию в службе Cloud Run при отправке запроса во время Cloud Build?

Отредактируйте свой вопрос и включите свой Cloud Build YAML.

John Hanley 25.11.2022 09:24

Вы должны найти ответ в моей статье. Я говорю о похожей проблеме с Cloud Functions. В любом случае, встроенная айдентика Cloud Build не очень проста и последовательна medium.com/google-cloud/…

guillaume blaquiere 25.11.2022 14:19

Примечание: НЕ ИСПОЛЬЗУЙТЕ ключевой файл сервисной учетной записи (JSON), когда это возможно, это плохая практика. Моя статья также может помочь вам в этом.

guillaume blaquiere 25.11.2022 14:19

@guillaume, я уже просматривал вашу статью, но не смог найти эквивалент AuthorizedSession в модуле npm. Можно ли использовать API учетных данных служебной учетной записи с JavaScript вместо Python?

Sven 25.11.2022 14:43

Хммм, вы можете попробовать что-то "новое" (точно не знаю, но это довольно новое в клиентской библиотеке. Убедитесь, что у вас есть последняя версия библиотеки Google OAuth2). Выполните gcloud auth application-default login --impersonate-service-account=XXXX. Установите правильную учетную запись службы для олицетворения, убедитесь, что у вас есть (ваша учетная запись) разрешение на создание токена в учетной записи службы (создатель токена учетной записи службы роли) и используйте эти учетные данные в своем локальном коде. Java, Go и Python lib совместимы. Я не знаю, я не разработчик узлов!

guillaume blaquiere 25.11.2022 15:11

Спасибо! Используя олицетворение и некоторые изменения в коде javascript, я могу пройти аутентификацию в Cloud Build. Я напишу ответ с более подробной информацией для всех, кто заинтересован.

Sven 29.11.2022 09:22
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Благодаря подсказке @guillaume blaquiere об использовании олицетворения можно пройти аутентификацию в Cloud Run из Cloud Build. В Cloud Build учетная запись службы сборки должна иметь роль: Service Account Token Creator. Затем вы можете создать аутентифицированного клиента с помощью кода JavaScript:

const url = [CLOUD_RUN_SERVICE_URL]
const scopes = 'https://www.googleapis.com/auth/cloud-platform'
const auth = new GoogleAuth({
    scopes: scopes
});
const client = auth.getClient();

let targetClient = new Impersonated({
    sourceClient: client,
    targetPrincipal: [YOUR-SERVICE-ACCOUNT],
    lifetime: 30,
    delegates: [],
    targetScopes: [scopes]
});

const authClient = new IdTokenClient({
    targetAudience: url,
    idTokenProvider: targetClient
});

Если вы хотите запустить это локально, убедитесь, что ваша учетная запись также имеет роль Service Account Token Creator, и сначала выполните команду:

gcloud auth application-default login --impersonate-service-account=XXXX

Другие вопросы по теме