In questa guida, Alex e Bola vogliono scoprire chi ha lo stipendio più alto senza rivelare i numeri l'uno all'altra. Decidono di utilizzare Confidential Space per mantenere riservati i propri dati e accettano di assumere i seguenti ruoli:
Alex: collaboratore di dati, autore del workload
Bola: collaboratore dei dati, operatore del carico di lavoro
Questa disposizione è pensata per semplificare al massimo la guida. Tuttavia, è possibile che l'autore e l'operatore del workload siano completamente indipendenti dai collaboratori dei dati e puoi avere tutti i collaboratori che vuoi.
Prima di iniziare
Questa guida illustra uno scenario di Confidential Space utilizzando un singolo account in una singola organizzazione con accesso a più progetti, in modo che tu possa sperimentare l'intero processo. In un deployment di produzione, collaboratori, autori di workload e operatori di workload hanno account separati e progetti propri contenuti in organizzazioni distinte, inaccessibili l'uno all'altro e che mantengono separati i dati riservati.
Confidential Space può interagire con molti servizi di Google Cloudper produrre i suoi risultati, tra cui, a titolo esemplificativo:
Questa guida utilizza e presuppone una conoscenza di base di tutte queste funzionalità.
Ruoli obbligatori
Per ottenere le autorizzazioni necessarie per completare questa guida, chiedi all'amministratore di concederti i seguenti ruoli IAM nel progetto:
-
Cloud KMS Admin (
roles/cloudkms.admin) per i collaboratori dei dati (Alex e Bola). -
IAM Workload Identity Pool Admin (
roles/iam.workloadIdentityPoolAdmin) per i collaboratori dei dati (Alex e Bola). -
Amministratore Service Usage (
roles/serviceusage.serviceUsageAdmin) per i collaboratori dei dati (Alex e Bola). -
Amministratore dell'archiviazione (
roles/storage.admin) per i collaboratori dei dati (Alex e Bola) e l'operatore del carico di lavoro (Bola). -
Amministratore service account (
roles/iam.serviceAccountAdmin) per l'operatore del workload (Bola). -
Compute Admin (
roles/compute.admin) per l'operatore del carico di lavoro (Bola). -
Amministratore sicurezza (
roles/securityAdmin) per l'operatore del workload (Bola). -
Amministratore Artifact Registry (
roles/artifactregistry.admin) per l'autore del workload (Alex).
Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.
Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.
Configurare le risorse per i collaboratori dei dati
Sia Alex che Bola hanno bisogno di progetti indipendenti che contengano le seguenti risorse:
I dati riservati stessi.
Una chiave di crittografia per criptare i dati e mantenerli riservati.
Un bucket Cloud Storage in cui archiviare i dati criptati.
Un pool di identità del workload. Il carico di lavoro che elabora i dati riservati utilizza il pool per accedere ai dati privati e decriptarli.
Per iniziare, vai alla console Google Cloud :
Configurare le risorse di Alex
Per configurare le risorse per Alex, completa le seguenti istruzioni.
- Fai clic su Attiva Cloud Shell.
-
In Cloud Shell, inserisci il comando seguente per creare un progetto per Alex, sostituendo ALEX_PROJECT_ID con un nome a tua scelta:
gcloud projects create ALEX_PROJECT_ID -
Passa al progetto appena creato:
gcloud config set project ALEX_PROJECT_ID -
Attiva le API richieste da Alex in qualità di collaboratore dei dati e autore del workload:
gcloud services enable \ artifactregistry.googleapis.com \ cloudkms.googleapis.com \ iamcredentials.googleapis.com -
Crea un portachiavi e una chiave di crittografia con Cloud Key Management Service:
gcloud kms keyrings create ALEX_KEYRING_NAME \ --location=global gcloud kms keys create ALEX_KEY_NAME \ --location=global \ --keyring=ALEX_KEYRING_NAME \ --purpose=encryption -
Concedi ad Alex il ruolo
cloudkms.cryptoKeyEncrypterin modo che possa utilizzare la chiave di crittografia appena creata per criptare i dati:gcloud kms keys add-iam-policy-binding \ "projects/ALEX_PROJECT_ID/locations/global/\ keyRings/ALEX_KEYRING_NAME/\ cryptoKeys/ALEX_KEY_NAME" \ --member=user:$(gcloud config get-value account) \ --role=roles/cloudkms.cryptoKeyEncrypter -
Crea il pool di identità del workload di Alex:
gcloud iam workload-identity-pools create ALEX_POOL_NAME \ --location=global -
Crea un bucket Cloud Storage per i dati di input e un altro per archiviare i risultati:
gcloud storage buckets create gs://ALEX_INPUT_BUCKET_NAME \ gs://ALEX_OUTPUT_BUCKET_NAME -
Crea un file contenente solo lo stipendio di Alex come numero:
echo 123456 > ALEX_SALARY.txt -
Cripta il file, quindi caricalo nel bucket di Alex:
gcloud kms encrypt \ --ciphertext-file="ALEX_ENCRYPTED_SALARY_FILE" \ --plaintext-file="ALEX_SALARY.txt" \ --key="projects/ALEX_PROJECT_ID/locations/global/\ keyRings/ALEX_KEYRING_NAME/\ cryptoKeys/ALEX_KEY_NAME"gcloud storage cp ALEX_ENCRYPTED_SALARY_FILE gs://ALEX_INPUT_BUCKET_NAME
Configurare le risorse di Bola
Per configurare le risorse per Bola, completa le seguenti istruzioni.
-
In Cloud Shell, inserisci il comando seguente per creare un progetto per Bola, sostituendo BOLA_PROJECT_ID con un nome a tua scelta:
gcloud projects create BOLA_PROJECT_ID -
Passa al progetto appena creato:
gcloud config set project BOLA_PROJECT_ID -
Abilita le API richieste da Bola in qualità di collaboratore dei dati e operatore del carico di lavoro:
gcloud services enable \ cloudkms.googleapis.com \ compute.googleapis.com \ confidentialcomputing.googleapis.com \ iamcredentials.googleapis.com -
Crea un portachiavi e una chiave di crittografia con Cloud Key Management Service:
gcloud kms keyrings create BOLA_KEYRING_NAME \ --location=global gcloud kms keys create BOLA_KEY_NAME \ --location=global \ --keyring=BOLA_KEYRING_NAME \ --purpose=encryption -
Concedi a Bola il ruolo
cloudkms.cryptoKeyEncrypterin modo che possa utilizzare la chiave di crittografia appena creata per criptare i dati:gcloud kms keys add-iam-policy-binding \ "projects/BOLA_PROJECT_ID/locations/global/\ keyRings/BOLA_KEYRING_NAME/\ cryptoKeys/BOLA_KEY_NAME" \ --member=user:$(gcloud config get-value account) \ --role=roles/cloudkms.cryptoKeyEncrypter -
Crea il pool di identità del workload di Bola:
gcloud iam workload-identity-pools create BOLA_POOL_NAME \ --location=global -
Crea un bucket Cloud Storage per i dati di input e un altro per archiviare i risultati:
gcloud storage buckets create gs://BOLA_INPUT_BUCKET_NAME \ gs://BOLA_OUTPUT_BUCKET_NAME -
Crea un file contenente solo lo stipendio di Bola come numero:
echo 111111 > BOLA_SALARY.txt -
Cripta il file e poi caricalo nel bucket di Bola:
gcloud kms encrypt \ --ciphertext-file="BOLA_ENCRYPTED_SALARY_FILE" \ --plaintext-file="BOLA_SALARY.txt" \ --key="projects/BOLA_PROJECT_ID/locations/global/\ keyRings/BOLA_KEYRING_NAME/\ cryptoKeys/BOLA_KEY_NAME"gcloud storage cp BOLA_ENCRYPTED_SALARY_FILE gs://BOLA_INPUT_BUCKET_NAME
Crea un account di servizio per il workload
In questa guida, Bola gestisce ed esegue il carico di lavoro, ma chiunque può assumere questi ruoli, inclusa una terza parte. La VM creata da Bola per eseguire il workload ha un account di servizio collegato, che ha l'autorizzazione per generare token di attestazione, scrivere log, leggere i dati criptati di Alex e Bola e scrivere i risultati in bucket Cloud Storage specifici.
Completa i seguenti passaggi nel progetto di Bola per configurare il account di servizio:
Crea un account di servizio per eseguire il workload:
gcloud iam service-accounts create WORKLOAD_SERVICE_ACCOUNT_NAMEConcedi a Bola il ruolo
iam.serviceAccountUser, in modo che possa collegare il service account alla VM del carico di lavoro in un secondo momento:gcloud iam service-accounts add-iam-policy-binding \ WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --member=user:$(gcloud config get-value account) \ --role=roles/iam.serviceAccountUserConcedi al account di servizio il ruolo
confidentialcomputing.workloadUserin modo che possa generare un token di attestazione:gcloud projects add-iam-policy-binding BOLA_PROJECT_ID \ --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/confidentialcomputing.workloadUserConcedi al account di servizio il ruolo
logging.logWriterper scrivere log in Cloud Logging, in modo da poter controllare l'avanzamento del workload:gcloud projects add-iam-policy-binding BOLA_PROJECT_ID \ --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/logging.logWriterConcedi all'account di servizio l'accesso in lettura ai bucket di Alex e Bola che contengono i loro dati criptati e l'accesso in scrittura ai bucket dei risultati di ciascuno:
gcloud storage buckets add-iam-policy-binding gs://ALEX_INPUT_BUCKET_NAME \ --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/storage.objectViewer gcloud storage buckets add-iam-policy-binding gs://ALEX_OUTPUT_BUCKET_NAME \ --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/storage.objectAdmin gcloud storage buckets add-iam-policy-binding gs://BOLA_INPUT_BUCKET_NAME \ --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/storage.objectViewer gcloud storage buckets add-iam-policy-binding gs://BOLA_OUTPUT_BUCKET_NAME \ --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/storage.objectAdminCiò presuppone che l'utente che concede l'accesso disponga del ruolo Storage Admin (
roles/storage.admin) per il progetto che contiene il bucket Cloud Storage su cui viene eseguita l'operazione.
Crea il workload
In questa guida, Alex fornisce il codice per il workload e crea un'immagine Docker per contenerlo, ma chiunque può assumere questi ruoli, inclusa una terza parte.
Alex deve creare le seguenti risorse per il workload:
Il codice che esegue il carico di lavoro.
Un repository Docker in Artifact Registry a cui ha accesso il account di servizio che esegue il carico di lavoro.
Un'immagine Docker che contiene ed esegue il codice del workload.
Per creare e configurare le risorse, completa i seguenti passaggi nel progetto di Alex:
Passa al progetto di Alex:
gcloud config set project ALEX_PROJECT_IDFai clic su Apri editor per aprire l'editor di Cloud Shell, quindi crea un nuovo file chiamato
salary.go. Copia il seguente codice nel file e poi salvalo:package main import ( "context" "fmt" "io" "os" "strconv" "strings" "time" kms "cloud.google.com/go/kms/apiv1" kmspb "cloud.google.com/go/kms/apiv1/kmspb" "cloud.google.com/go/storage" "google.golang.org/api/option" ) type collaborator struct { name string wipName string keyName string inputBucket string inputFile string outputBucket string } // The following values are pulled from environment variables // Alex's values var collaborator1Name string = os.Getenv("COLLAB_1_NAME") // Alex's name var collaborator1EncryptedSalaryFileName string = os.Getenv("COLLAB_1_ENCRYPTED_SALARY") // The name of Alex's encrypted salary file. var collaborator1BucketInputName string = os.Getenv("COLLAB_1_INPUT_BUCKET") // The name of the storage bucket that contains Alex's encrypted salary file. var collaborator1BucketOutputName string = os.Getenv("COLLAB_1_OUTPUT_BUCKET") // The name of the storage bucket to store Alex's results in. var collaborator1KMSKeyringName string = os.Getenv("COLLAB_1_KEYRING_NAME") // Alex's Key Management Service key ring. var collaborator1KMSKeyName string = os.Getenv("COLLAB_1_KEY_NAME") // Alex's Key Management Service key. var collaborator1ProjectName string = os.Getenv("COLLAB_1_PROJECT_ID") // Alex's project ID. var collaborator1ProjectNumber string = os.Getenv("COLLAB_1_PROJECT_NUMBER") // Alex's project number. var collaborator1PoolName string = os.Getenv("COLLAB_1_POOL_NAME") // Alex's workload identity pool name. // Bola's values var collaborator2Name string = os.Getenv("COLLAB_2_NAME") // Bola's name var collaborator2EncryptedSalaryFileName string = os.Getenv("COLLAB_2_ENCRYPTED_SALARY") // The name of Bola's encrypted salary file. var collaborator2BucketInputName string = os.Getenv("COLLAB_2_INPUT_BUCKET") // The name of the storage bucket that contains Bola's encrypted salary file. var collaborator2BucketOutputName string = os.Getenv("COLLAB_2_OUTPUT_BUCKET") // The name of the storage bucket to store Bola's results in. var collaborator2KMSKeyringName string = os.Getenv("COLLAB_2_KEYRING_NAME") // Bola's Key Management Service key ring. var collaborator2KMSKeyName string = os.Getenv("COLLAB_2_KEY_NAME") // Bola's Key Management Service key. var collaborator2ProjectName string = os.Getenv("COLLAB_2_PROJECT_ID") // Bola's project ID. var collaborator2ProjectNumber string = os.Getenv("COLLAB_2_PROJECT_NUMBER") // Bola's project number. var collaborator2PoolName string = os.Getenv("COLLAB_2_POOL_NAME") // Bola's workload identity pool name. var collaborators = [2]collaborator{ { collaborator1Name, "projects/" + collaborator1ProjectNumber + "/locations/global/workloadIdentityPools/" + collaborator1PoolName + "/providers/attestation-verifier", "projects/" + collaborator1ProjectName + "/locations/global/keyRings/" + collaborator1KMSKeyringName + "/cryptoKeys/" + collaborator1KMSKeyName, collaborator1BucketInputName, collaborator1EncryptedSalaryFileName, collaborator1BucketOutputName, }, { collaborator2Name, "projects/" + collaborator2ProjectNumber + "/locations/global/workloadIdentityPools/" + collaborator2PoolName + "/providers/attestation-verifier", "projects/" + collaborator2ProjectName + "/locations/global/keyRings/" + collaborator2KMSKeyringName + "/cryptoKeys/" + collaborator2KMSKeyName, collaborator2BucketInputName, collaborator2EncryptedSalaryFileName, collaborator2BucketOutputName, }, } const credentialConfig = `{ "type": "external_account", "audience": "//iam.googleapis.com/%s", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "token_url": "https://sts.googleapis.com/v1/token", "credential_source": { "file": "/run/container_launcher/attestation_verifier_claims_token" } }` func main() { fmt.Println("workload started") ctx := context.Background() storageClient, err := storage.NewClient(ctx) // Using the default credential on the Compute Engine VM if err != nil { panic(err) } // Get and decrypt s0, err := getSalary(ctx, storageClient, collaborators[0]) if err != nil { panic(err) } s1, err := getSalary(ctx, storageClient, collaborators[1]) if err != nil { panic(err) } res := "" if s0 > s1 { res = fmt.Sprintf("%s earns more!\n", collaborators[0].name) } else if s1 > s0 { res = fmt.Sprintf("%s earns more!\n", collaborators[1].name) } else { res = "You earn the same!\n" } now := time.Now() for _, cw := range collaborators { outputWriter := storageClient.Bucket(cw.outputBucket).Object(fmt.Sprintf("comparison-result-%d", now.Unix())).NewWriter(ctx) _, err = outputWriter.Write([]byte(res)) if err != nil { fmt.Printf("Could not write: %v", err) panic(err) } if err = outputWriter.Close(); err != nil { fmt.Printf("Could not close: %v", err) panic(err) } } } func getSalary(ctx context.Context, storageClient *storage.Client, cw collaborator) (float64, error) { encryptedBytes, err := getFile(ctx, storageClient, cw.inputBucket, cw.inputFile) if err != nil { return 0.0, err } decryptedByte, err := decryptByte(ctx, cw.keyName, cw.wipName, encryptedBytes) if err != nil { return 0.0, err } decryptedNumber := strings.TrimSpace(string(decryptedByte)) num, err := strconv.ParseFloat(decryptedNumber, 64) if err != nil { return 0.0, err } return num, nil } func decryptByte(ctx context.Context, keyName, wippro string, encryptedData []byte) ([]byte, error) { cc := fmt.Sprintf(credentialConfig, wippro) kmsClient, err := kms.NewKeyManagementClient(ctx, option.WithCredentialsJSON([]byte(cc))) if err != nil { return nil, fmt.Errorf("creating a new KMS client with federated credentials: %w", err) } decryptRequest := &kmspb.DecryptRequest{ Name: keyName, Ciphertext: encryptedData, } decryptResponse, err := kmsClient.Decrypt(ctx, decryptRequest) if err != nil { return nil, fmt.Errorf("could not decrypt ciphertext: %w", err) } return decryptResponse.Plaintext, nil } func getFile(ctx context.Context, c *storage.Client, bucketName string, objPath string) ([]byte, error) { bucketHandle := c.Bucket(bucketName) objectHandle := bucketHandle.Object(objPath) objectReader, err := objectHandle.NewReader(ctx) if err != nil { return nil, err } defer objectReader.Close() s, err := io.ReadAll(objectReader) if err != nil { return nil, err } return s, nil }Assicurati che tutte le parti leggano e controllino il codice sorgente.
Crea un file denominato
Dockerfilenell'editor di Cloud Shell contenente il seguente contenuto:# Compile the provided Go code to a statically linked binary FROM golang:latest AS build WORKDIR /build COPY salary.go . RUN go mod init salary RUN go get cloud.google.com/go/kms/apiv1 cloud.google.com/go/storage google.golang.org/api/option google.golang.org/genproto/googleapis/cloud/kms/v1 RUN CGO_ENABLED=0 go build -trimpath # Build the workload container image FROM alpine:latest AS run WORKDIR /test COPY --from=build /build/salary /test/salary ENTRYPOINT ["/test/salary"] CMD [] # Allow the workload to access the following environment variables LABEL "tee.launch_policy.allow_env_override"="\ COLLAB_1_NAME,\ COLLAB_2_NAME,\ COLLAB_1_ENCRYPTED_SALARY,\ COLLAB_2_ENCRYPTED_SALARY,\ COLLAB_1_INPUT_BUCKET,\ COLLAB_2_INPUT_BUCKET,\ COLLAB_1_OUTPUT_BUCKET,\ COLLAB_2_OUTPUT_BUCKET,\ COLLAB_1_KEYRING_NAME,\ COLLAB_2_KEYRING_NAME,\ COLLAB_1_KEY_NAME,\ COLLAB_2_KEY_NAME,\ COLLAB_1_PROJECT_ID,\ COLLAB_2_PROJECT_ID,\ COLLAB_1_PROJECT_NUMBER,\ COLLAB_2_PROJECT_NUMBER,\ COLLAB_1_POOL_NAME,\ COLLAB_2_POOL_NAME"Questo
Dockerfileutilizza una build in più fasi per compilare prima il codice Go e poi copia la versione compilata del codice nel contenitore del workload finale. Consente inoltre di utilizzare variabili di ambiente specifiche nel container del carico di lavoro. I valori di queste variabili di ambiente vengono mappati in un secondo momento alle risorse specifiche su cui deve operare il workload.Fai clic su Apri terminale per tornare a Cloud Shell oppure richiama il terminale integrato nell'editor di Cloud Shell dal menu Visualizza.
Crea un repository Docker in Artifact Registry:
gcloud artifacts repositories create REPOSITORY_NAME \ --repository-format=docker \ --location=usConcedi al account di servizio che eseguirà il workload il ruolo Lettore Artifact Registry (
roles/artifactregistry.reader) in modo che possa leggere dal repository:gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \ --location=us \ --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/artifactregistry.readerAggiorna le credenziali Docker per includere il nome di dominio
us-docker.pkg.dev:gcloud auth configure-docker us-docker.pkg.devCrea un'immagine Docker da
Dockerfileinserendo questo comando nel terminale:docker build -t \ "us-docker.pkg.dev/ALEX_PROJECT_ID/\ REPOSITORY_NAME/WORKLOAD_CONTAINER_NAME:latest" .Esegui il push dell'immagine Docker in Artifact Registry:
docker push \ us-docker.pkg.dev/ALEX_PROJECT_ID/REPOSITORY_NAME/WORKLOAD_CONTAINER_NAMELa risposta al comando Docker push elenca il digest SHA256 dell'immagine, necessario in un secondo momento per autorizzare il workload. Il riepilogo è simile al seguente esempio:
sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Copia il digest dell'immagine (incluso il prefisso
sha256:) in un punto in cui puoi farvi riferimento. Puoi anche inserire il digest nel seguente esempio di codice per precompilare il resto degli esempi di codice in questa guida che richiedono il valore:WORKLOAD_CONTAINER_IMAGE_DIGESTPrima di autorizzarne l'utilizzo, assicurati che tutte le parti controllino l'immagine Docker e verifichino che sia attendibile.
Autorizza il workload
Con il workload approvato da entrambe le parti, Alex e Bola devono aggiungere Google Cloud Attestation come provider ai loro pool di identità dei workload. Il fornitore specifica il servizio di attestazione da utilizzare e le proprietà che il carico di lavoro deve corrispondere per poter operare sui dati di Alex o Bola. Se un malintenzionato modifica l'immagine Docker o altera un'altra proprietà misurata, l'accesso al workload viene negato.
Questa guida utilizza le mappature degli attributi per fornire l'accesso diretto alle risorse al workload in base al digest dell'immagine. Tuttavia, in altre situazioni potresti preferire utilizzare l'imitazione del account di servizio per accedere alle risorse. Per saperne di più, consulta la sezione Accesso ai workload esterni.
Per configurare i fornitori per Alex e Bola con le condizioni richieste, completa i seguenti passaggi:
Inserisci questo comando per creare il fornitore per Alex:
gcloud iam workload-identity-pools providers create-oidc attestation-verifier \ --location=global \ --workload-identity-pool=ALEX_POOL_NAME \ --issuer-uri="https://confidentialcomputing.googleapis.com/" \ --allowed-audiences="https://sts.googleapis.com" \ --attribute-mapping="google.subject=\"gcpcs\ ::\"+assertion.submods.container.image_digest+\"\ ::\"+assertion.submods.gce.project_number+\"\ ::\"+assertion.submods.gce.instance_id,\ attribute.image_digest=assertion.submods.container.image_digest" \ --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE'"Recupera il numero di progetto di Alex per il comando successivo:
gcloud projects describe ALEX_PROJECT_ID --format="value(projectNumber)"Concedi all'identità federata definita dal provider di Alex il ruolo
cloudkms.cryptoKeyDecrypter, specificando l'attributoimage_digestin modo che solo i container dei workload con il digest specificato possano decriptare le chiavi KMS:gcloud kms keys add-iam-policy-binding \ "projects/ALEX_PROJECT_ID/locations/global/\ keyRings/ALEX_KEYRING_NAME/\ cryptoKeys/ALEX_KEY_NAME" \ --member="principalSet://iam.googleapis.com/\ projects/ALEX_PROJECT_NUMBER/locations/global/\ workloadIdentityPools/ALEX_POOL_NAME/\ attribute.image_digest/WORKLOAD_CONTAINER_IMAGE_DIGEST" \ --role=roles/cloudkms.cryptoKeyDecrypterPassa al progetto di Bola:
gcloud config set project BOLA_PROJECT_IDInserisci questo comando per creare il provider per Bola:
gcloud iam workload-identity-pools providers create-oidc attestation-verifier \ --location=global \ --workload-identity-pool=BOLA_POOL_NAME \ --issuer-uri="https://confidentialcomputing.googleapis.com/" \ --allowed-audiences="https://sts.googleapis.com" \ --attribute-mapping="google.subject=\"gcpcs\ ::\"+assertion.submods.container.image_digest+\"\ ::\"+assertion.submods.gce.project_number+\"\ ::\"+assertion.submods.gce.instance_id,\ attribute.image_digest=assertion.submods.container.image_digest" \ --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE'"Recupera il numero di progetto di Bola per il comando successivo:
gcloud projects describe BOLA_PROJECT_ID --format="value(projectNumber)"Concedi all'identità federata definita dal provider di Bola il ruolo
cloudkms.cryptoKeyDecrypter, specificando l'attributoimage_digestin modo che solo i container dei workload con il digest specificato possano decriptare le chiavi KMS:gcloud kms keys add-iam-policy-binding \ "projects/BOLA_PROJECT_ID/locations/global/\ keyRings/BOLA_KEYRING_NAME/\ cryptoKeys/BOLA_KEY_NAME" \ --member="principalSet://iam.googleapis.com/\ projects/BOLA_PROJECT_NUMBER/locations/global/\ workloadIdentityPools/BOLA_POOL_NAME/\ attribute.image_digest/WORKLOAD_CONTAINER_IMAGE_DIGEST" \ --role=roles/cloudkms.cryptoKeyDecrypter
Testa il carico di lavoro
Con i provider aggiunti ai pool di identità del workload di Alex e Bola e le risorse richieste, è il momento per l'operatore del workload di testare il workload.
Per testare il workload, crea una nuova istanza Confidential VM nel progetto di Bola con le seguenti proprietà:
Una configurazione supportata con AMD SEV, Intel TDX o Intel TDX con NVIDIA Confidential Computing (anteprima).
Avvio protetto abilitato.
Un sistema operativo basato sull'immagine di debug di Confidential Space, per semplificare la risoluzione dei problemi.
Un riferimento all'immagine Docker creata in precedenza da Alex. Viene caricato sopra l'immagine di Confidential Space.
Un service account che Bola ha creato in precedenza, che esegue il workload.
STDOUTeSTDERRreindirizzati sia a Cloud Logging sia alla console seriale.I dettagli delle risorse di cui ha bisogno il workload sono impostati come variabili di ambiente.
Inserisci questo comando nella Cloud Shell di Bola per testare il carico di lavoro:
gcloud compute instances create WORKLOAD_VM_2_NAME \
--confidential-compute-type=SEV \
--shielded-secure-boot \
--scopes=cloud-platform \
--zone=us-west1-b \
--maintenance-policy=MIGRATE \
--min-cpu-platform="AMD Milan" \
--image-project=confidential-space-images \
--image-family=confidential-space-debug \
--service-account=WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \
--metadata="^~^tee-image-reference=us-docker.pkg.dev/\
ALEX_PROJECT_ID/REPOSITORY_NAME/WORKLOAD_CONTAINER_NAME:latest\
~tee-container-log-redirect=true\
~tee-env-COLLAB_1_NAME=Alex\
~tee-env-COLLAB_2_NAME=Bola\
~tee-env-COLLAB_1_ENCRYPTED_SALARY=ALEX_ENCRYPTED_SALARY_FILE\
~tee-env-COLLAB_2_ENCRYPTED_SALARY=BOLA_ENCRYPTED_SALARY_FILE\
~tee-env-COLLAB_1_INPUT_BUCKET=ALEX_INPUT_BUCKET_NAME\
~tee-env-COLLAB_2_INPUT_BUCKET=BOLA_INPUT_BUCKET_NAME\
~tee-env-COLLAB_1_OUTPUT_BUCKET=ALEX_OUTPUT_BUCKET_NAME\
~tee-env-COLLAB_2_OUTPUT_BUCKET=BOLA_OUTPUT_BUCKET_NAME\
~tee-env-COLLAB_1_KEYRING_NAME=ALEX_KEYRING_NAME\
~tee-env-COLLAB_2_KEYRING_NAME=BOLA_KEYRING_NAME\
~tee-env-COLLAB_1_KEY_NAME=ALEX_KEY_NAME\
~tee-env-COLLAB_2_KEY_NAME=BOLA_KEY_NAME\
~tee-env-COLLAB_1_PROJECT_ID=ALEX_PROJECT_ID\
~tee-env-COLLAB_2_PROJECT_ID=BOLA_PROJECT_ID\
~tee-env-COLLAB_1_PROJECT_NUMBER=ALEX_PROJECT_NUMBER\
~tee-env-COLLAB_2_PROJECT_NUMBER=BOLA_PROJECT_NUMBER\
~tee-env-COLLAB_1_POOL_NAME=ALEX_POOL_NAME\
~tee-env-COLLAB_2_POOL_NAME=BOLA_POOL_NAME"
Visualizza avanzamento
Puoi visualizzare l'avanzamento del workload nel progetto di Bola andando a Esplora log.
Per mostrare solo le voci di log di Confidential Space, filtra in base ai seguenti campi di log, se disponibili:
Tipo di risorsa:istanza VM
ID istanza:l'ID istanza della VM
Nome log: confidential-space-launcher
Per aggiornare il log, fai clic su Vai a ora. Puoi anche scorrere fino ai risultati precedenti e poi fino alla fine del log per caricare le ultime voci.
Visualizza i risultati
Se l'attività del workload termina e restituisce 0, significa che non si sono verificati errori
ed è il momento di controllare l'output nei bucket di output di Alex e Bola:
Passa al progetto di Alex:
gcloud config set project ALEX_PROJECT_IDElenca tutti i file nel bucket dei risultati:
gcloud storage ls gs://ALEX_OUTPUT_BUCKET_NAMELeggi l'ultimo file elencato, sostituendo
ALEX_OUTPUT_CLOUD_STORAGE_PATHcon il percorso del file, inclusogs://:gcloud storage cat ALEX_OUTPUT_CLOUD_STORAGE_PATHSe non è presente alcun file, devi eseguire il debug del carico di lavoro.
Passa al progetto di Bola:
gcloud config set project BOLA_PROJECT_IDElenca tutti i file nel bucket dei risultati:
gcloud storage ls gs://BOLA_OUTPUT_BUCKET_NAMELeggi l'ultimo file elencato, sostituendo
BOLA_RESULTS_CLOUD_STORAGE_PATHcon il percorso del file, inclusogs://:gcloud storage cat BOLA_RESULTS_CLOUD_STORAGE_PATHSe non è presente alcun file, devi eseguire il debug del carico di lavoro.
Dopo aver letto correttamente i risultati, arresta l'istanza VM:
gcloud compute instances stop WORKLOAD_VM_2_NAME --zone=us-west1-b
Leggendo i file, Alex e Bola scoprono chi guadagna di più senza mai rivelarsi reciprocamente i propri stipendi.
Esegui il debug e riavvia il workload
Un ambiente Confidential Space è composto da molte parti ed è possibile che qualcosa sia stato configurato in modo errato, causando l'errore del workload.
A differenza dell'immagine Confidential Space di produzione, l'immagine di debug mantiene l'istanza VM in esecuzione dopo il completamento del workload. Ciò significa che, se i log non rivelano informazioni sufficienti per risolvere il problema, il passaggio successivo consiste nel connettersi alla tua istanza VM tramite SSH e continuare il debug.
Al termine del debug, arresta l'istanza VM:
gcloud compute instances stop WORKLOAD_VM_2_NAME --zone=us-west1-b
Per eseguire il workload nell'ambiente di cui è stato eseguito il debug, avvia di nuovo la VM:
gcloud compute instances start WORKLOAD_VM_2_NAME --zone=us-west1-b
Proteggere l'ambiente per la produzione
Dopo aver testato il carico di lavoro, è il momento di
proteggere l'ambiente Confidential Space per il deployment di produzione. Alex e Bola
devono aggiungere
un'asserzione
ai loro fornitori per verificare che l'immagine di Confidential Space di produzione venga utilizzata
per il workload:support_attributes
Passa al progetto di Alex:
gcloud config set project ALEX_PROJECT_IDInserisci il seguente comando per aggiornare il fornitore di Alex:
gcloud iam workload-identity-pools providers update-oidc attestation-verifier \ --location=global \ --workload-identity-pool=ALEX_POOL_NAME \ --issuer-uri="https://confidentialcomputing.googleapis.com/" \ --allowed-audiences="https://sts.googleapis.com" \ --attribute-mapping="google.subject=\"gcpcs\ ::\"+assertion.submods.container.image_digest+\"\ ::\"+assertion.submods.gce.project_number+\"\ ::\"+assertion.submods.gce.instance_id,\ attribute.image_digest=assertion.submods.container.image_digest" \ --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' \ && 'STABLE' in assertion.submods.confidential_space.support_attributes"Passa al progetto di Bola:
gcloud config set project BOLA_PROJECT_IDInserisci il seguente comando per aggiornare il fornitore per Bola:
gcloud iam workload-identity-pools providers update-oidc attestation-verifier \ --location=global \ --workload-identity-pool=BOLA_POOL_NAME \ --issuer-uri="https://confidentialcomputing.googleapis.com/" \ --allowed-audiences="https://sts.googleapis.com" \ --attribute-mapping="google.subject=\"gcpcs\ ::\"+assertion.submods.container.image_digest+\"\ ::\"+assertion.submods.gce.project_number+\"\ ::\"+assertion.submods.gce.instance_id,\ attribute.image_digest=assertion.submods.container.image_digest" \ --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' \ && 'STABLE' in assertion.submods.confidential_space.support_attributes"
Esegui il deployment del carico di lavoro di produzione
Bola deve creare un'istanza VM separata per eseguire il workload di produzione. Rispetto al carico di lavoro di test, sono diverse le seguenti cose:
Il sistema operativo si basa sull'immagine di Confidential Space di produzione. SSH è disattivato e l'istanza VM si arresta al termine del workload.
Il reindirizzamento della registrazione è stato rimosso. In Cloud Logging vengono visualizzati solo i log di base che non espongono informazioni sensibili.
Inserisci questo comando nella sessione di Cloud Shell di Bola per eseguire il deployment del carico di lavoro di produzione:
gcloud compute instances create WORKLOAD_VM_NAME \
--confidential-compute-type=SEV \
--shielded-secure-boot \
--scopes=cloud-platform \
--zone=us-west1-b \
--maintenance-policy=MIGRATE \
--image-project=confidential-space-images \
--image-family=confidential-space \
--service-account=WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \
--metadata="^~^tee-image-reference=us-docker.pkg.dev/\
ALEX_PROJECT_ID/REPOSITORY_NAME/WORKLOAD_CONTAINER_NAME:latest\
~tee-env-COLLAB_1_NAME=Alex\
~tee-env-COLLAB_2_NAME=Bola\
~tee-env-COLLAB_1_ENCRYPTED_SALARY=ALEX_ENCRYPTED_SALARY_FILE\
~tee-env-COLLAB_2_ENCRYPTED_SALARY=BOLA_ENCRYPTED_SALARY_FILE\
~tee-env-COLLAB_1_INPUT_BUCKET=ALEX_INPUT_BUCKET_NAME\
~tee-env-COLLAB_2_INPUT_BUCKET=BOLA_INPUT_BUCKET_NAME\
~tee-env-COLLAB_1_OUTPUT_BUCKET=ALEX_OUTPUT_BUCKET_NAME\
~tee-env-COLLAB_2_OUTPUT_BUCKET=BOLA_OUTPUT_BUCKET_NAME\
~tee-env-COLLAB_1_KEYRING_NAME=ALEX_KEYRING_NAME\
~tee-env-COLLAB_2_KEYRING_NAME=BOLA_KEYRING_NAME\
~tee-env-COLLAB_1_KEY_NAME=ALEX_KEY_NAME\
~tee-env-COLLAB_2_KEY_NAME=BOLA_KEY_NAME\
~tee-env-COLLAB_1_PROJECT_ID=ALEX_PROJECT_ID\
~tee-env-COLLAB_2_PROJECT_ID=BOLA_PROJECT_ID\
~tee-env-COLLAB_1_PROJECT_NUMBER=ALEX_PROJECT_NUMBER\
~tee-env-COLLAB_2_PROJECT_NUMBER=BOLA_PROJECT_NUMBER\
~tee-env-COLLAB_1_POOL_NAME=ALEX_POOL_NAME\
~tee-env-COLLAB_2_POOL_NAME=BOLA_POOL_NAME"
Il modo in cui visualizzi l'avanzamento e visualizzi i risultati è lo stesso di quando hai testato il carico di lavoro.
Al termine del workload di produzione, l'istanza VM si arresta. Per visualizzare risultati diversi, puoi modificare gli stipendi, crittografarli di nuovo, caricarli di nuovo nei rispettivi bucket Cloud Storage e poi riavviare l'istanza VM per eseguire di nuovo il workload:
gcloud compute instances start WORKLOAD_VM_NAME --zone=us-west1-b
Esegui la pulizia
Per rimuovere le risorse create in questa guida, completa le seguenti istruzioni.
Esegui la pulizia delle risorse di Alessandro
Passa al progetto di Alex:
gcloud config set project ALEX_PROJECT_IDElimina il pool di identità del workload di Alex:
gcloud iam workload-identity-pools delete ALEX_POOL_NAME \ --location=globalElimina i bucket Cloud Storage di Alex:
gcloud storage rm gs://ALEX_INPUT_BUCKET_NAME \ gs://ALEX_OUTPUT_BUCKET_NAME --recursiveElimina i file della busta paga di Alex, il codice Go e
Dockerfile:rm ALEX_SALARY.txt \ ALEX_ENCRYPTED_SALARY_FILE \ salary.go \ Dockerfile(Facoltativo) Disattiva o elimina la chiave Cloud Key Management Service di Alex.
(Facoltativo) Chiudi il progetto di Alex.
Esegui la pulizia delle risorse di Bola
Passa al progetto di Bola:
gcloud config set project BOLA_PROJECT_IDElimina la VM che ha eseguito il flusso di lavoro di test:
gcloud compute instances delete WORKLOAD_VM_2_NAME --zone=us-west1-bElimina la VM che ha eseguito il flusso di lavoro di produzione:
gcloud compute instances delete WORKLOAD_VM_NAME --zone=us-west1-bElimina il account di servizio che ha eseguito il carico di lavoro:
gcloud iam service-accounts delete \ WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.comElimina il pool di identità del workload di Bola:
gcloud iam workload-identity-pools delete BOLA_POOL_NAME \ --location=globalElimina i bucket Cloud Storage di Bola:
gcloud storage rm gs://BOLA_INPUT_BUCKET_NAME \ gs://BOLA_OUTPUT_BUCKET_NAME --recursiveElimina i file della busta paga di Bola:
rm BOLA_SALARY.txt \ BOLA_ENCRYPTED_SALARY_FILE(Facoltativo) Disattiva o elimina la chiave Cloud Key Management Service di Bola.
(Facoltativo) Chiudi il progetto di Bola.