Бессерверная структура, по-видимому, включает в себя собственные интеграции AWS SSM :
functions:
myfunc:
# other config
environment:
TWITTER_ACCESS_TOKEN: ${ssm:myFunc}
Однако, как вы заметили, аналогичных функций в GCP нет, поэтому вам придется выполнить некоторыеоб этом самостоятельно.Возможно, вас заинтересуют некоторые из стратегий, изложенных в Секреты без сервера :
Вам нужны секреты?
Всегда важно спросить - действительно ли они мне нужны?секреты?Не могли бы вы использовать облачный провайдер IAM (или даже кросс-облачный OIDC ) вместо введения секретов в мое приложение?По возможности старайтесь использовать решение IAM, предоставляемое различными облаками.Очевидно, что есть еще несколько случаев, когда требуется секрет.
Зашифрованные переменные среды
Перед запуском функции вы шифруете секреты открытого текста локально в зашифрованный текст (зашифрованные строки).Вот пример с gcloud, но вы также можете использовать API или другие инструменты, такие как HashiCorp Vault :
$ gcloud kms encrypt \
--ciphertext-file=- \
--plaintext-file=/path/to/my/secret \
--key=my-kms-key \
--key-ring=my-kms-keyring \
--location=us-east4 \
| base64
Это выведет зашифрованную строку в кодировке base64, которую вы затем сохранитев вашем config.js
:
CiQAePa3VBJLbunLSqIJT+RS4nYiKdIaW6U69Y...
При запуске настройте ваше приложение на:
- Base64, декодируйте строку
- Расшифруйте зашифрованный текст с помощью Cloud KMS
- Сохраняйте открытый текст в памяти до тех пор, пока вам необходим секрет
Я не уверен, какой язык (языки) вы используете, но вот пример nodejs.Вы можете найти гораздо больше примеров на GitHub по адресу sethvargo / secrets-in-serverless :
const cryptoKeyID = process.env.KMS_CRYPTO_KEY_ID;
const kms = require('@google-cloud/kms');
const client = new kms.v1.KeyManagementServiceClient();
let username;
client.decrypt({
name: cryptoKeyID,
ciphertext: process.env.DB_USER,
}).then(res => {
username = res[0].plaintext.toString().trim();
}).catch(err => {
console.error(err);
});
let password;
client.decrypt({
name: cryptoKeyID,
ciphertext: process.env.DB_PASS,
}).then(res => {
password = res[0].plaintext.toString().trim();
}).catch(err => {
console.error(err);
});
exports.F = (req, res) => {
res.send(`${username}:${password}`)
}
Облачное хранилище Google
Поскольку вы находитесь в GCP, другойВариант - использовать Google Cloud Storage (GCS) напрямую для хранения секретов.Это приведет к удалению вашей связи из безсерверной инфраструктуры.
Создание корзины:
$ gsutil mb gs://${GOOGLE_CLOUD_PROJECT}-serverless-secrets
Создание корзины частной:
$ gsutil defacl set private gs://${GOOGLE_CLOUD_PROJECT}-serverless-secrets
$ gsutil acl set -r private gs://${GOOGLE_CLOUD_PROJECT}-serverless-secrets
Запишите некоторые секреты в ведро.Несмотря на то, что они передаются в виде открытого текста, они зашифрованы в состоянии покоя, и доступ строго контролируется с помощью IAM.
$ gsutil -h 'Content-Type: application/json' cp - gs://${GOOGLE_CLOUD_PROJECT}-serverless-secrets/app1 <<< '{"username":"my-user", "password":"s3cr3t"}'
Затем создайте учетную запись службы, которая имеет разрешение на чтение изи назначьте эту служебную учетную запись своим функциям.
Наконец, прочитайте из корзины при запуске функции (на этот раз пример Python):
import os
import json
from google.cloud import storage
blob = storage.Client() \
.get_bucket(os.environ['STORAGE_BUCKET']) \
.get_blob('app1') \
.download_as_string()
parsed = json.loads(blob)
username = parsed['username']
password = parsed['password']
def F(request):
return f'{username}:{password}'