Membuat lingkungan Confidential Space pertama Anda

Dalam panduan ini, Alex dan Bola ingin mengetahui siapa yang memiliki gaji tertinggi tanpa mengungkapkan angka satu sama lain. Mereka memutuskan untuk menggunakan Confidential Space untuk menjaga kerahasiaan data mereka, dan setuju untuk mengambil peran berikut:

  • Alex: Kolaborator data, pembuat beban kerja

  • Bola: Kolaborator data, operator beban kerja

Pengaturan ini dirancang agar panduan ini sesederhana mungkin. Namun, penulis dan operator beban kerja dapat sepenuhnya independen dari kolaborator data, dan Anda dapat memiliki kolaborator sebanyak yang Anda inginkan.

Sebelum memulai

Panduan ini menunjukkan skenario Ruang Rahasia menggunakan satu akun dalam satu organisasi dengan akses ke beberapa project, sehingga Anda dapat merasakan seluruh prosesnya. Dalam deployment produksi, kolaborator, penulis workload, dan operator workload memiliki akun terpisah dan project mereka sendiri yang ada dalam organisasi terpisah, yang tidak dapat diakses satu sama lain dan menjaga data rahasia mereka tetap terpisah.

Ruang Privasi dapat berinteraksi dengan banyak layanan Google Clouduntuk menghasilkan hasilnya, termasuk, tetapi tidak terbatas pada:

Panduan ini menggunakan dan mengasumsikan pemahaman dasar tentang semua fitur ini.

Peran yang diperlukan

Untuk mendapatkan izin yang Anda perlukan untuk menyelesaikan panduan ini, minta administrator Anda untuk memberi Anda peran IAM berikut di project:

  • Admin Cloud KMS (roles/cloudkms.admin) untuk kolaborator data (Alex dan Bola).
  • IAM Workload Identity Pool Admin (roles/iam.workloadIdentityPoolAdmin) untuk kolaborator data (Alex dan Bola).
  • Service Usage Admin (roles/serviceusage.serviceUsageAdmin) untuk kolaborator data (Alex dan Bola).
  • Storage Admin (roles/storage.admin) untuk kolaborator data (Alex dan Bola) serta operator workload (Bola).
  • Admin Akun Layanan (roles/iam.serviceAccountAdmin) untuk operator beban kerja (Bola).
  • Compute Admin (roles/compute.admin) untuk operator workload (Bola).
  • Security Admin (roles/securityAdmin) untuk operator workload (Bola).
  • Administrator Artifact Registry (roles/artifactregistry.admin) untuk penulis workload (Alex).

Untuk mengetahui informasi selengkapnya tentang pemberian peran, lihat Mengelola akses ke project, folder, dan organisasi.

Anda mungkin juga bisa mendapatkan izin yang diperlukan melalui peran khusus atau peran bawaan lainnya.

Menyiapkan resource kolaborator data

Alex dan Bola memerlukan project independen yang berisi resource berikut:

  • Data rahasia itu sendiri.

  • Kunci enkripsi untuk mengenkripsi data tersebut dan menjaganya tetap rahasia.

  • Bucket Cloud Storage untuk menyimpan data terenkripsi.

  • Workload identity pool. Workload yang memproses data rahasia menggunakan pool untuk mengakses data pribadi dan mendekripsinya.

Untuk memulai, buka konsol Google Cloud :

Buka konsol Google Cloud

Menyiapkan resource Alex

Untuk menyiapkan resource untuk Alex, selesaikan petunjuk berikut.

  1. Klik Aktifkan Cloud Shell.
  2. Di Cloud Shell, masukkan perintah berikut untuk membuat project untuk Alex, dengan mengganti ALEX_PROJECT_ID dengan nama pilihan Anda:

    gcloud projects create ALEX_PROJECT_ID
  3. Beralih ke project yang baru dibuat:

    gcloud config set project ALEX_PROJECT_ID
  4. Aktifkan API yang diperlukan Alex sebagai kolaborator data dan pembuat beban kerja:

    gcloud services enable \
        artifactregistry.googleapis.com \
        cloudkms.googleapis.com \
        iamcredentials.googleapis.com
  5. Buat key ring dan kunci enkripsi dengan 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
  6. Beri Alex peran cloudkms.cryptoKeyEncrypter agar dia dapat menggunakan kunci enkripsi yang baru dibuat untuk mengenkripsi data:

    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
  7. Buat workload identity pool Alex:

    gcloud iam workload-identity-pools create ALEX_POOL_NAME \
        --location=global
  8. Buat bucket Cloud Storage untuk data input, dan bucket lain untuk menyimpan hasilnya:

    gcloud storage buckets create gs://ALEX_INPUT_BUCKET_NAME \
        gs://ALEX_OUTPUT_BUCKET_NAME
  9. Buat file yang hanya berisi gaji Alex sebagai angka:

    echo 123456 > ALEX_SALARY.txt
  10. Enkripsi file, lalu upload ke bucket 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

Menyiapkan resource Bola

Untuk menyiapkan resource untuk Bola, selesaikan petunjuk berikut.

  1. Di Cloud Shell, masukkan perintah berikut untuk membuat project untuk Bola, ganti BOLA_PROJECT_ID dengan nama pilihan Anda:

    gcloud projects create BOLA_PROJECT_ID
  2. Beralih ke project yang baru dibuat:

    gcloud config set project BOLA_PROJECT_ID
  3. Aktifkan API yang diperlukan Bola sebagai kolaborator data dan operator beban kerja:

    gcloud services enable \
        cloudkms.googleapis.com \
        compute.googleapis.com \
        confidentialcomputing.googleapis.com \
        iamcredentials.googleapis.com
  4. Buat key ring dan kunci enkripsi dengan 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
  5. Beri Bola peran cloudkms.cryptoKeyEncrypter agar dia dapat menggunakan kunci enkripsi yang baru dibuat untuk mengenkripsi data:

    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
  6. Buat workload identity pool Bola:

    gcloud iam workload-identity-pools create BOLA_POOL_NAME \
        --location=global
  7. Buat bucket Cloud Storage untuk data input, dan bucket lain untuk menyimpan hasilnya:

    gcloud storage buckets create gs://BOLA_INPUT_BUCKET_NAME \
        gs://BOLA_OUTPUT_BUCKET_NAME
  8. Buat file yang hanya berisi gaji Bola sebagai angka:

    echo 111111 > BOLA_SALARY.txt
  9. Enkripsi file, lalu upload ke bucket 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

Buat akun layanan untuk workload

Dalam panduan ini, Bola mengoperasikan dan menjalankan beban kerja, tetapi siapa pun dapat mengambil peran ini, termasuk pihak ketiga. Instance VM yang dibuat Bola untuk menjalankan beban kerja memiliki akun layanan yang terlampir, yang memiliki izin untuk membuat token pengesahan, menulis log, membaca data terenkripsi Alex dan Bola, serta menulis hasil ke bucket Cloud Storage tertentu.

Selesaikan langkah-langkah berikut di project Bola untuk menyiapkan akun layanan:

  1. Buat akun layanan untuk menjalankan workload:

    gcloud iam service-accounts create WORKLOAD_SERVICE_ACCOUNT_NAME
    
  2. Berikan peran iam.serviceAccountUser kepada Bola, sehingga ia dapat melampirkan akun layanan ke VM beban kerja nanti:

    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.serviceAccountUser
    
  3. Berikan peran confidentialcomputing.workloadUser ke akun layanan agar dapat membuat token pengesahan:

    gcloud projects add-iam-policy-binding BOLA_PROJECT_ID \
        --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/confidentialcomputing.workloadUser
    
  4. Beri akun layanan peran logging.logWriter untuk menulis log ke Cloud Logging, sehingga Anda dapat memeriksa progres beban kerja:

    gcloud projects add-iam-policy-binding BOLA_PROJECT_ID \
        --member=serviceAccount:WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/logging.logWriter
    
  5. Beri akun layanan akses baca ke bucket Alex dan Bola yang berisi data terenkripsi mereka, dan akses tulis ke setiap bucket hasil mereka:

    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.objectAdmin
    

    Hal ini mengasumsikan bahwa pengguna yang memberikan akses memiliki peran Storage Admin (roles/storage.admin) untuk project yang berisi bucket Cloud Storage yang sedang dioperasikan.

Buat workload

Dalam panduan ini, Alex menyediakan kode untuk beban kerja dan membangun image Docker untuk memuatnya, tetapi siapa pun dapat mengambil peran ini, termasuk pihak ketiga.

Alex perlu membuat resource berikut untuk workload:

  • Kode yang menjalankan workload.

  • Repositori Docker di Artifact Registry, yang dapat diakses oleh akun layanan yang menjalankan workload.

  • Image Docker yang berisi dan menjalankan kode beban kerja.

Untuk membuat dan menyiapkan resource, selesaikan langkah-langkah berikut di project Alex:

  1. Beralih ke project Alex:

    gcloud config set project ALEX_PROJECT_ID
    
  2. Klik Open editor untuk membuka Cloud Shell Editor, lalu buat file baru bernama salary.go. Salin kode berikut ke dalam file, lalu simpan:

    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
    }
    
  3. Pastikan semua pihak membaca dan mengaudit kode sumber.

  4. Buat file bernama Dockerfile di Cloud Shell Editor yang berisi konten berikut:

    # 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"
    

    Dockerfile ini menggunakan build multi-tahap untuk mengompilasi kode Go terlebih dahulu, lalu menyalin kode yang dikompilasi tersebut ke container workload akhir. Selain itu, variabel lingkungan tertentu dapat digunakan dalam container workload tersebut. Nilai untuk variabel lingkungan ini dipetakan nanti ke resource tertentu yang dibutuhkan workload untuk beroperasi.

  5. Klik Open Terminal untuk kembali ke Cloud Shell, atau panggil terminal yang ada di Cloud Shell Editor dari menu View.

  6. Buat repositori Docker di Artifact Registry:

    gcloud artifacts repositories create REPOSITORY_NAME \
        --repository-format=docker \
        --location=us
    
  7. Berikan peran Pembaca Artifact Registry (roles/artifactregistry.reader) ke akun layanan yang akan menjalankan workload agar akun layanan tersebut dapat membaca dari repositori:

    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.reader
    
  8. Perbarui kredensial Docker Anda untuk menyertakan nama domain us-docker.pkg.dev:

    gcloud auth configure-docker us-docker.pkg.dev
    
  9. Buat image Docker dari Dockerfile dengan memasukkan perintah berikut di terminal:

    docker build -t \
        "us-docker.pkg.dev/ALEX_PROJECT_ID/\
    REPOSITORY_NAME/WORKLOAD_CONTAINER_NAME:latest" .
    
  10. Kirim image Docker ke Artifact Registry:

    docker push \
        us-docker.pkg.dev/ALEX_PROJECT_ID/REPOSITORY_NAME/WORKLOAD_CONTAINER_NAME
    
  11. Respons push Docker mencantumkan ringkasan SHA256 image, yang diperlukan nanti untuk mengizinkan workload. Ringkasan terlihat mirip dengan contoh berikut:

    sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
    

    Salin ringkasan gambar (termasuk awalan sha256:) ke tempat yang dapat Anda gunakan sebagai referensi. Anda juga dapat memasukkan ringkasan dalam contoh kode berikut untuk mengisi otomatis contoh kode lainnya dalam panduan ini yang memerlukan nilai:

    WORKLOAD_CONTAINER_IMAGE_DIGEST
    
  12. Pastikan semua pihak mengaudit image Docker dan memverifikasi bahwa image tersebut dapat dipercaya sebelum mengizinkan penggunaannya.

Memberi otorisasi workload

Setelah workload disetujui oleh kedua belah pihak, Alex dan Bola perlu menambahkan Pengesahan Google Cloud sebagai penyedia ke kumpulan identitas workload mereka. Penyedia menentukan layanan pengesahan yang akan digunakan, dan properti yang harus cocok dengan beban kerja agar diizinkan untuk beroperasi pada data Alex atau Bola. Jika pihak yang tidak bertanggung jawab mengubah image Docker, atau mengubah properti terukur lainnya, beban kerja akan ditolak aksesnya.

Panduan ini menggunakan pemetaan atribut untuk memberikan akses resource langsung ke workload berdasarkan ringkasan image. Namun, untuk situasi lain, Anda mungkin lebih memilih menggunakan peniruan identitas akun layanan untuk mengakses resource. Lihat Akses workload eksternal untuk mempelajari lebih lanjut.

Untuk menyiapkan penyedia bagi Alex dan Bola dengan kondisi yang diperlukan, selesaikan langkah-langkah berikut:

  1. Masukkan perintah berikut untuk membuat penyedia bagi 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'"
    
  2. Dapatkan nomor project Alex untuk perintah berikutnya:

    gcloud projects describe ALEX_PROJECT_ID --format="value(projectNumber)"
    
  3. Beri identitas gabungan yang ditentukan oleh penyedia Alex peran cloudkms.cryptoKeyDecrypter, dengan menentukan atribut image_digest sehingga hanya penampung workload dengan ringkasan yang ditentukan yang dapat mendekripsi kunci KMS-nya:

    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.cryptoKeyDecrypter
    
  4. Beralih ke project Bola:

    gcloud config set project BOLA_PROJECT_ID
    
  5. Masukkan perintah berikut untuk membuat penyedia untuk 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'"
    
  6. Dapatkan nomor project Bola untuk perintah berikutnya:

    gcloud projects describe BOLA_PROJECT_ID --format="value(projectNumber)"
    
  7. Beri identitas gabungan yang ditentukan oleh penyedia Bola peran cloudkms.cryptoKeyDecrypter, dengan menentukan atribut image_digest sehingga hanya penampung workload dengan ringkasan yang ditentukan yang dapat mendekripsi kunci KMS-nya:

    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
    

Menguji workload

Setelah penyedia ditambahkan ke workload identity pool Alex dan Bola, serta resource yang diperlukan tersedia, saatnya operator workload menguji workload.

Untuk menguji workload, Anda membuat instance Confidential VM baru di project Bola yang memiliki properti berikut:

Masukkan perintah berikut di Cloud Shell Bola untuk menguji beban kerja:

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"

Lihat progres

Anda dapat melihat progres workload di project Bola dengan membuka Logs Explorer.

Buka Logs Explorer

Untuk hanya menampilkan entri log Ruang Rahasia, filter menurut Kolom log berikut, jika tersedia:

  • Jenis resource: Instance VM

  • ID Instance: ID instance VM

  • Nama log: confidential-space-launcher

Untuk memuat ulang log, klik Lompat ke sekarang. Anda juga dapat men-scroll ke hasil sebelumnya, lalu men-scroll ke akhir log lagi untuk memuat entri terbaru.

Melihat hasil

Jika tugas beban kerja berakhir dan menampilkan 0, berarti tidak ada error yang terjadi dan saatnya memeriksa output di bucket output Alex dan Bola:

  1. Beralih ke project Alex:

    gcloud config set project ALEX_PROJECT_ID
    
  2. Mencantumkan semua file di bucket hasilnya:

    gcloud storage ls gs://ALEX_OUTPUT_BUCKET_NAME
    
  3. Baca file terbaru yang tercantum, ganti ALEX_OUTPUT_CLOUD_STORAGE_PATH dengan jalur file, termasuk gs://:

    gcloud storage cat ALEX_OUTPUT_CLOUD_STORAGE_PATH
    

    Jika tidak ada file, Anda perlu men-debug beban kerja.

  4. Beralih ke project Bola:

    gcloud config set project BOLA_PROJECT_ID
    
  5. Mencantumkan semua file di bucket hasilnya:

    gcloud storage ls gs://BOLA_OUTPUT_BUCKET_NAME
    
  6. Baca file terbaru yang tercantum, ganti BOLA_RESULTS_CLOUD_STORAGE_PATH dengan jalur file, termasuk gs://:

    gcloud storage cat BOLA_RESULTS_CLOUD_STORAGE_PATH
    

    Jika tidak ada file, Anda perlu men-debug beban kerja.

  7. Setelah berhasil membaca hasilnya, hentikan instance VM:

    gcloud compute instances stop WORKLOAD_VM_2_NAME --zone=us-west1-b
    

Dengan membaca file, Alex dan Bola masing-masing mengetahui siapa yang berpenghasilan lebih tinggi tanpa pernah mengungkapkan gaji mereka satu sama lain.

Men-debug dan memulai ulang workload

Lingkungan Confidential Space memiliki banyak bagian, dan ada kemungkinan sesuatu telah dikonfigurasi secara tidak benar sehingga menyebabkan workload gagal.

Tidak seperti image Confidential Space produksi, image debug membuat instance VM tetap berjalan setelah workload selesai. Artinya, jika log tidak mengungkapkan cukup banyak informasi untuk menyelesaikan masalah Anda, langkah berikutnya adalah menghubungkan ke instance VM Anda melalui SSH dan melanjutkan proses debug.

Setelah Anda selesai men-debug, hentikan instance VM:

gcloud compute instances stop WORKLOAD_VM_2_NAME --zone=us-west1-b

Untuk menjalankan workload terhadap lingkungan yang di-debug, mulai VM lagi:

gcloud compute instances start WORKLOAD_VM_2_NAME --zone=us-west1-b

Memperkuat lingkungan untuk produksi

Setelah Anda berhasil menguji workload, saatnya memperkuat lingkungan Confidential Space untuk deployment produksi. Alex dan Bola perlu menambahkan pernyataan support_attributes ke penyedia mereka untuk memverifikasi bahwa image Confidential Space produksi digunakan untuk beban kerja:

  1. Beralih ke project Alex:

    gcloud config set project ALEX_PROJECT_ID
    
  2. Masukkan perintah berikut untuk memperbarui penyedia untuk 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"
    
  3. Beralih ke project Bola:

    gcloud config set project BOLA_PROJECT_ID
    
  4. Masukkan perintah berikut untuk memperbarui penyedia untuk 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"
    

Men-deploy workload produksi

Bola perlu membuat instance VM terpisah untuk menjalankan workload produksi. Hal-hal berikut berbeda dibandingkan dengan workload pengujian:

  • OS ini didasarkan pada image Confidential Space produksi. Hal ini akan menonaktifkan SSH, dan instance VM akan berhenti setelah beban kerja selesai.

  • Pengalihan logging dihapus. Hanya log dasar yang tidak mengekspos informasi sensitif yang ditampilkan di Cloud Logging.

Masukkan perintah berikut di Cloud Shell Bola untuk men-deploy beban kerja produksi:

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"

Cara Anda melihat progres dan melihat hasilnya sama seperti saat Anda menguji beban kerja.

Setelah beban kerja produksi selesai, instance VM akan berhenti. Untuk melihat hasil yang berbeda, Anda dapat mengubah gaji, mengenkripsinya kembali, menguploadnya kembali ke bucket Cloud Storage masing-masing, lalu memulai ulang instance VM untuk menjalankan workload lagi:

gcloud compute instances start WORKLOAD_VM_NAME --zone=us-west1-b

Pembersihan

Untuk menghapus resource yang dibuat dalam panduan ini, selesaikan petunjuk berikut.

Membersihkan resource Alex

  1. Beralih ke project Alex:

    gcloud config set project ALEX_PROJECT_ID
    
  2. Hapus workload identity pool Alex:

    gcloud iam workload-identity-pools delete ALEX_POOL_NAME \
        --location=global
    
  3. Hapus bucket Cloud Storage Alex:

    gcloud storage rm gs://ALEX_INPUT_BUCKET_NAME \
        gs://ALEX_OUTPUT_BUCKET_NAME --recursive
    
  4. Hapus file gaji Alex, kode Go, dan Dockerfile:

    rm ALEX_SALARY.txt \
        ALEX_ENCRYPTED_SALARY_FILE \
        salary.go \
        Dockerfile
    
  5. Opsional: Nonaktifkan atau hancurkan kunci Cloud Key Management Service Alex.

  6. Opsional: Hentikan project Alex.

Membersihkan resource Bola

  1. Beralih ke project Bola:

    gcloud config set project BOLA_PROJECT_ID
    
  2. Hapus VM yang menjalankan alur kerja pengujian:

    gcloud compute instances delete WORKLOAD_VM_2_NAME --zone=us-west1-b
    
  3. Hapus VM yang menjalankan alur kerja produksi:

    gcloud compute instances delete WORKLOAD_VM_NAME --zone=us-west1-b
    
  4. Hapus akun layanan yang menjalankan workload:

    gcloud iam service-accounts delete \
        WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com
    
  5. Hapus workload identity pool Bola:

    gcloud iam workload-identity-pools delete BOLA_POOL_NAME \
        --location=global
    
  6. Hapus bucket Cloud Storage Bola:

    gcloud storage rm gs://BOLA_INPUT_BUCKET_NAME \
        gs://BOLA_OUTPUT_BUCKET_NAME --recursive
    
  7. Hapus file gaji Bola:

    rm BOLA_SALARY.txt \
        BOLA_ENCRYPTED_SALARY_FILE
    
  8. Opsional: Nonaktifkan atau hancurkan kunci Cloud Key Management Service Bola.

  9. Opsional: Hentikan project Bola.