Dalam panduan ini, Alex dan Bola ingin mengetahui siapa yang memiliki gaji tertinggi tanpa mengungkapkan angka kepada satu sama lain. Mereka memutuskan untuk menggunakan Confidential Space untuk menjaga data mereka tetap rahasia, dan setuju untuk mengambil peran berikut:
Alex: Kolaborator data, penulis beban kerja
Bola: Kolaborator data, operator beban kerja
Pengaturan ini dirancang agar semuanya tetap semudah mungkin untuk panduan ini. Namun, penulis dan operator workload 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 di satu organisasi dengan akses ke beberapa project, sehingga Anda dapat merasakan seluruh prosesnya. Dalam deployment produksi, kolaborator, penulis beban kerja, dan operator beban kerja memiliki akun terpisah dan project mereka sendiri yang terdapat dalam organisasi terpisah, yang tidak dapat diakses satu sama lain dan menjaga data rahasia mereka tetap terpisah.
Ruang Rahasia 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.
API yang diperlukan
Anda harus mengaktifkan API berikut di project yang ditentukan agar dapat menyelesaikan panduan ini.
Nama API | Judul API | Aktifkan di project ini |
---|---|---|
cloudkms.googleapis.com |
Cloud KMS | Kolaborator data (project Alex dan Bola) |
iamcredentials.googleapis.com |
IAM Service Account Credentials API |
Kolaborator data (project Alex) Dalam panduan ini, hanya Alex yang perlu mengaktifkan API ini. Namun, jika lebih dari dua pihak terlibat, IAM Service Account Credentials API perlu diaktifkan di setiap project kolaborator data yang tidak menghosting akun layanan beban kerja. |
artifactregistry.googleapis.com |
Artifact Registry | Penulis beban kerja (project Alex) |
compute.googleapis.com |
Compute Engine | Operator workload (project Bola) |
confidentialcomputing.googleapis.com |
Confidential Computing | Operator workload (project Bola) |
Peran yang diperlukan
Untuk mendapatkan izin yang Anda perlukan untuk menyelesaikan panduan ini, minta administrator untuk memberi Anda peran IAM berikut pada project:
-
Cloud KMS Admin (
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). -
Admin Akun Layanan (
roles/iam.serviceAccountAdmin
) untuk kolaborator data (Alex dan Bola). -
Storage Admin (
roles/storage.admin
) untuk kolaborator data (Alex dan Bola) dan operator beban kerja (Bola). -
Compute Admin (
roles/compute.admin
) untuk operator beban kerja (Bola). -
Security Admin (
roles/securityAdmin
) untuk operator beban kerja (Bola). -
Administrator Artifact Registry (
roles/artifactregistry.admin
) untuk penulis workload (Alex).
Untuk mengetahui informasi selengkapnya tentang cara memberikan 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 menjaga kerahasiaannya.
Bucket Cloud Storage untuk menyimpan data terenkripsi.
Akun layanan yang memiliki akses ke kunci enkripsi, sehingga dapat mendekripsi data rahasia.
Identitas kumpulan beban kerja dengan akun layanan yang terhubung ke akun tersebut. Workload yang memproses data rahasia menggunakan kumpulan untuk meniru akun layanan dan mengambil data yang tidak dienkripsi.
Untuk memulai, buka konsol Google Cloud:
Menyiapkan resource Alex
Untuk menyiapkan resource bagi Alex, selesaikan petunjuk berikut.
- Klik Aktifkan Cloud Shell.
-
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
-
Beralih ke project yang baru dibuat:
gcloud config set project ALEX_PROJECT_ID
-
Jika Anda belum melakukannya, aktifkan API yang diperlukan Alex sebagai collaborator data dan penulis workload:
gcloud services enable cloudkms.googleapis.com artifactregistry.googleapis.com iamcredentials.googleapis.com
-
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
-
Berikan peran
cloudkms.cryptoKeyEncrypter
kepada Alex agar ia 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
-
Buat akun layanan yang nantinya akan digunakan oleh workload untuk mendekripsi data:
gcloud iam service-accounts create ALEX_SERVICE_ACCOUNT_NAME
-
Berikan peran
cloudkms.cryptoKeyDecrypter
kepada akun layanan agar dapat menggunakan kunci enkripsi yang baru saja Anda buat untuk mendekripsi data:gcloud kms keys add-iam-policy-binding \ projects/ALEX_PROJECT_ID/locations/global/keyRings/ALEX_KEYRING_NAME/cryptoKeys/ALEX_KEY_NAME \ --member=serviceAccount:ALEX_SERVICE_ACCOUNT_NAME@ALEX_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/cloudkms.cryptoKeyDecrypter
-
Buat workload identity pool, lalu hubungkan akun layanan ke workload identity pool tersebut dengan peran
iam.workloadIdentityUser
:gcloud iam workload-identity-pools create ALEX_POOL_NAME \ --location=global
gcloud iam service-accounts add-iam-policy-binding \ ALEX_SERVICE_ACCOUNT_NAME@ALEX_PROJECT_ID.iam.gserviceaccount.com \ --member="principalSet://iam.googleapis.com/projects/"$(gcloud projects describe ALEX_PROJECT_ID \ --format="value(projectNumber)")"/locations/global/workloadIdentityPools/ALEX_POOL_NAME/*" \ --role=roles/iam.workloadIdentityUser
-
Buat bucket Cloud Storage untuk data input, dan bucket lain untuk menyimpan hasilnya:
gcloud storage buckets create gs://ALEX_INPUT_BUCKET_NAME \ gs://ALEX_RESULTS_BUCKET_NAME
-
Buat file yang hanya berisi gaji Alex sebagai angka:
echo 123456 > ALEX_SALARY.txt
-
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.
-
Di Cloud Shell, masukkan perintah berikut untuk membuat project untuk Bola, dengan mengganti BOLA_PROJECT_ID dengan nama pilihan Anda:
gcloud projects create BOLA_PROJECT_ID
-
Beralih ke project yang baru dibuat:
gcloud config set project BOLA_PROJECT_ID
-
Jika Anda belum melakukannya, aktifkan API yang diperlukan Bola sebagai collaborator data dan operator workload:
gcloud services enable cloudkms.googleapis.com compute.googleapis.com confidentialcomputing.googleapis.com
-
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
-
Berikan peran
cloudkms.cryptoKeyEncrypter
kepada Bola 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
-
Buat akun layanan yang nantinya akan digunakan oleh workload untuk mendekripsi data:
gcloud iam service-accounts create BOLA_SERVICE_ACCOUNT_NAME
-
Berikan peran
cloudkms.cryptoKeyDecrypter
kepada akun layanan agar dapat menggunakan kunci enkripsi yang baru saja Anda buat untuk mendekripsi data:gcloud kms keys add-iam-policy-binding \ projects/BOLA_PROJECT_ID/locations/global/keyRings/BOLA_KEYRING_NAME/cryptoKeys/BOLA_KEY_NAME \ --member=serviceAccount:BOLA_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/cloudkms.cryptoKeyDecrypter
-
Buat workload identity pool, lalu hubungkan akun layanan ke workload identity pool tersebut dengan peran
iam.workloadIdentityUser
:gcloud iam workload-identity-pools create BOLA_POOL_NAME \ --location=global
gcloud iam service-accounts add-iam-policy-binding \ BOLA_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com \ --member="principalSet://iam.googleapis.com/projects/"$(gcloud projects describe BOLA_PROJECT_ID \ --format="value(projectNumber)")"/locations/global/workloadIdentityPools/BOLA_POOL_NAME/*" \ --role=roles/iam.workloadIdentityUser
-
Buat bucket Cloud Storage untuk data input, dan bucket lain untuk menyimpan hasilnya:
gcloud storage buckets create gs://BOLA_INPUT_BUCKET_NAME \ gs://BOLA_RESULTS_BUCKET_NAME
-
Buat file yang hanya berisi gaji Bola sebagai angka:
echo 111111 > BOLA_SALARY.txt
-
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
Membuat akun layanan untuk workload
Selain akun layanan yang disiapkan Alex dan Bola untuk mendekripsi data mereka, akun layanan lain diperlukan untuk menjalankan beban kerja. Karena akun layanan digunakan untuk mendekripsi data rahasia dan memprosesnya, visibilitas data dibatasi untuk pemiliknya.
Dalam panduan ini, Bola mengoperasikan dan menjalankan beban kerja, tetapi siapa saja dapat mengambil peran ini, termasuk pihak ketiga.
Selesaikan langkah-langkah berikut di project Bola untuk menyiapkan akun layanan:
Buat akun layanan untuk menjalankan beban kerja:
gcloud iam service-accounts create WORKLOAD_SERVICE_ACCOUNT_NAME
Berikan peran
iam.serviceAccountUser
kepada Bola untuk meniru akun layanan, yang diperlukan agar ia dapat membuat VM workload 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
Berikan peran
confidentialcomputing.workloadUser
kepada 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
Berikan peran
logging.logWriter
ke akun layanan 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
Berikan 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://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://ALEX_RESULTS_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_RESULTS_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.
Membuat workload
Dalam panduan ini, Alex menyediakan kode untuk beban kerja dan mem-build image Docker untuk menyimpannya, tetapi siapa pun dapat mengambil peran ini, termasuk pihak ketiga.
Alex perlu membuat resource berikut untuk workload:
Kode yang menjalankan beban kerja.
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 dalam project Alex:
Beralih ke project Alex:
gcloud config set project ALEX_PROJECT_ID
Buat repositori Docker di Artifact Registry:
gcloud artifacts repositories create REPOSITORY_NAME \ --repository-format=docker \ --location=us
Berikan peran Pembaca Artifact Registry (
roles/artifactregistry.reader
) ke akun layanan yang akan menjalankan beban kerja agar 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
Klik Open editor untuk membuka Editor Cloud Shell, lalu buat file baru bernama
salary.go
. Salin kode berikut ke dalam file, lalu simpan:// READ ME FIRST: Before compiling, customize the details in the USER VARIABLES // SECTION starting at line 30. package main import ( kms "cloud.google.com/go/kms/apiv1" "cloud.google.com/go/storage" "context" "fmt" "google.golang.org/api/option" kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" "io/ioutil" "strconv" "strings" "time" ) type collaborator struct { name string wipName string sa string keyName string inputBucket string inputFile string outputBucket string outputFile string } // ============================ // START USER VARIABLES SECTION // You need to customize this section, replacing each const's value with your // own. // To get a project number, use the following command, and substitute // <PROJECT_ID> for the data collaborator's project ID. // gcloud projects describe <PROJECT_ID> --format="value(projectNumber)" // Alex's values const collaborator1Name string = "Alex" // Alex's name const collaborator1EncryptedSalaryFileName string = "" // The name of Alex's encrypted salary file const collaborator1BucketInputName string = "" // The name of the storage bucket that contains Alex's encrypted salary file const collaborator1BucketOutputName string = "" // The name of the storage bucket to store Alex's results in const collaborator1BucketOutputFileName string = "" // The name of Alex's output file that contains the results const collaborator1KMSKeyringName string = "" // Alex's Key Management Service key ring const collaborator1KMSKeyName string = "" // Alex's Key Management Service key const collaborator1ProjectName string = "" // Alex's project ID const collaborator1ProjectNumber string = "" // Alex's project number const collaborator1PoolName string = "" // Alex's workload identity pool name const collaborator1ServiceAccountName string = "" // The name of Alex's service account that can decrypt their salary // Bola's values const collaborator2Name string = "Bola" // Bola's name const collaborator2EncryptedSalaryFileName string = "" // The name of Bola's encrypted salary file const collaborator2BucketInputName string = "" // The name of the storage bucket that contains Bola's encrypted salary file const collaborator2BucketOutputName string = "" // The name of the storage bucket to store Bola's results in const collaborator2BucketOutputFileName string = "" // The name of Bola's output file that contains the results const collaborator2KMSKeyringName string = "" // Bola's Key Management Service key ring const collaborator2KMSKeyName string = "" // Bola's Key Management Service key const collaborator2ProjectName string = "" // Bola's project ID const collaborator2ProjectNumber string = "" // Bola's project number const collaborator2PoolName string = "" // Bola's workload identity pool name const collaborator2ServiceAccountName string = "" // The name of Bola's service account that can decrypt their salary // END USER VARIABLES SECTION // ========================== var collaborators = [2]collaborator{ { collaborator1Name, "projects/" + collaborator1ProjectNumber + "/locations/global/workloadIdentityPools/" + collaborator1PoolName + "/providers/attestation-verifier", collaborator1ServiceAccountName + "@" + collaborator1ProjectName + ".iam.gserviceaccount.com", "projects/" + collaborator1ProjectName + "/locations/global/keyRings/" + collaborator1KMSKeyringName + "/cryptoKeys/" + collaborator1KMSKeyName, collaborator1BucketInputName, collaborator1EncryptedSalaryFileName, collaborator1BucketOutputName, collaborator1BucketOutputFileName, }, { collaborator2Name, "projects/" + collaborator2ProjectNumber + "/locations/global/workloadIdentityPools/" + collaborator2PoolName + "/providers/attestation-verifier", collaborator2ServiceAccountName + "@" + collaborator2ProjectName + ".iam.gserviceaccount.com", "projects/" + collaborator2ProjectName + "/locations/global/keyRings/" + collaborator2KMSKeyringName + "/cryptoKeys/" + collaborator2KMSKeyName, collaborator2BucketInputName, collaborator2EncryptedSalaryFileName, collaborator2BucketOutputName, collaborator2BucketOutputFileName, }, } 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" }, "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s:generateAccessToken" }` 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 = "earns same\n" } now := time.Now() for _, cw := range collaborators { outputWriter := storageClient.Bucket(cw.outputBucket).Object(fmt.Sprintf("%s-%d", cw.outputFile, 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.sa, 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, trustedServiceAccountEmail, wippro string, encryptedData []byte) ([]byte, error) { cc := fmt.Sprintf(credentialConfig, wippro, trustedServiceAccountEmail) 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 := ioutil.ReadAll(objectReader) if err != nil { return nil, err } return s, nil }
Ubah
USER VARIABLES SECTION
dalam kode sumber, ganti nilaiconst
kosong dengan nama resource yang relevan seperti yang dijelaskan dalam komentar kode. Jika Anda telah mengedit variabel placeholder sepertiALEX_PROJECT_ID
yang ditampilkan dalam panduan ini, nilainya disertakan dalam contoh kode berikut, yang dapat Anda salin dan tempel di atas kode yang ada:// Alex's values const collaborator1Name string = "Alex" // Alex's name const collaborator1EncryptedSalaryFileName string = "ALEX_ENCRYPTED_SALARY_FILE" // The name of Alex's encrypted salary file const collaborator1BucketInputName string = "ALEX_INPUT_BUCKET_NAME" // The name of the storage bucket that contains Alex's encrypted salary file const collaborator1BucketOutputName string = "ALEX_RESULTS_BUCKET_NAME" // The name of the storage bucket to store Alex's results in const collaborator1BucketOutputFileName string = "ALEX_RESULTS_FILE_NAME" // The name of Alex's output file that contains the results const collaborator1KMSKeyringName string = "ALEX_KEYRING_NAME" // Alex's Key Management Service key ring const collaborator1KMSKeyName string = "ALEX_KEY_NAME" // Alex's Key Management Service key const collaborator1ProjectName string = "ALEX_PROJECT_ID" // Alex's project ID const collaborator1ProjectNumber string = "ALEX_PROJECT_NUMBER" // Alex's project number const collaborator1PoolName string = "ALEX_POOL_NAME" // Alex's workload identity pool name const collaborator1ServiceAccountName string = "ALEX_SERVICE_ACCOUNT_NAME" // The name of Alex's service account that can decrypt their salary // Bola's values const collaborator2Name string = "Bola" // Bola's name const collaborator2EncryptedSalaryFileName string = "BOLA_ENCRYPTED_SALARY_FILE" // The name of Bola's encrypted salary file const collaborator2BucketInputName string = "BOLA_INPUT_BUCKET_NAME" // The name of the storage bucket that contains Bola's encrypted salary file const collaborator2BucketOutputName string = "BOLA_RESULTS_BUCKET_NAME" // The name of the storage bucket to store Bola's results in const collaborator2BucketOutputFileName string = "BOLA_RESULTS_FILE_NAME" // The name of Bola's output file that contains the results const collaborator2KMSKeyringName string = "BOLA_KEYRING_NAME" // Bola's Key Management Service key ring const collaborator2KMSKeyName string = "BOLA_KEY_NAME" // Bola's Key Management Service key const collaborator2ProjectName string = "BOLA_PROJECT_ID" // Bola's project ID const collaborator2ProjectNumber string = "BOLA_PROJECT_NUMBER" // Bola's project number const collaborator2PoolName string = "BOLA_POOL_NAME" // Bola's workload identity pool name const collaborator2ServiceAccountName string = "BOLA_SERVICE_ACCOUNT_NAME" // The name of Bola's service account that can decrypt their salary
Pastikan untuk memperbarui nomor project Alex dan Bola juga. Anda dapat mengambilnya dengan perintah berikut:
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
Pastikan semua pihak membaca dan mengaudit kode sumber.
Klik Terminal > New Terminal untuk membuka terminal dalam Cloud Shell Editor.
Masukkan perintah berikut di terminal untuk menyiapkan lingkungan Go:
go mod init salary 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
Masukkan perintah berikut untuk mengompilasi kode sumber ke biner yang ditautkan secara statis:
CGO_ENABLED=0 go build -trimpath
Buat file bernama
Dockerfile
di Cloud Shell Editor yang berisi konten berikut:FROM alpine:latest WORKDIR /test COPY salary /test ENTRYPOINT ["/test/salary"] CMD []
Perbarui kredensial Docker Anda untuk menyertakan nama domain
us-docker.pkg.dev
:gcloud auth configure-docker us-docker.pkg.dev
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 .
Kirim image Docker ke Artifact Registry:
docker push \ us-docker.pkg.dev/ALEX_PROJECT_ID/REPOSITORY_NAME/WORKLOAD_CONTAINER_NAME
Dari respons push Docker, salin ringkasan image Docker (termasuk awalan
sha256:
) ke tempat yang aman untuk digunakan nanti.Pastikan semua pihak mengaudit image Docker dan memverifikasi bahwa image tersebut dapat dipercaya sebelum mengizinkan penggunaannya.
Memberi otorisasi pada workload
Dengan workload yang disetujui oleh kedua belah pihak, Alex dan Bola perlu menambahkan layanan verifier pengesahan Confidential Space sebagai penyedia ke workload identity pool mereka. Hal ini memungkinkan akun layanan yang terpasang ke beban kerja meniru akun layanan yang terhubung ke kumpulannya dan mengakses datanya, dengan syarat kondisi atribut tertentu terpenuhi. Artinya, kondisi atribut berfungsi sebagai kebijakan pengesahan.
Kondisi atribut yang digunakan dalam panduan ini adalah sebagai berikut:
Ringkasan image Docker yang sedang dijalankan
Alamat email akun layanan yang menjalankan beban kerja
Jika pelaku berbahaya mengubah image Docker, atau akun layanan yang berbeda disertakan ke beban kerja, beban kerja tidak akan diizinkan untuk mengakses data Alex atau Bola.
Untuk melihat kondisi atribut yang tersedia, lihat Pernyataan pengesahan.
Untuk menyiapkan penyedia bagi Alex dan Bola dengan kondisi yang diperlukan, selesaikan langkah-langkah berikut:
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=assertion.sub" \ --attribute-condition="assertion.submods.container.image_digest == 'DOCKER_IMAGE_DIGEST' \ && 'WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts \ && assertion.swname == 'CONFIDENTIAL_SPACE' \ && 'STABLE' in assertion.submods.confidential_space.support_attributes"
Beralih ke project Bola:
gcloud config set project BOLA_PROJECT_ID
Masukkan perintah berikut untuk membuat penyedia 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=assertion.sub" \ --attribute-condition="assertion.submods.container.image_digest == 'DOCKER_IMAGE_DIGEST' \ && 'WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts \ && assertion.swname == 'CONFIDENTIAL_SPACE' \ && 'STABLE' in assertion.submods.confidential_space.support_attributes"
Men-deploy workload
Dengan penyedia yang ditambahkan ke workload identity pool Alex dan Bola serta resource yang diperlukan, saatnya operator beban kerja menjalankan beban kerja.
Untuk men-deploy workload, buat instance Confidential VM baru di project Bola yang memiliki properti berikut:
Konfigurasi yang didukung untuk instance AMD SEV atau Intel TDX Confidential VM.
OS berdasarkan image Confidential Space.
Booting Aman diaktifkan.
Image Docker yang dilampirkan yang dibuat Alex sebelumnya.
Akun layanan terlampir yang menjalankan beban kerja.
Masukkan perintah berikut di Cloud Shell Bola untuk men-deploy beban kerja:
gcloud compute instances create WORKLOAD_VM_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 \
--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"
Anda dapat melihat progres beban kerja di project Bola dengan membuka Logs Explorer.
Untuk menemukan log Confidential Space, 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 Langsung ke sekarang.
Setelah beban kerja selesai, instance VM akan berhenti. Jika ingin mengubah file gaji terenkripsi dan men-deploy workload lagi, Anda hanya perlu memulai VM yang ada:
gcloud compute instances start WORKLOAD_VM_NAME --zone=us-west1-b
Men-debug workload
Anda dapat menggunakan Logs Explorer untuk memecahkan masalah seperti resource yang tidak disiapkan dengan benar, atau kondisi atribut di penyedia yang tidak cocok dengan klaim yang dibuat oleh workload Confidential Space.
Untuk melakukannya, Anda perlu melakukan perubahan berikut:
Perbarui penyedia workload identity pool Alex dan Bola untuk menghapus pernyataan
support_attributes
. Anda perlu menggunakan image debug Confidential Space untuk melakukan pemecahan masalah yang lebih mendalam, dan image tersebut tidak memiliki atribut dukungan untuk diverifikasi.Buat VM workload menggunakan image debug Confidential Space, dan tetapkan metadata VM untuk mengalihkan
STDOUT
danSTDERR
ke Cloud Logging untuk mengambil semua output dari workload.
Untuk melakukan perubahan, selesaikan langkah-langkah berikut:
Beralih ke project Alex:
gcloud config set project ALEX_PROJECT_ID
Perbarui penyedia Alex untuk menghapus pernyataan
support_attributes
: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=assertion.sub" \ --attribute-condition="assertion.submods.container.image_digest == 'DOCKER_IMAGE_DIGEST' \ && 'WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts \ && assertion.swname == 'CONFIDENTIAL_SPACE'"
Beralih ke project Bola:
gcloud config set project BOLA_PROJECT_ID
Perbarui penyedia Bola untuk menghapus pernyataan
support_attributes
: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=assertion.sub" \ --attribute-condition="assertion.submods.container.image_digest == 'DOCKER_IMAGE_DIGEST' \ && 'WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts \ && assertion.swname == 'CONFIDENTIAL_SPACE'"
Buat VM baru dengan image debug Confidential Space, dan
tee-container-log-redirect
ditetapkan ketrue
dalam metadata.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"
Tidak seperti image produksi, image debug membuat VM tetap berjalan setelah workload selesai. Artinya, Anda dapat menggunakan SSH untuk terhubung ke VM guna melanjutkan proses debug.
Melihat hasil
Setelah beban kerja berhasil diselesaikan, Alex dan Bola dapat melihat hasilnya di bucket hasil masing-masing:
Beralih ke project Alex:
gcloud config set project ALEX_PROJECT_ID
Cantumkan semua file dalam bucket hasilnya:
gcloud storage ls gs://ALEX_RESULTS_BUCKET_NAME
Kemudian, baca file terbaru:
gcloud storage cat gs://ALEX_RESULTS_BUCKET_NAME/ALEX_RESULTS_FILE_NAME
Beralih ke project Bola:
gcloud config set project BOLA_PROJECT_ID
Untuk Bola, cantumkan semua file di bucket hasilnya:
gcloud storage ls gs://BOLA_RESULTS_BUCKET_NAME
Kemudian, baca file terbaru:
gcloud storage cat gs://BOLA_RESULTS_BUCKET_NAME/BOLA_RESULTS_FILE_NAME
Dengan membaca file tersebut, Alex dan Bola masing-masing mengetahui siapa yang berpenghasilan lebih tinggi tanpa mengungkapkan gaji mereka kepada satu sama lain.
Pembersihan
Untuk menghapus resource yang dibuat dalam panduan ini, selesaikan petunjuk berikut.
Membersihkan resource Alex
Beralih ke project Alex:
gcloud config set project ALEX_PROJECT_ID
Hapus akun layanan yang mendekripsi data Alex:
gcloud iam service-accounts delete \ ALEX_SERVICE_ACCOUNT_NAME@ALEX_PROJECT_ID.iam.gserviceaccount.com
Hapus workload identity pool Alex:
gcloud iam workload-identity-pools delete ALEX_POOL_NAME \ --location=global
Hapus bucket Cloud Storage Alex:
gcloud storage rm gs://ALEX_INPUT_BUCKET_NAME \ gs://ALEX_RESULTS_BUCKET_NAME --recursive
Hapus file gaji Alex dan kode Go:
rm ALEX_SALARY.txt \ ALEX_ENCRYPTED_SALARY_FILE \ salary.go salary \ go.mod go.sum
Opsional: Nonaktifkan atau hancurkan kunci Cloud Key Management Service Alex.
Opsional: Nonaktifkan project Alex.
Membersihkan resource Bola
Beralih ke project Bola:
gcloud config set project BOLA_PROJECT_ID
Hapus VM workload:
gcloud compute instances delete WORKLOAD_VM_NAME --zone=us-west1-b
Hapus akun layanan yang mendekripsi data Bola dan akun layanan yang menjalankan beban kerja:
gcloud iam service-accounts delete \ BOLA_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com
gcloud iam service-accounts delete \ WORKLOAD_SERVICE_ACCOUNT_NAME@BOLA_PROJECT_ID.iam.gserviceaccount.com
Hapus workload identity pool Bola:
gcloud iam workload-identity-pools delete BOLA_POOL_NAME \ --location=global
Hapus bucket Cloud Storage Bola:
gcloud storage rm gs://BOLA_INPUT_BUCKET_NAME \ gs://BOLA_RESULTS_BUCKET_NAME --recursive
Hapus file gaji Bola:
rm BOLA_SALARY.txt \ BOLA_ENCRYPTED_SALARY_FILE
Opsional: Nonaktifkan atau hancurkan kunci Cloud Key Management Service Bola.
Opsional: Matikan project Bola.