Лаборатория кода Trusted Space

1. Обзор

Готовы ли вы повысить безопасность и конфиденциальность рабочих нагрузок, ускоренных на GPU? Эта практическая работа познакомит вас с возможностями Trusted Space — решения, обеспечивающего надежную изоляцию операторов и поддержку ускорения для ваших конфиденциальных рабочих нагрузок ИИ/МО.

Защита ценных данных, моделей и ключей сейчас важнее, чем когда-либо. Trusted Space предлагает решение, гарантируя, что ваши рабочие нагрузки будут работать в безопасной, доверенной среде, к которой даже оператор рабочих нагрузок не имеет доступа.

Вот что предлагает Trusted Space:

  • Повышенная конфиденциальность и безопасность: Trusted Space обеспечивает надежную среду выполнения, в которой ваши конфиденциальные активы (например, модели, ценные данные и ключи) остаются защищенными с помощью криптографического подтверждения.
  • Изоляция оператора: избавьтесь от беспокойства о вмешательстве оператора. Благодаря Trusted Space даже операторы вашей рабочей нагрузки не имеют доступа, что исключает возможность подключения по SSH, доступа к данным, установки программного обеспечения или изменения кода.
  • Поддержка ускорителей: Trusted Space разработан для бесперебойной работы с широким спектром аппаратных ускорителей, включая графические процессоры, такие как H100, A100, T4 и L4. Это гарантирует бесперебойную работу критически важных для производительности приложений ИИ/МО.

Чему вы научитесь

  • Ознакомьтесь с основными предложениями Trusted Space.
  • Узнайте, как развернуть и настроить среду Trusted Space для защиты ценных ресурсов вашей рабочей нагрузки ИИ/МИ.

Что вам понадобится

Защита запросов на генерацию конфиденциального кода с помощью Primus Company

В этой лабораторной работе мы попробуем себя в роли Primus, компании, которая уделяет первостепенное внимание конфиденциальности и безопасности данных своих сотрудников. Primus планирует внедрить модель генерации кода, чтобы помочь разработчикам в написании кода. Однако компания обеспокоена конфиденциальностью запросов, отправляемых сотрудниками, поскольку эти запросы часто содержат конфиденциальные фрагменты кода, внутреннюю информацию о проекте или проприетарные алгоритмы.

Почему компания Primus не доверяет Оператору?

Primus Corp работает на высококонкурентном рынке. Их кодовая база содержит ценную интеллектуальную собственность, включая запатентованные алгоритмы и конфиденциальные фрагменты кода, обеспечивающие конкурентное преимущество. Компания обеспокоена возможностью корпоративного шпионажа со стороны операторов рабочих нагрузок. Кроме того, запросы для сотрудников могут содержать конфиденциальные фрагменты кода, которые Primus Corp хочет защитить.

Чтобы решить эту проблему, Primus Corp будет использовать доверенное пространство (Trusted Space) для изоляции сервера вывода, на котором запущена модель для генерации кода. Вот как это работает:

  • Шифрование подсказок: перед отправкой подсказки на сервер вывода каждый сотрудник шифрует её с помощью ключа KMS, управляемого Primus Corp в Google Cloud. Это гарантирует, что расшифровать её и получить доступ к текстовой подсказке сможет только среда Trusted Space, где доступен соответствующий ключ дешифрования. В реальном сценарии шифрование на стороне клиента может быть реализовано с помощью доступных библиотек (например, tink ). В рамках этой лабораторной работы мы будем использовать этот пример клиентского приложения с конвертным шифрованием.
  • Изоляция оператора: Только сервер вывода, работающий в среде доверенного пространства, будет иметь доступ к ключу, используемому для шифрования, и сможет расшифровать запрос в доверенной среде. Доступ к ключу шифрования будет защищён пулом удостоверений рабочей нагрузки. Благодаря гарантиям изоляции доверенного пространства, даже оператор рабочей нагрузки не сможет получить доступ к ключу, используемому для шифрования, и расшифрованному контенту.
  • Безопасный вывод с использованием ускорителей: сервер вывода будет запущен на защищенной виртуальной машине (в рамках настройки доверенного пространства), что гарантирует защиту экземпляра рабочей нагрузки от вредоносного ПО или руткитов на уровне загрузки или ядра. Этот сервер расшифровывает запрос в среде доверенного пространства, выполняет вывод с использованием модели генерации кода и возвращает сгенерированный код сотруднику.

2. Настройте облачные ресурсы

Прежде чем начать

  • Клонируйте этот репозиторий с помощью приведенной ниже команды, чтобы получить необходимые скрипты, которые используются в рамках этой лабораторной работы.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • Измените каталог для этой лабораторной работы.
cd confidential-space/codelabs/trusted_space_codelab/scripts
  • Убедитесь, что вы установили необходимые переменные среды проекта, как показано ниже. Подробнее о настройке проекта GCP см. в этой лабораторной работе . Здесь вы можете узнать, как получить идентификатор проекта и чем он отличается от имени и номера проекта.
export PRIMUS_PROJECT_ID=<GCP project id of Primus>
gcloud services enable \
    cloudapis.googleapis.com \
    cloudresourcemanager.googleapis.com \
    cloudkms.googleapis.com \
    cloudshell.googleapis.com \
    container.googleapis.com \
    containerregistry.googleapis.com \
    iam.googleapis.com \
    confidentialcomputing.googleapis.com
  • Присвойте значения переменным для имён ресурсов, указанных выше, с помощью следующей команды. Эти переменные позволяют настраивать имена ресурсов по мере необходимости, а также использовать существующие ресурсы, если они уже созданы. (например, export PRIMUS_SERVICE_ACCOUNT='my-service-account' )
  1. Вы можете задать следующие переменные с существующими именами облачных ресурсов в проекте Primus. Если переменная задана, будет использоваться соответствующий существующий облачный ресурс из проекта Primus. Если переменная не задана, имя облачного ресурса будет сгенерировано на основе имени проекта, и будет создан новый облачный ресурс с этим именем. Ниже перечислены поддерживаемые переменные для имён ресурсов:

$PRIMUS_PROJECT_REGION

Регион, в рамках которого будут созданы региональные ресурсы для компании Primus.

$PRIMUS_SERVICE_LOCATION

Место, в котором будут создаваться ресурсы для компании Primus.

$PRIMUS_PROJECT_ZONE

Зона, в рамках которой будут созданы зональные ресурсы для компании Primus.

$PRIMUS_WORKLOAD_IDENTITY_POOL

Workload Identity Pool компании Primus для защиты облачных ресурсов.

$PRIMUS_WIP_PROVIDER

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

$PRIMUS_SERVICEACCOUNT

Сервисная учётная запись компании Primus, которую $PRIMUS_WORKLOAD_IDENTITY_POOL использует для доступа к защищённым ресурсам. На этом этапе у неё есть разрешение на просмотр данных клиентов, хранящихся в контейнере $PRIMUS_INPUT_STORAGE_BUCKET .

$PRIMUS_ENC_KEY

Ключ KMS используется для шифрования подсказок, предоставляемых сотрудниками компании Primus.

$PRIMUS_ENC_KEYRING

Связка ключей KMS, которая будет использоваться для создания ключа шифрования $PRIMUS_ENC_KEY для компании Primus.

$PRIMUS_ENC_KEYVERSION

Версия ключа шифрования KMS $PRIMUS_ENC_KEY . Значение по умолчанию — 1. Обновите это значение, если вы используете существующий ключ, который был ротирован ранее, и его версия была обновлена.

$PRIMUS_ARTIFACT_REPOSITORY

Репозиторий артефактов, куда будет помещён образ Docker рабочей нагрузки.

$PRIMUS_PROJECT_REPOSITORY_REGION

Регион для репозитория артефактов, в котором будет размещен опубликованный образ Docker рабочей нагрузки.

$WORKLOAD_VM

Имя рабочей нагрузки VM.

$WORKLOAD_IMAGE_NAME

Имя образа docker рабочей нагрузки.

$WORKLOAD_IMAGE_TAG

Тег изображения контейнера рабочей нагрузки.

$WORKLOAD_SERVICEACCOUNT

Учетная запись службы, имеющая разрешение на доступ к конфиденциальной виртуальной машине, которая запускает рабочую нагрузку.

$CLIENT_VM

Имя клиентской виртуальной машины, на которой будет запущено клиентское приложение сервера вывода.

$CLIENT_SERVICEACCOUNT

Учетная запись службы, используемая $CLIENT_VM

  • Для проекта $PRIMUS_PROJECT_ID вам потребуются роли администратора хранилища, администратора реестра артефактов, администратора Cloud KMS, администратора учётных записей служб и администратора пула удостоверений рабочей нагрузки IAM. Инструкции по назначению ролей IAM с помощью консоли GCP см. в этом руководстве .
  • Для $PRIMUS_PROJECT_ID запустите следующий скрипт , чтобы задать оставшимся именам переменных значения на основе идентификатора вашего проекта для имен ресурсов.
source config_env.sh

Настройка ресурсов компании Primus

На этом этапе вам необходимо настроить необходимые облачные ресурсы для Primus. Запустите следующий скрипт для настройки ресурсов для Primus. В ходе выполнения скрипта будут созданы следующие ресурсы:

  • Ключ шифрования ( $PRIMUS_ENC_KEY ) и брелок ( $PRIMUS_ENC_KEYRING ) в KMS для шифрования файла данных клиентов компании Primus.
  • Workload Identity Pool ( $PRIMUS_WORKLOAD_IDENTITY_POOL ) для проверки заявок на основе условий атрибутов, настроенных у его поставщика.
  • Учетная запись службы ( $PRIMUS_SERVICE_ACCOUNT ), прикрепленная к вышеупомянутому пулу удостоверений рабочей нагрузки ( $PRIMUS_WORKLOAD_IDENTITY_POOL ), имеет доступ для расшифровки данных с использованием ключа KMS (с использованием роли roles/cloudkms.cryptoKeyDecrypter ), шифрования данных с использованием ключа KMS (с использованием роли roles/cloudkms.cryptoKeyEncrypter ), чтения данных из контейнера облачного хранилища (с использованием роли objectViewer ) и подключения учетной записи службы к пулу удостоверений рабочей нагрузки (с использованием roles/iam.workloadIdentityUser ).
./setup_primus_resources.sh

3. Создать рабочую нагрузку

Создать учетную запись службы рабочей нагрузки

Теперь вам нужно создать учётную запись службы для рабочей нагрузки с необходимыми ролями и разрешениями. Запустите следующий скрипт , чтобы создать учётную запись службы рабочей нагрузки в проекте Primus. Эта учётная запись будет использоваться виртуальной машиной, на которой запущен сервер вывода.

Эта учетная запись службы рабочей нагрузки ( $WORKLOAD_SERVICEACCOUNT ) будет иметь следующие роли:

  • confidentialcomputing.workloadUser для получения токена подтверждения
  • logging.logWriter для записи журналов в Cloud Logging.
./create_workload_service_account.sh

Создать рабочую нагрузку

На этом этапе вы создадите образ Docker для рабочей нагрузки. Рабочая нагрузка будет разработана компанией Primus. В этой лабораторной работе используется код Python, использующий модель codegemma из общедоступного контейнера GCS (из Vertex Model Garden). Рабочая нагрузка загрузит модель codegemma и запустит сервер вывода, который будет обрабатывать запросы на генерацию кода от разработчиков Primus.

При запросе на генерацию кода рабочая нагрузка получит зашифрованный DEK вместе с зашифрованным запросом. Затем рабочая нагрузка выполнит вызов API KMS для расшифровки DEK и расшифрует запрос, используя этот DEK. Ключи шифрования (для DEK) будут защищены пулом удостоверений рабочей нагрузки, а доступ будет предоставлен рабочим нагрузкам, соответствующим условиям атрибутов. Эти условия атрибутов более подробно описаны в следующем разделе, посвященном авторизации рабочей нагрузки. Получив расшифрованный запрос, сервер вывода сгенерирует код, используя загруженную модель, и вернет ответ.

Запустите следующий скрипт для создания рабочей нагрузки, в которой выполняются следующие шаги:

  • Создать реестр артефактов ( $PRIMUS_ARTIFACT_REGISTRY ), принадлежащий Primus.
  • Обновите код рабочей нагрузки, указав необходимые имена ресурсов.
  • Создайте рабочую нагрузку сервера вывода и Dockerfile для сборки образа Docker с кодом рабочей нагрузки. Вот Dockerfile, используемый для этой лабораторной работы.
  • Создайте и опубликуйте образ Docker в реестре артефактов ( $PRIMUS_ARTIFACT_REGISTRY ), принадлежащем Primus.
  • Предоставьте пользователю $WORKLOAD_SERVICEACCOUNT разрешение на чтение $PRIMUS_ARTIFACT_REGISTRY . Это необходимо для того, чтобы контейнер рабочей нагрузки мог извлечь образ Docker рабочей нагрузки из реестра артефактов.
./create_workload.sh

Для справки, вот метод generate() рабочей нагрузки, который создается и используется в этой лабораторной работе (весь код рабочей нагрузки можно найти здесь ).

def generate():
  try:
    data = request.get_json()
    ciphertext = base64.b64decode(data["ciphertext"])
    wrapped_dek = base64.b64decode(data["wrapped_dek"])
    unwrapped_dek_response = kms_client.decrypt(
        request={"name": key_name, "ciphertext": wrapped_dek}
    )
    unwrapped_dek = unwrapped_dek_response.plaintext
    f = Fernet(unwrapped_dek)
    plaintext = f.decrypt(ciphertext)
    prompt = plaintext.decode("utf-8")
    tokens = tokenizer(prompt, return_tensors="pt")
    outputs = model.generate(**tokens, max_new_tokens=128)
    generated_code = tokenizer.decode(outputs[0])
    generated_code_bytes = generated_code.encode("utf-8")

    response = f.encrypt(generated_code_bytes)
    ciphertext_base64 = base64.b64encode(response).decode("utf-8")
    response = {"generated_code_ciphertext": ciphertext_base64}
    return jsonify(response)

  except (ValueError, TypeError, KeyError) as e:
    return jsonify({"error": str(e)}), 500

4. Авторизация и запуск рабочей нагрузки

Авторизовать рабочую нагрузку

Primus хочет разрешить рабочим нагрузкам доступ к своему ключу KMS, используемому для быстрого шифрования, на основе атрибутов следующих ресурсов:

  • Что : Код, который проверен
  • Где : Безопасная среда
  • Кто : Оператор, которому доверяют

Primus использует федерацию удостоверений рабочей нагрузки для реализации политики доступа на основе этих требований. Федерация удостоверений рабочей нагрузки позволяет задавать условия атрибутов . Эти условия ограничивают, какие удостоверения могут проходить аутентификацию в пуле удостоверений рабочей нагрузки (WIP) . Вы можете добавить службу проверки аттестации в WIP в качестве поставщика пула удостоверений рабочей нагрузки для предоставления измерений и реализации политики.

Пул удостоверений рабочей нагрузки был создан ранее на этапе настройки облачных ресурсов. Теперь Primus создаст нового поставщика пула удостоверений рабочей нагрузки OIDC. Указанное --attribute-condition разрешает доступ к контейнеру рабочей нагрузки. Для этого требуется:

  • Что : Последний $WORKLOAD_IMAGE_NAME загружен в репозиторий $PRIMUS_ARTIFACT_REPOSITORY .
  • Где : доверенная среда выполнения Confidential Space работает на полностью поддерживаемом образе виртуальной машины Confidential Space.
  • Кто : учетная запись сервиса Primus $WORKLOAD_SERVICE_ACCOUNT .
export WORKLOAD_IMAGE_DIGEST=$(gcloud artifacts docker images describe ${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG  --format="value(image_summary.digest)" --project ${PRIMUS_PROJECT_ID})
gcloud iam workload-identity-pools providers create-oidc $PRIMUS_WIP_PROVIDER \
  --location="global" \
  --project="$PRIMUS_PROJECT_ID" \
  --workload-identity-pool="$PRIMUS_WORKLOAD_IDENTITY_POOL" \
  --issuer-uri="https://confidentialcomputing.googleapis.com/" \
  --allowed-audiences="https://sts.googleapis.com" \
  --attribute-mapping="google.subject='assertion.sub'" \
  --attribute-condition="assertion.swname == 'HARDENED_SHIELDED' && assertion.hwmodel == 'GCP_SHIELDED_VM' && 
assertion.submods.container.image_digest == '${WORKLOAD_IMAGE_DIGEST}' &&
 assertion.submods.container.image_reference == '${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG' && 
'$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts"

Приведённая выше команда проверяет, выполняется ли рабочая нагрузка в доверенной среде, проверяя, что для параметра hwmodel задано значение «GCP_SHIELDED_VM», а для параметра swname — значение «HARDENED_SHIELDED». Кроме того, она включает в себя специфичные для рабочей нагрузки утверждения, такие как image_digest и image_reference , для повышения безопасности и обеспечения целостности выполняемой рабочей нагрузки.

Выполнить рабочую нагрузку

На этом этапе мы запустим рабочую нагрузку в виртуальной машине Trusted Space, к которой будет подключен ускоритель. Необходимые аргументы TEE передаются с помощью флага метаданных . Аргументы для контейнера рабочей нагрузки передаются с помощью части флага « tee-cmd ». Чтобы оснастить виртуальную машину рабочей нагрузкой графическим процессором Nvidia Tesla T4, мы используем флаг --accelerator=type=nvidia-tesla-t4,count=1 . Это позволит подключить один графический процессор к виртуальной машине. Также необходимо включить tee-install-gpu-driver=true в флаги метаданных, чтобы инициировать установку соответствующего драйвера графического процессора.

gcloud compute instances create ${WORKLOAD_VM} \
  --accelerator=type=nvidia-tesla-t4,count=1 \
  --machine-type=n1-standard-16 \
  --shielded-secure-boot \
  --image-project=conf-space-images-preview \
  --image=confidential-space-0-gpupreview-796705b \
  --zone=${PRIMUS_PROJECT_ZONE} \
  --maintenance-policy=TERMINATE \
  --boot-disk-size=40 \
  --scopes=cloud-platform \
  --service-account=${WORKLOAD_SERVICEACCOUNT}@${PRIMUS_PROJECT_ID}.iam.gserviceaccount.com \
  --metadata="^~^tee-image-reference=${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${PRIMUS_PROJECT_ID}/${PRIMUS_ARTIFACT_REPOSITORY}/${WORKLOAD_IMAGE_NAME}:${WORKLOAD_IMAGE_TAG}~tee-install-gpu-driver=true~tee-restart-policy=Never"

Выполнить запрос вывода

После успешного запуска сервера вывода рабочей нагрузки сотрудники компании Primus могут отправлять запросы на генерацию кода на сервер вывода.

В рамках этой лабораторной работы мы будем использовать следующий скрипт для настройки клиентского приложения, взаимодействующего с сервером вывода. Запустите этот скрипт для настройки клиентской виртуальной машины.

./setup_client.sh

Следующие шаги демонстрируют, как подключиться к клиентской виртуальной машине по SSH и запустить пример клиентского приложения в виртуальной среде Python. В этом примере приложения используется конвертное шифрование с библиотекой Fernet, но следует учитывать, что конкретные библиотеки шифрования можно адаптировать для различных сценариев использования.

gcloud compute ssh ${CLIENT_VM} --zone=${PRIMUS_PROJECT_ZONE}

Выполните следующие команды, чтобы активировать виртуальную среду Python в клиентской виртуальной машине и запустить клиентское приложение.

source venv/bin/activate
python3 inference_client.py

На выходе этого примера клиентского приложения будут показаны запросы на шифрование и открытый текст, а также соответствующие им зашифрованные и расшифрованные ответы.

5. Уборка

Вот скрипт, который можно использовать для очистки ресурсов, созданных в рамках этой лабораторной работы. В ходе очистки будут удалены следующие ресурсы:

  • Учетная запись сервиса Primus ( $PRIMUS_SERVICEACCOUNT ).
  • Ключ шифрования Primus ( $PRIMUS_ENC_KEY ).
  • Хранилище артефактов Примуса ( $PRIMUS_ARTIFACT_REPOSITORY ).
  • Пул удостоверений рабочей нагрузки Primus ( $PRIMUS_WORKLOAD_IDENTITY_POOL ) у его провайдера.
  • Учетная запись службы рабочей нагрузки Primus ( $WORKLOAD_SERVICEACCOUNT ).
  • Рабочая виртуальная машина ( $WORKLOAD_VM ) и клиентская виртуальная машина ( $CLIENT_VM ).
./cleanup.sh

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

  • Перейдите в консоль облачной платформы.
  • Выберите проект, который вы хотите закрыть, затем нажмите «Удалить» вверху: это запланирует удаление проекта.