Синхронно загружать секреты в HTTP-функцию Google Cloud (NodeJS) - PullRequest
0 голосов
/ 11 июля 2019

У меня есть облачная функция Google, которая предоставляет конечную точку API входа в систему.Функция подписывает JWT с помощью закрытого ключа.

Теперь при развертывании функции мне нужно безопасно загрузить закрытый ключ, используемый для подписи JWT.Конечно, я не могу использовать переменные окружения или встраивать их в какую-либо часть кода, поскольку это видно каждому, кто может прочитать функцию в gcloud.

Варианты, которые я рассмотрел:

  1. Создайте выделенную служебную учетную запись для функции, плюс корзину GCS, к которой имеет доступ только эта учетная запись службы, и сохраните секрет в виде простого текста.Когда функция загрузится, загрузите секреты (await loadMySecrets(...)) и продолжайте.

  2. Рекомендуемый способ: создать ключ KMS, зашифровать секреты этим ключом и загрузить зашифрованный текст вместе скод функции.Во время выполнения попросите KMS расшифровать ключ (await decryptSecret(...)).

Проблема в том, что, насколько я вижу, при загрузке функции HTTP весь процесс загрузки должен быть синхронным .

Ваша функция возвращает обработчик запроса, а затем GCF выполняет его.Нет возможности await Promise перед возвратом обработчика запросов, и GCF не поддерживает возврат Promises для функций HTTP.API GCS и KMS основаны на Promise, не поддерживается *Sync() вызовов.

Как другие справились с этой проблемой?Я не могу синхронно ждать разрешения моего Обещания (например, через sleep()), так как это заблокирует цикл событий Node.Я вынужден как-то предоставлять секреты синхронно или есть способ сделать это асинхронно, что хорошо работает с GCF?

Примечание: это простые функции Google Cloud, не Firebase.

Примечание 2: существует ядерная опция, которая заключается в переносе асинхронного аспекта в промежуточное программное обеспечение Express.Я действительно, действительно, не хочу этого делать, поскольку мне приходится оборачивать такие вещи, как cookie-parser и passport, которые ожидают, что секреты будут доступны при первом создании промежуточного программного обеспечения, в асинхронном промежуточном программном обеспечении, которое загружает мои секреты, а затем делегирует.Некрасиво и может повлиять на производительность.

1 Ответ

1 голос
/ 11 июля 2019

Вы можете сделать весь обработчик функций асинхронным (требуется узел 8 +):

const decrypt = async (ciphertext) => {
  result = await client.decrypt({
      name: cryptoKeyID,
      ciphertext: ciphertext,
  });
  return result.plaintext;
}

exports.F = async (req, res) => {
  const username = await decrypt(process.env.DB_USER);
  const password = await decrypt(process.env.DB_PASS);
  res.send(`${username}:${password}`)
}

Я видел вашу заметку о промежуточном программном обеспечении. Если вы отправите пример кода, я постараюсь обновить его, чтобы он лучше соответствовал.

...