Codelab zu Trusted Space

1. Übersicht

Möchten Sie die Sicherheit und den Datenschutz Ihrer GPU-beschleunigten Arbeitslasten erhöhen? In diesem Codelab erfahren Sie mehr über die Funktionen von Trusted Space, einem Angebot, das eine starke Operatorisolation und Beschleunigerunterstützung für Ihre vertraulichen KI-/ML-Arbeitslasten bietet.

Der Schutz wertvoller Daten, Modelle und Schlüssel ist wichtiger denn je. Trusted Space bietet eine Lösung, indem es dafür sorgt, dass Ihre Arbeitslasten in einer sicheren, vertrauenswürdigen Umgebung ausgeführt werden, auf die nicht einmal der Arbeitslastoperator Zugriff hat.

Das bietet Trusted Space:

  • Verbesserter Datenschutz und erhöhte Sicherheit:Trusted Space bietet eine vertrauenswürdige Ausführungsumgebung, in der Ihre vertraulichen Assets (z.B. Modelle, wertvolle Daten und Schlüssel) durch kryptografische Beweise geschützt bleiben.
  • Operatorisolation:Sie müssen sich keine Sorgen mehr über Eingriffe durch den Operator machen. Mit Trusted Space hat nicht einmal der Arbeitslastoperator Zugriff. So kann er keine SSH-Verbindung herstellen, nicht auf Daten zugreifen, keine Software installieren und Ihren Code nicht manipulieren.
  • Beschleunigerunterstützung:Trusted Space ist so konzipiert, dass es nahtlos mit einer Vielzahl von Hardwarebeschleunigern funktioniert, darunter GPUs wie H100, A100, T4 und L4. So können Sie sicher sein, dass Ihre leistungskritischen KI-/ML-Anwendungen reibungslos ausgeführt werden.

Lerninhalte

  • Sie lernen die wichtigsten Angebote von Trusted Space kennen.
  • Sie erfahren, wie Sie eine Trusted Space-Umgebung bereitstellen und konfigurieren, um wertvolle Assets Ihrer KI-/ML-Arbeitslast zu schützen.

Voraussetzungen

Schutz vertraulicher Prompts zur Codegenerierung mit Primus Company

In diesem Codelab schlüpfen wir in die Rolle von Primus, einem Unternehmen, das Datenschutz und Sicherheit der Daten seiner Mitarbeiter in den Vordergrund stellt. Primus möchte ein Modell zur Codegenerierung bereitstellen, um seine Entwickler bei ihren Programmieraufgaben zu unterstützen. Das Unternehmen ist jedoch besorgt um den Schutz der Vertraulichkeit der von seinen Mitarbeitern eingereichten Prompts, da diese oft vertrauliche Code-Snippets, interne Projektdetails oder proprietäre Algorithmen enthalten.

Warum vertraut Primus dem Operator nicht?

Primus ist in einem hart umkämpften Markt tätig. Die Codebasis des Unternehmens enthält wertvolles geistiges Eigentum, darunter proprietäre Algorithmen und vertrauliche Code-Snippets, die einen Wettbewerbsvorteil bieten. Das Unternehmen befürchtet, dass Arbeitslastoperatoren Industriespionage betreiben könnten. Außerdem können Prompts von Mitarbeitern vertrauliche Codeabschnitte enthalten, die Primus schützen möchte.

Um diese Bedenken auszuräumen, nutzt Primus Trusted Space, um den Inferenzserver zu isolieren, auf dem das Modell zur Codegenerierung ausgeführt wird. So funktioniert es:

  • Promptverschlüsselung:Bevor ein Mitarbeiter einen Prompt an den Inferenzserver sendet, verschlüsselt er ihn mit einem KMS-Schlüssel, der von Primus in Google Cloud verwaltet wird. So kann nur die Trusted Space-Umgebung, in der der entsprechende Entschlüsselungsschlüssel verfügbar ist, den Prompt entschlüsseln und auf den Klartext-Prompt zugreifen. In der Praxis kann die clientseitige Verschlüsselung von den verfügbaren Bibliotheken (z.B. Tink) übernommen werden. Im Rahmen dieses Codelabs verwenden wir diese Beispiel-Clientanwendung mit Envelope-Verschlüsselung.
  • Operatorisolation: Nur der Inferenzserver, der in einer Trusted Space-Umgebung ausgeführt wird, hat Zugriff auf den für die Verschlüsselung verwendeten Schlüssel und kann den Prompt in einer vertrauenswürdigen Umgebung entschlüsseln. Der Zugriff auf den Verschlüsselungsschlüssel wird durch den Workload Identity-Pool geschützt. Aufgrund der Isolationsgarantien von Trusted Space kann nicht einmal der Arbeitslastoperator auf den für die Verschlüsselung verwendeten Schlüssel und die entschlüsselten Inhalte zugreifen.
  • Sichere Inferenz mit Beschleunigern: Der Inferenzserver wird auf einer Shielded VM gestartet (im Rahmen der Trusted Space-Einrichtung). So wird sichergestellt, dass die Arbeitslastinstanz nicht durch Malware oder Rootkits auf Boot- oder Kernel-Ebene manipuliert wurde. Dieser Server entschlüsselt den Prompt in der Trusted Space-Umgebung, führt die Inferenz mit dem Modell zur Codegenerierung aus und gibt den generierten Code an den Mitarbeiter zurück.

2. Cloud-Ressourcen einrichten

Hinweis

  • Klonen Sie dieses Repository mit dem folgenden Befehl, um die erforderlichen Skripts zu erhalten, die in diesem Codelab verwendet werden.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • Ändern Sie das Verzeichnis für dieses Codelab.
cd confidential-space/codelabs/trusted_space_codelab/scripts
  • Achten Sie darauf, dass Sie die erforderlichen Umgebungsvariablen für das Projekt wie unten gezeigt festgelegt haben. Weitere Informationen zum Einrichten eines GCP-Projekts finden Sie in diesem Codelab. Hier erfahren Sie, wie Sie die Projekt-ID abrufen und wie sie sich von Projektname und Projektnummer unterscheidet.
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
  • Weisen Sie den Variablen für die oben angegebenen Ressourcennamen mit dem folgenden Befehl Werte zu. Mit diesen Variablen können Sie die Ressourcennamen nach Bedarf anpassen und auch vorhandene Ressourcen verwenden, wenn sie bereits erstellt wurden. Beispiel: export PRIMUS_SERVICE_ACCOUNT='my-service-account'
  1. Sie können die folgenden Variablen mit vorhandenen Cloud-Ressourcennamen im Primus-Projekt festlegen. Wenn die Variable festgelegt ist, wird die entsprechende vorhandene Cloud-Ressource aus dem Primus-Projekt verwendet. Wenn die Variable nicht festgelegt ist, wird der Name der Cloud-Ressource aus dem Projektnamen generiert und eine neue Cloud-Ressource mit diesem Namen erstellt. Die folgenden Variablen werden für Ressourcennamen unterstützt:

$PRIMUS_PROJECT_REGION

Region, in der regionale Ressourcen für Primus erstellt werden.

$PRIMUS_SERVICE_LOCATION

Standort, an dem Ressourcen für Primus erstellt werden.

$PRIMUS_PROJECT_ZONE

Zone, in der zonale Ressourcen für Primus erstellt werden.

$PRIMUS_WORKLOAD_IDENTITY_POOL

Workload Identity-Pool von Primus zum Schutz der Cloud-Ressourcen.

$PRIMUS_WIP_PROVIDER

Workload Identity-Poolanbieter von Primus, der die Autorisierungsbedingung für Tokens enthält, die vom Attestation Verifier Service signiert wurden.

$PRIMUS_SERVICEACCOUNT

Dienstkonto von Primus, das von $PRIMUS_WORKLOAD_IDENTITY_POOL verwendet wird, um auf die geschützten Ressourcen zuzugreifen. In diesem Schritt hat es die Berechtigung, die Kundendaten einzusehen, die im Bucket $PRIMUS_INPUT_STORAGE_BUCKET gespeichert sind.

$PRIMUS_ENC_KEY

Der KMS-Schlüssel wird verwendet, um die von Mitarbeitern von Primus bereitgestellten Prompts zu verschlüsseln.

$PRIMUS_ENC_KEYRING

Der KMS-Schlüsselbund, der verwendet wird, um den Verschlüsselungsschlüssel $PRIMUS_ENC_KEY für Primus zu erstellen.

$PRIMUS_ENC_KEYVERSION

Die KMS-Schlüsselversion des Verschlüsselungsschlüssels $PRIMUS_ENC_KEY. Der Standardwert ist 1. Aktualisieren Sie diesen Wert, wenn Sie einen vorhandenen Schlüssel verwenden, der in der Vergangenheit rotiert wurde und dessen Version aktualisiert wurde.

$PRIMUS_ARTIFACT_REPOSITORY

Das Artefakt-Repository, in das das Docker-Image der Arbeitslast übertragen wird.

$PRIMUS_PROJECT_REPOSITORY_REGION

Die Region für das Artefakt-Repository, das das veröffentlichte Docker-Image der Arbeitslast enthält.

$WORKLOAD_VM

Name der Arbeitslast-VM.

$WORKLOAD_IMAGE_NAME

Name des Docker-Images der Arbeitslast.

$WORKLOAD_IMAGE_TAG

Tag des Container-Images der Arbeitslast.

$WORKLOAD_SERVICEACCOUNT

Das Dienstkonto, das die Berechtigung hat, auf die Confidential VM zuzugreifen, auf der die Arbeitslast ausgeführt wird.

$CLIENT_VM

Name der Client-VM, auf der die Clientanwendung des Inferenzservers ausgeführt wird.

$CLIENT_SERVICEACCOUNT

Das Dienstkonto, das von $CLIENT_VM verwendet wird.

  • Sie benötigen die Rollen „Storage Admin“, „Artifact Registry Administrator“, „Cloud KMS Admin“, „Service Account Admin“ und „IAM Workload Identity Pool Admin“ für das Projekt $PRIMUS_PROJECT_ID. In diesem Leitfaden erfahren Sie, wie Sie IAM-Rollen über die GCP Console zuweisen.
  • Führen Sie für $PRIMUS_PROJECT_ID das folgende Skript aus, um die verbleibenden Variablennamen auf Werte festzulegen, die auf Ihrer Projekt-ID für Ressourcennamen basieren.
source config_env.sh

Ressourcen für Primus einrichten

In diesem Schritt richten Sie die erforderlichen Cloud-Ressourcen für Primus ein. Führen Sie das folgende Skript aus, um die Ressourcen für Primus einzurichten. Im Rahmen der Skriptausführung werden die folgenden Ressourcen erstellt:

  • Verschlüsselungsschlüssel ($PRIMUS_ENC_KEY) und Schlüsselbund ($PRIMUS_ENC_KEYRING) in KMS zum Verschlüsseln der Kundendatei von Primus.
  • Workload Identity-Pool ($PRIMUS_WORKLOAD_IDENTITY_POOL) zum Validieren von Ansprüchen basierend auf Attributbedingungen, die unter dem Anbieter konfiguriert sind.
  • Das Dienstkonto ($PRIMUS_SERVICE_ACCOUNT), das an den oben genannten Workload Identity-Pool ($PRIMUS_WORKLOAD_IDENTITY_POOL) angehängt ist, hat Zugriff auf das Entschlüsseln von Daten mit dem KMS-Schlüssel (mit der Rolle roles/cloudkms.cryptoKeyDecrypter), das Verschlüsseln von Daten mit dem KMS-Schlüssel (mit der Rolle roles/cloudkms.cryptoKeyEncrypter), das Lesen von Daten aus dem Cloud Storage-Bucket (mit der Rolle objectViewer) und das Verbinden des Dienstkontos mit dem Workload Identity-Pool (mit der Rolle roles/iam.workloadIdentityUser).
./setup_primus_resources.sh

3. Arbeitslast erstellen

Dienstkonto für die Arbeitslast erstellen

Jetzt erstellen Sie ein Dienstkonto für die Arbeitslast mit den erforderlichen Rollen und Berechtigungen. Führen Sie das folgende Skript aus, um ein Dienstkonto für die Arbeitslast im Primus-Projekt zu erstellen. Dieses Dienstkonto wird von der VM verwendet, auf der der Inferenzserver ausgeführt wird.

Dieses Dienstkonto für die Arbeitslast ($WORKLOAD_SERVICEACCOUNT) hat die folgenden Rollen:

  • confidentialcomputing.workloadUser zum Abrufen eines Attestierungstokens
  • logging.logWriter zum Schreiben von Logs in Cloud Logging.
./create_workload_service_account.sh

Arbeitslast erstellen

In diesem Schritt erstellen Sie ein Docker-Image der Arbeitslast. Die Arbeitslast wird von Primus erstellt. Die in diesem Codelab verwendete Arbeitslast ist Python-Code, der das codegemma-Modell aus dem öffentlich verfügbaren GCS-Bucket (von Vertex Model Garden) verwendet. Die Arbeitslast lädt das Modell codegemma und startet den Inferenzserver, der die Anfragen zur Codegenerierung von den Entwicklern von Primus verarbeitet.

Bei der Anfrage zur Codegenerierung ruft die Arbeitslast den zusammengefassten DEK zusammen mit einem verschlüsselten Prompt ab. Anschließend ruft die Arbeitslast die KMS API auf, um den DEK zu entschlüsseln, und entschlüsselt dann den Prompt mit diesem DEK. Verschlüsselungsschlüssel (für DEK) werden über den Workload Identity-Pool geschützt und der Zugriff wird den Arbeitslasten gewährt, die die Attributbedingungen erfüllen. Diese Attributbedingungen werden im nächsten Abschnitt zur Autorisierung der Arbeitslast ausführlicher beschrieben. Sobald der Inferenzserver den entschlüsselten Prompt hat, generiert er den Code mit einem geladenen Modell und gibt die Antwort zurück.

Führen Sie das folgende Skript aus, um eine Arbeitslast zu erstellen, bei der die folgenden Schritte ausgeführt werden:

  • Erstellen Sie eine Artifact Registry($PRIMUS_ARTIFACT_REGISTRY), die Primus gehört.
  • Aktualisieren Sie den Arbeitslastcode mit den erforderlichen Ressourcennamen.
  • Erstellen Sie die Arbeitslast des Inferenzservers und erstellen Sie ein Dockerfile zum Erstellen eines Docker-Images des Arbeitslastcodes. Hier ist das Dockerfile, das für dieses Codelab verwendet wird.
  • Erstellen Sie das Docker-Image und veröffentlichen Sie es in der Artifact Registry ($PRIMUS_ARTIFACT_REGISTRY), die Primus gehört.
  • Gewähren Sie $WORKLOAD_SERVICEACCOUNT die Leseberechtigung für $PRIMUS_ARTIFACT_REGISTRY. Dies ist erforderlich, damit der Arbeitslastcontainer das Docker-Image der Arbeitslast aus der Artifact Registry abrufen kann.
./create_workload.sh

Hier ist die Methode `generate()` der Arbeitslast, die in diesem Codelab erstellt und verwendet wird (den vollständigen Arbeitslastcode finden Sie hier).

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. Arbeitslast autorisieren und ausführen

Arbeitslast autorisieren

Primus möchte Arbeitslasten autorisieren, auf den KMS-Schlüssel zuzugreifen, der für die Promptverschlüsselung verwendet wird. Die Autorisierung soll auf den Attributen der folgenden Ressourcen basieren:

  • Was: Code, der verifiziert wurde
  • Wo: Eine sichere Umgebung
  • Wer: Ein vertrauenswürdiger Operator

Primus verwendet die Workload Identity Federation, um eine Zugriffsrichtlinie basierend auf diesen Anforderungen zu erzwingen. Mit der Workload Identity Federation können Sie Attributbedingungen angeben. Diese Bedingungen schränken ein, welche Identitäten sich mit dem Workload Identity-Pool (WIP) authentifizieren können. Sie können den Attestation Verifier Service als Workload Identity-Poolanbieter zum WIP hinzufügen, um Messungen zu präsentieren und die Richtlinie zu erzwingen.

Der Workload Identity-Pool wurde bereits zuvor im Rahmen der Einrichtung der Cloud-Ressourcen erstellt. Jetzt erstellt Primus einen neuen OIDC-Workload Identity-Poolanbieter. Die angegebene --attribute-condition autorisiert den Zugriff auf den Arbeitslastcontainer. Dafür sind erforderlich:

  • Was: Das neueste $WORKLOAD_IMAGE_NAME, das in das Repository $PRIMUS_ARTIFACT_REPOSITORY hochgeladen wurde.
  • Wo: Die vertrauenswürdige Ausführungsumgebung von Confidential Space wird auf dem vollständig unterstützten Confidential Space-VM-Image ausgeführt.
  • Wer: Das Dienstkonto $WORKLOAD_SERVICE_ACCOUNT von Primus.
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"

Mit dem obigen Befehl wird geprüft, ob die Arbeitslast in einer Trusted Space-Umgebung ausgeführt wird. Dazu wird geprüft, ob hwmodel auf „GCP_SHIELDED_VM“ und swname auf „HARDENED_SHIELDED“ festgelegt ist. Außerdem enthält er arbeitslastspezifische Zusicherungen wie image_digest und image_reference, um die Sicherheit zu erhöhen und die Integrität der ausgeführten Arbeitslast zu gewährleisten.

Arbeitslast ausführen

In diesem Schritt führen wir die Arbeitslast in der Trusted Space-VM aus, an die ein Beschleuniger angehängt ist. Erforderliche TEE-Argumente werden mit dem Metadaten-Flag übergeben. Argumente für den Arbeitslastcontainer werden mit dem Teil "tee-cmd" des Flags übergeben. Um die Arbeitslast-VM mit einer Nvidia Tesla T4-GPU auszustatten, verwenden wir das Flag --accelerator=type=nvidia-tesla-t4,count=1. Dadurch wird eine GPU an die VM angehängt. Außerdem müssen wir tee-install-gpu-driver=true in die Metadaten-Flags aufnehmen, um die Installation des entsprechenden GPU-Treibers auszulösen.

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"

Inferenzabfrage ausführen

Nachdem der Inferenzserver der Arbeitslast erfolgreich gestartet wurde, können Mitarbeiter von Primus Anfragen zur Codegenerierung an den Inferenzserver senden.

Im Rahmen dieses Codelabs verwenden wir das folgende Skript, um die Clientanwendung einzurichten, die mit dem Inferenzserver interagiert. Führen Sie dieses Skript aus, um die Client-VM einzurichten.

./setup_client.sh

Die folgenden Schritte zeigen, wie Sie eine SSH-Verbindung zur Client-VM herstellen und eine Beispiel-Clientanwendung in einer virtuellen Python-Umgebung ausführen. In dieser Beispielanwendung wird die Envelope-Verschlüsselung mit der Fernet-Bibliothek verwendet. Die spezifischen Verschlüsselungsbibliotheken können jedoch an verschiedene Anwendungsfälle angepasst werden.

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

Führen Sie die folgenden Befehle aus, um die virtuelle Python-Umgebung in der Client-VM zu aktivieren und die Clientanwendung auszuführen.

source venv/bin/activate
python3 inference_client.py

Die Ausgabe dieser Beispiel-Clientanwendung zeigt die verschlüsselten und Klartext-Promptanfragen sowie die entsprechenden verschlüsselten und entschlüsselten Antworten.

5. Bereinigen

Hier ist das Skript, mit dem Sie die Ressourcen bereinigen können, die wir im Rahmen dieses Codelabs erstellt haben. Im Rahmen dieser Bereinigung werden die folgenden Ressourcen gelöscht:

  • Dienstkonto von Primus ($PRIMUS_SERVICEACCOUNT).
  • Verschlüsselungsschlüssel von Primus ($PRIMUS_ENC_KEY).
  • Artefakt-Repository von Primus ($PRIMUS_ARTIFACT_REPOSITORY).
  • Workload Identity-Pool von Primus ($PRIMUS_WORKLOAD_IDENTITY_POOL) mit seinem Anbieter.
  • Dienstkonto für die Arbeitslast von Primus ($WORKLOAD_SERVICEACCOUNT).
  • Arbeitslast-VM ($WORKLOAD_VM) und Client-VM ($CLIENT_VM).
./cleanup.sh

Wenn Sie fertig sind, können Sie Ihr Projekt löschen.

  • Rufen Sie die Cloud Platform Console auf.
  • Wählen Sie das Projekt aus, das Sie herunterfahren möchten, und klicken Sie oben auf „Löschen“. Das Projekt wird dann zur Löschung geplant.