1. ภาพรวม
ก่อนที่เราจะเริ่ม แม้ว่าไม่จำเป็นทั้งหมด แต่ความรู้เกี่ยวกับฟีเจอร์และแนวคิดต่อไปนี้จะเป็นประโยชน์ในโค้ดแล็บนี้
- Cloud Storage โดยเฉพาะที่เก็บข้อมูล
- Compute Engine โดยเฉพาะ Confidential VM
- บัญชีบริการ
- คอนเทนเนอร์และที่เก็บข้อมูลระยะไกล
- การรวมศูนย์ข้อมูล Workload Identity และเงื่อนไขแอตทริบิวต์

สิ่งที่คุณจะได้เรียนรู้
ห้องทดลองนี้มีการใช้งานอ้างอิงสำหรับการลงนามในบล็อกเชนที่สอดคล้องกับ MPC โดยใช้ Confidential Space เพื่ออธิบายแนวคิด เราจะยกตัวอย่างสถานการณ์ที่บริษัท Primus ต้องการโอนชิ้นงานดิจิทัลไปยังบริษัท Secundus ในสถานการณ์นี้ บริษัท Primus ใช้โมเดลที่สอดคล้องกับ MPC ซึ่งหมายความว่าบริษัทใช้การแชร์คีย์แบบกระจายแทนการใช้คีย์ส่วนตัวแต่ละรายการ โดยคีย์แชร์เหล่านี้จะถือครองโดยหลายฝ่าย ในกรณีนี้คืออลิซและบ็อบ แนวทางนี้ช่วยให้ Company Primus ได้รับประโยชน์หลายประการ ซึ่งรวมถึงประสบการณ์ของผู้ใช้ที่ง่ายขึ้น ประสิทธิภาพในการดำเนินงาน และการควบคุมคีย์ส่วนตัว
เพื่ออธิบายแง่มุมพื้นฐานของกระบวนการนี้ เราจะอธิบายรายละเอียดการตั้งค่าทางเทคนิคและแนะนำขั้นตอนการอนุมัติและการลงนามที่จะเริ่มการโอนชิ้นงานดิจิทัลจากบริษัท Primus ไปยังบริษัท Secundus โปรดทราบว่าบัญชาและขวัญใจซึ่งเป็นพนักงานของบริษัทไพรมัสทั้งคู่ต้องอนุมัติธุรกรรม
แม้ว่าการติดตั้งใช้งานอ้างอิงนี้จะแสดงการดำเนินการลายเซ็น แต่ก็ไม่ได้ครอบคลุมทุกด้านของการจัดการคีย์ MPC เช่น เราจะไม่พูดถึงการสร้างคีย์ นอกจากนี้ ยังมีแนวทางอื่นและแนวทางเสริม เช่น การใช้บริการที่ไม่ใช่ Google Cloud เพื่อสร้างลายเซ็นร่วม หรือให้ผู้ร่วมลงนามสร้างลายเซ็นบล็อกเชนในสภาพแวดล้อมของตนเอง ซึ่งเป็นสถาปัตยกรรมแบบกระจายศูนย์มากกว่า เราหวังว่าห้องทดลองนี้จะสร้างแรงบันดาลใจให้เกิดแนวทางต่างๆ ในการใช้ MPC บน Google Cloud
คุณจะทำงานกับเวิร์กโหลดอย่างง่ายที่ลงนามในธุรกรรม Ethereum ใน Confidential Space โดยใช้วัสดุคีย์ผู้ร่วมลงนาม การลงนามธุรกรรม Ethereum เป็นกระบวนการที่ผู้ใช้สามารถให้สิทธิ์ธุรกรรมในบล็อกเชน Ethereum หากต้องการส่งธุรกรรม Ethereum คุณต้องลงนามด้วยคีย์ส่วนตัว ซึ่งเป็นการพิสูจน์ว่าคุณเป็นเจ้าของบัญชีและอนุญาตให้ทำธุรกรรม กระบวนการลงนามมีดังนี้
- ผู้ส่งจะสร้างออบเจ็กต์ธุรกรรมที่ระบุที่อยู่ของผู้รับ จำนวน ETH ที่จะส่ง และข้อมูลอื่นๆ ที่เกี่ยวข้อง
- ระบบจะใช้คีย์ส่วนตัวของผู้ส่งเพื่อแฮชข้อมูลธุรกรรม
- จากนั้นระบบจะลงนามแฮชด้วยคีย์ส่วนตัว
- ระบบจะแนบลายเซ็นไปกับออบเจ็กต์ธุรกรรม
- ระบบจะกระจายธุรกรรมไปยังเครือข่าย Ethereum
เมื่อโหนดในเครือข่ายได้รับธุรกรรม โหนดจะยืนยันลายเซ็นเพื่อให้แน่ใจว่าเจ้าของบัญชีเป็นผู้ลงนาม หากลายเซ็นถูกต้อง โหนดจะเพิ่มธุรกรรมลงในบล็อกเชน
ก่อนอื่น คุณจะต้องกำหนดค่าทรัพยากรระบบคลาวด์ที่จำเป็น จากนั้นคุณจะเรียกใช้เวิร์กโหลดใน Confidential Space Codelab นี้จะแนะนำขั้นตอนระดับสูงต่อไปนี้
- วิธีกำหนดค่าทรัพยากรระบบคลาวด์ที่จำเป็นสำหรับการเรียกใช้ Confidential Space
- วิธีให้สิทธิ์เข้าถึงทรัพยากรที่มีการป้องกันตามแอตทริบิวต์ของ
- อะไร: คอนเทนเนอร์ของภาระงาน
- ที่ไหน: สภาพแวดล้อม Confidential Space (อิมเมจ Confidential Space ใน Confidential VM)
- ใคร: บัญชีที่เรียกใช้เวิร์กโหลด
- วิธีเรียกใช้เวิร์กโหลดใน VM ที่เป็นความลับซึ่งเรียกใช้อิมเมจ VM ของ Confidential Space
API ที่จำเป็น
คุณต้องเปิดใช้ API ต่อไปนี้ในโปรเจ็กต์ที่ระบุเพื่อให้ทำตามคำแนะนำนี้ได้
ชื่อ API | ชื่อ API |
cloudkms.googleapis.com | Cloud KMS |
compute.googleapis.com | Compute Engine |
confidentialcomputing.googleapis.com | Confidential Computing |
iamcredentials.googleapis.com | IAM |
artifactregistry.googleapis.com | Artifact Registry |
2. ตั้งค่าทรัพยากรระบบคลาวด์
ก่อนเริ่มต้น
- โคลน ที่เก็บนี้โดยใช้คำสั่งด้านล่างเพื่อรับสคริปต์ที่จำเป็นซึ่งใช้เป็นส่วนหนึ่งของ Codelab นี้
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
- เปลี่ยนไดเรกทอรีสำหรับ Codelab นี้
cd confidential-space/codelabs/digital_asset_transaction_codelab/scripts
- ตรวจสอบว่าคุณได้ตั้งค่าตัวแปรสภาพแวดล้อมของโปรเจ็กต์ที่จำเป็นตามที่แสดงด้านล่าง ดูข้อมูลเพิ่มเติมเกี่ยวกับการตั้งค่าโปรเจ็กต์ GCP ได้ที่ Codelab นี้ คุณดูรายละเอียดเกี่ยวกับวิธีดึงรหัสโปรเจ็กต์และวิธีที่รหัสโปรเจ็กต์แตกต่างจากชื่อโปรเจ็กต์และหมายเลขโปรเจ็กต์ได้ที่นี่ .
export PRIMUS_PROJECT_ID=<GCP project id>
- เปิดใช้การเรียกเก็บเงินสำหรับโปรเจ็กต์
- เปิดใช้ Confidential Computing API และ API ต่อไปนี้สำหรับทั้ง 2 โปรเจ็กต์
gcloud services enable \
cloudapis.googleapis.com \
cloudkms.googleapis.com \
cloudresourcemanager.googleapis.com \
cloudshell.googleapis.com \
container.googleapis.com \
containerregistry.googleapis.com \
iam.googleapis.com \
confidentialcomputing.googleapis.com
- หากต้องการตั้งค่าตัวแปรสำหรับชื่อทรัพยากร ให้ใช้คำสั่งต่อไปนี้ โปรดทราบว่าการดำเนินการนี้จะลบล้างชื่อทรัพยากรที่เฉพาะเจาะจงสำหรับโปรเจ็กต์ GCP ของบริษัท ก. เช่น
export PRIMUS_INPUT_STORAGE_BUCKET='primus-input-bucket' - คุณตั้งค่าตัวแปรต่อไปนี้สำหรับโปรเจ็กต์ GCP ในบริษัท ก. ได้
$PRIMUS_INPUT_STORAGE_BUCKET | ที่เก็บข้อมูลที่จัดเก็บคีย์ที่เข้ารหัส |
$PRIMUS_RESULT_STORAGE_BUCKET | ที่เก็บข้อมูลที่จัดเก็บผลลัพธ์ของธุรกรรม MPC |
$PRIMUS_KEY | คีย์ KMS ที่ใช้ในการเข้ารหัสข้อมูลที่จัดเก็บไว้ใน $PRIMUS_INPUT_STORAGE_BUCKET สำหรับ Primus Bank |
$PRIMUS_KEYRING | พวงกุญแจ KMS ที่จะใช้สร้างคีย์การเข้ารหัส $PRIMUS_KEY สำหรับ Primus Bank |
$PRIMUS_WIP_PROVIDER | ผู้ให้บริการ Workload Identity Pool ซึ่งรวมถึงเงื่อนไขแอตทริบิวต์ที่จะใช้สำหรับโทเค็นที่ลงนามโดยบริการภาระงาน MPC |
$PRIMUS_SERVICEACCOUNT | บัญชีบริการที่ $PRIMUS_WORKLOAD_IDENTITY_POOL ใช้เพื่อเข้าถึงทรัพยากรที่ได้รับการปกป้อง บัญชีบริการนี้จะมีสิทธิ์ดูคีย์ที่เข้ารหัสซึ่งจัดเก็บไว้ในที่เก็บข้อมูล $PRIMUS_INPUT_STORAGE_BUCKET |
$PRIMUS_ARTIFACT_REPOSITORY | ที่เก็บสิ่งประดิษฐ์สำหรับจัดเก็บอิมเมจคอนเทนเนอร์ของภาระงาน |
$WORKLOAD_SERVICEACCOUNT | บัญชีบริการที่มีสิทธิ์เข้าถึง Confidential VM ที่เรียกใช้ภาระงาน |
$WORKLOAD_CONTAINER | คอนเทนเนอร์ Docker ที่เรียกใช้ภาระงาน |
$WORKLOAD_IMAGE_NAME | ชื่อของอิมเมจคอนเทนเนอร์ของภาระงาน |
$WORKLOAD_IMAGE_TAG | แท็กของอิมเมจคอนเทนเนอร์ของภาระงาน |
- เรียกใช้สคริปต์ต่อไปนี้เพื่อตั้งค่าชื่อตัวแปรที่เหลือเป็นค่าตามรหัสโปรเจ็กต์สำหรับชื่อทรัพยากร
source config_env.sh
ตั้งค่าทรัพยากรระบบคลาวด์
ในขั้นตอนนี้ คุณจะต้องตั้งค่าทรัพยากรระบบคลาวด์ที่จำเป็นสำหรับการประมวลผลแบบหลายฝ่าย สำหรับแล็บนี้ คุณจะใช้คีย์ส่วนตัวต่อไปนี้ 0000000000000000000000000000000000000000000000000000000000000001
ในสภาพแวดล้อมการใช้งานจริง คุณจะต้องสร้างคีย์ส่วนตัวของคุณเอง อย่างไรก็ตาม เพื่อวัตถุประสงค์ของแล็บนี้ เราจะแบ่งคีย์ส่วนตัวนี้ออกเป็น 2 ส่วนและเข้ารหัสแต่ละส่วน ในสถานการณ์การใช้งานจริง ไม่ควรจัดเก็บคีย์ไว้ในไฟล์ข้อความธรรมดา แต่คุณสามารถสร้างคีย์ส่วนตัวภายนอก Google Cloud (หรือข้ามไปเลยและแทนที่ด้วยการสร้างคีย์ย่อย MPC ที่กำหนดเอง) แล้วเข้ารหัสเพื่อให้ไม่มีใครเข้าถึงคีย์ส่วนตัวหรือคีย์แชร์ได้ เราจะใช้ Gcloud CLI เพื่อวัตถุประสงค์ของแล็บนี้
เรียกใช้สคริปต์ต่อไปนี้เพื่อตั้งค่าทรัพยากรระบบคลาวด์ที่จำเป็น ในขั้นตอนเหล่านี้ ระบบจะสร้างทรัพยากรที่กล่าวถึงด้านล่าง
- ที่เก็บข้อมูล Cloud Storage (
$PRIMUS_INPUT_STORAGE_BUCKET) เพื่อจัดเก็บส่วนของคีย์ส่วนตัวที่เข้ารหัส - ที่เก็บข้อมูล Cloud Storage (
$PRIMUS_RESULT_STORAGE_BUCKET) เพื่อจัดเก็บผลลัพธ์ของธุรกรรมสินทรัพย์ดิจิทัล - คีย์การเข้ารหัส (
$PRIMUS_KEY) และพวงกุญแจ ($PRIMUS_KEYRING) ใน KMS เพื่อเข้ารหัสการแชร์คีย์ส่วนตัว - Workload Identity Pool (
$PRIMUS_WORKLOAD_IDENTITY_POOL) เพื่อตรวจสอบการอ้างสิทธิ์ตามเงื่อนไขของแอตทริบิวต์ที่กำหนดค่าไว้ภายใต้ผู้ให้บริการ - บัญชีบริการ (
$PRIMUS_SERVICEACCOUNT) ที่แนบกับพูล Workload Identity ($PRIMUS_WORKLOAD_IDENTITY_POOL) ที่กล่าวถึงข้างต้นพร้อมสิทธิ์เข้าถึง IAM ต่อไปนี้ roles/cloudkms.cryptoKeyDecrypterเพื่อถอดรหัสข้อมูลโดยใช้คีย์ KMSobjectViewerเพื่ออ่านข้อมูลจากที่เก็บข้อมูล Cloud Storageroles/iam.workloadIdentityUserเพื่อเชื่อมต่อบัญชีบริการนี้กับ Workload Identity Pool
./setup_resources.sh
3. สร้างภาระงาน
สร้างบัญชีบริการของเวิร์กโหลด
ตอนนี้คุณจะสร้างบัญชีบริการสำหรับภาระงานที่มีบทบาทและสิทธิ์ที่จำเป็น โดยให้เรียกใช้สคริปต์ต่อไปนี้ ซึ่งจะสร้างบัญชีบริการของเวิร์กโหลดสำหรับบริษัท ก. VM ที่เรียกใช้เวิร์กโหลดจะใช้บัญชีบริการนี้
บัญชีบริการของเวิร์กโหลด ($WORKLOAD_SERVICEACCOUNT) จะมีบทบาทต่อไปนี้
confidentialcomputing.workloadUserเพื่อรับโทเค็นการรับรองlogging.logWriterเพื่อเขียนบันทึกลงใน Cloud LoggingobjectViewerเพื่ออ่านข้อมูลจากที่เก็บข้อมูล$PRIMUS_INPUT_STORAGE_BUCKETCloud StorageobjectUserเพื่อเขียนผลลัพธ์ของเวิร์กโหลดไปยังที่เก็บข้อมูล$PRIMUS_RESULT_STORAGE_BUCKETCloud Storage
./create_workload_service_account.sh
สร้างภาระงาน
ขั้นตอนนี้เกี่ยวข้องกับการสร้างอิมเมจ Docker ของภาระงาน เวิร์กโหลดในโค้ดแล็บนี้คือแอปพลิเคชัน MPC ของ Node.js อย่างง่ายที่ลงนามในธุรกรรมดิจิทัลสำหรับการโอนสินทรัพย์โดยใช้การแชร์คีย์ส่วนตัวที่เข้ารหัส ที่นี่คือโค้ดโปรเจ็กต์ของเวิร์กโหลด โปรเจ็กต์ภาระงานมีไฟล์ต่อไปนี้
package.json: ไฟล์นี้มีรายการแพ็กเกจที่ควรใช้สำหรับแอปพลิเคชัน MPC ของเวิร์กโหลด ในกรณีนี้ เราจะใช้ไลบรารี @google-cloud/kms, @google-cloud/storage, ethers และ fast-crc32c ที่นี่คือไฟล์ package.json ที่เราจะใช้สำหรับโค้ดแล็บนี้
index.js: นี่คือจุดแรกเข้าของแอปพลิเคชันเวิร์กโหลด และระบุคำสั่งที่ควรเรียกใช้เมื่อคอนเทนเนอร์เวิร์กโหลดเริ่มต้น นอกจากนี้ เรายังได้รวมตัวอย่างธุรกรรมที่ไม่ได้ลงนามซึ่งปกติแล้วจะมาจากแอปพลิเคชันที่ไม่น่าเชื่อถือที่ขอให้ผู้ใช้ลงนาม ไฟล์ index.js นี้ยังนําเข้าฟังก์ชันจาก mpc.js ซึ่งเราจะสร้างในขั้นตอนถัดไปด้วย ด้านล่างนี้คือเนื้อหาของไฟล์ index.js และคุณยังดูได้ที่นี่
import {signTransaction, submitTransaction, uploadFromMemory} from './mpc.js';
const signAndSubmitTransaction = async () => {
try {
// Create the unsigned transaction object
const unsignedTransaction = {
nonce: 0,
gasLimit: 21000,
gasPrice: '0x09184e72a000',
to: '0x0000000000000000000000000000000000000000',
value: '0x00',
data: '0x',
};
// Sign the transaction
const signedTransaction = await signTransaction(unsignedTransaction);
// Submit the transaction to Ganache
const transaction = await submitTransaction(signedTransaction);
// Write the transaction receipt
uploadFromMemory(transaction);
return transaction;
} catch (e) {
console.log(e);
uploadFromMemory(e);
}
};
await signAndSubmitTransaction();
mpc.js: ส่วนนี้คือที่ที่การลงนามธุรกรรมเกิดขึ้น โดยจะนำเข้าฟังก์ชันจาก kms-decrypt และ credential-config ซึ่งเราจะพูดถึงในส่วนถัดไป ด้านล่างนี้คือเนื้อหาของไฟล์ mpc.js และคุณยังดูเนื้อหาได้ที่นี่
import {Storage} from '@google-cloud/storage';
import {ethers} from 'ethers';
import {credentialConfig} from './credential-config.js';
import {decryptSymmetric} from './kms-decrypt.js';
const providers = ethers.providers;
const Wallet = ethers.Wallet;
// The ID of the GCS bucket holding the encrypted keys
const bucketName = process.env.KEY_BUCKET;
// Name of the encrypted key files.
const encryptedKeyFile1 = 'alice_encrypted_key_share';
const encryptedKeyFile2 = 'bob_encrypted_key_share';
// Create a new storage client with the credentials
const storageWithCreds = new Storage({
credentials: credentialConfig,
});
// Create a new storage client without the credentials
const storage = new Storage();
const downloadIntoMemory = async (keyFile) => {
// Downloads the file into a buffer in memory.
const contents =
await storageWithCreds.bucket(bucketName).file(keyFile).download();
return contents;
};
const provider =
new providers.JsonRpcProvider(`http://${process.env.NODE_URL}:80`);
export const signTransaction = async (unsignedTransaction) => {
/* Check if Alice and Bob have both approved the transaction
For this example, we're checking if their encrypted keys are available. */
const encryptedKey1 =
await downloadIntoMemory(encryptedKeyFile1).catch(console.error);
const encryptedKey2 =
await downloadIntoMemory(encryptedKeyFile2).catch(console.error);
// For each key share, make a call to KMS to decrypt the key
const privateKeyshare1 = await decryptSymmetric(encryptedKey1[0]);
const privateKeyshare2 = await decryptSymmetric(encryptedKey2[0]);
/* Perform the MPC calculations
In this example, we're combining the private key shares
Alternatively, you could import your mpc calculations here */
const wallet = new Wallet(privateKeyshare1 + privateKeyshare2);
// Sign the transaction
const signedTransaction = await wallet.signTransaction(unsignedTransaction);
return signedTransaction;
};
export const submitTransaction = async (signedTransaction) => {
// This can now be sent to Ganache
const hash = await provider.sendTransaction(signedTransaction);
return hash;
};
export const uploadFromMemory = async (contents) => {
// Upload the results to the bucket without service account impersonation
await storage.bucket(process.env.RESULTS_BUCKET)
.file('transaction_receipt_' + Date.now())
.save(JSON.stringify(contents));
};
kms-decrypt.js: ไฟล์นี้มีโค้ดสำหรับการถอดรหัสโดยใช้คีย์ที่จัดการใน KMS เนื้อหาของไฟล์ kms-decrypt.js อยู่ด้านล่าง และคุณยังดูได้ที่นี่
import {KeyManagementServiceClient} from '@google-cloud/kms';
import crc32c from 'fast-crc32c';
import {credentialConfig} from './credential-config.js';
const projectId = process.env.PRIMUS_PROJECT_ID;
const locationId = process.env.PRIMUS_LOCATION;
const keyRingId = process.env.PRIMUS_ENC_KEYRING;
const keyId = process.env.PRIMUS_ENC_KEY;
// Instantiates a client
const client = new KeyManagementServiceClient({
credentials: credentialConfig,
});
// Build the key name
const keyName = client.cryptoKeyPath(projectId, locationId, keyRingId, keyId);
export const decryptSymmetric = async (ciphertext) => {
const ciphertextCrc32c = crc32c.calculate(ciphertext);
const [decryptResponse] = await client.decrypt({
name: keyName,
ciphertext,
ciphertextCrc32c: {
value: ciphertextCrc32c,
},
});
// Optional, but recommended: perform integrity verification on
// decryptResponse. For more details on ensuring E2E in-transit integrity to
// and from Cloud KMS visit:
// https://cloud.google.com/kms/docs/data-integrity-guidelines
if (crc32c.calculate(decryptResponse.plaintext) !==
Number(decryptResponse.plaintextCrc32c.value)) {
throw new Error('Decrypt: response corrupted in-transit');
}
const plaintext = decryptResponse.plaintext.toString();
return plaintext;
};
credential-config.js: ไฟล์จะจัดเก็บเส้นทางและรายละเอียดของ Workload Identity Pool สำหรับการแอบอ้างเป็นบัญชีบริการ ที่นี่คือไฟล์ credential-config.js ที่เราจะใช้สำหรับโค้ดแล็บนี้
Dockerfile: สุดท้าย เราจะสร้าง Dockerfile ที่จะใช้สร้างอิมเมจ Docker ของภาระงาน โดยจะกำหนด Dockerfile ตามที่ระบุไว้ที่นี่
FROM node:16.18.0
ENV NODE_ENV=production
WORKDIR /app
COPY ["package.json", "package-lock.json*", "./"]
RUN npm install --production
COPY . .
LABEL "tee.launch_policy.allow_cmd_override"="true"
LABEL "tee.launch_policy.allow_env_override"="NODE_URL,RESULTS_BUCKET,KEY_BUCKET,PRIMUS_PROJECT_NUMBER,PRIMUS_PROJECT_ID,PRIMUS_WORKLOAD_IDENTITY_POOL,PRIMUS_WIP_PROVIDER,PRIMUS_SERVICEACCOUNT,PRIMUS_ENC_KEYRING,PRIMUS_ENC_KEY"
CMD [ "node", "index.js" ]
หมายเหตุ: LABEL "tee.launch_policy.allow_cmd_override"="true" ใน Dockerfile เป็นนโยบายการเปิดตัวที่ผู้สร้างอิมเมจตั้งค่าไว้ ซึ่งจะช่วยให้ผู้ปฏิบัติงานลบล้าง CMD ได้เมื่อเรียกใช้เวิร์กโหลด โดยค่าเริ่มต้น ระบบจะตั้งค่า allow_cmd_override เป็นเท็จ LABEL "tee.launch_policy.allow_env_override" จะบอก Confidential Space ว่าผู้ใช้รูปภาพใช้ตัวแปรสภาพแวดล้อมใดได้
เรียกใช้สคริปต์ต่อไปนี้เพื่อสร้างภาระงานที่จะดำเนินการตามขั้นตอนต่อไปนี้
- สร้าง Artifact Registry(
$PRIMUS_ARTIFACT_REPOSITORY) เพื่อจัดเก็บอิมเมจ Docker ของภาระงาน - อัปเดตโค้ดภาระงานด้วยชื่อทรัพยากรที่จำเป็น ที่นี่คือโค้ดของเวิร์กโหลดที่ใช้สำหรับ Codelab นี้
- สร้าง Dockerfile สำหรับสร้างอิมเมจ Docker ของโค้ดภาระงาน ดู Dockerfile ได้ที่นี่
- สร้างและเผยแพร่อิมเมจ Docker ไปยัง Artifact Registry (
$PRIMUS_ARTIFACT_REPOSITORY) ที่สร้างไว้ในขั้นตอนก่อนหน้า - ให้สิทธิ์อ่านแก่
$WORKLOAD_SERVICEACCOUNTสำหรับ$PRIMUS_ARTIFACT_REPOSITORYซึ่งจำเป็นเพื่อให้คอนเทนเนอร์ของภาระงานดึงอิมเมจ Docker ของภาระงานจาก Artifact Registry ได้
./create_workload.sh
สร้างโหนดบล็อกเชน
โหนด Ethereum ของ Ganache
เราต้องสร้างอินสแตนซ์ Ethereum Ganache ก่อนที่จะให้สิทธิ์เวิร์กโหลด ระบบจะส่งธุรกรรมที่ลงนามแล้วไปยังอินสแตนซ์ Ganache นี้ โปรดจดที่อยู่ IP ของอินสแตนซ์นี้ หลังจากเรียกใช้คำสั่งด้านล่างแล้ว คุณอาจต้องป้อน y เพื่อเปิดใช้ API
gcloud compute instances create-with-container ${ETHEREUM_NODE} \
--zone=${PRIMUS_PROJECT_ZONE} \
--tags=http-server \
--project=${PRIMUS_PROJECT_ID} \
--shielded-secure-boot \
--shielded-vtpm \
--shielded-integrity-monitoring \
--container-image=docker.io/trufflesuite/ganache:v7.7.3 \
--container-arg=--wallet.accounts=\"0x0000000000000000000000000000000000000000000000000000000000000001,0x21E19E0C9BAB2400000\" \
--container-arg=--port=80
4. ให้สิทธิ์และเรียกใช้เวิร์กโหลด
ให้สิทธิ์ภาระงาน
ในขั้นตอนนี้ เราจะตั้งค่าผู้ให้บริการ Workload Identity Pool ภายใต้ Workload Identity Pool ($PRIMUS_WORKLOAD_IDENTITY_POOL) โดยมีการกำหนดค่าเงื่อนไขแอตทริบิวต์สำหรับ Workload Identity ดังที่แสดงด้านล่าง เงื่อนไขข้อหนึ่งคือการตรวจสอบว่ามีการดึงอิมเมจของเวิร์กโหลดจากที่เก็บอาร์ติแฟกต์ที่คาดไว้
gcloud config set project $PRIMUS_PROJECT_ID
gcloud iam workload-identity-pools providers create-oidc ${PRIMUS_WIP_PROVIDER} \
--location="${PRIMUS_PROJECT_LOCATION}" \
--workload-identity-pool="$PRIMUS_WORKLOAD_IDENTITY_POOL" \
--issuer-uri="https://confidentialcomputing.googleapis.com/" \
--allowed-audiences="https://sts.googleapis.com" \
--attribute-mapping="google.subject='assertion.sub'" \
--attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' && 'STABLE' in assertion.submods.confidential_space.support_attributes && assertion.submods.container.image_reference == '${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG' && '$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts"
เรียกใช้ภาระงาน
ส่วนนี้จะอธิบายวิธีเรียกใช้เวิร์กโหลดใน Confidential VM โดยเราจะส่งอาร์กิวเมนต์ TEE ที่จำเป็นโดยใช้แฟล็กข้อมูลเมตา นอกจากนี้ เราจะตั้งค่าตัวแปรสภาพแวดล้อมสำหรับคอนเทนเนอร์ภาระงานโดยใช้แฟล็ก "tee-env-*" รูปภาพมีตัวแปรต่อไปนี้
NODE_URL: URL ของโหนด Ethereum ที่จะประมวลผลธุรกรรมที่ลงนามแล้วRESULTS_BUCKET: ที่เก็บข้อมูลที่จัดเก็บผลลัพธ์ของธุรกรรม MPCKEY_BUCKET: บัคเก็ตที่จัดเก็บคีย์ที่เข้ารหัส MPCPRIMUS_PROJECT_NUMBER: หมายเลขโปรเจ็กต์ที่ใช้สำหรับไฟล์กำหนดค่าข้อมูลเข้าสู่ระบบPRIMUS_PROJECT_ID: รหัสโปรเจ็กต์ที่ใช้สำหรับไฟล์การกำหนดค่าข้อมูลเข้าสู่ระบบ ผลการดำเนินการของเวิร์กโหลดจะเผยแพร่ไปยัง$PRIMUS_RESULT_STORAGE_BUCKETPRIMUS_WORKLOAD_IDENTITY_POOL: พูล Workload Identity ที่ใช้เพื่อตรวจสอบความถูกต้องของคำกล่าวอ้างPRIMUS_WIP_POROVIDER: ผู้ให้บริการ Workload Identity Pool ซึ่งรวมถึงเงื่อนไขแอตทริบิวต์ที่จะใช้ในการตรวจสอบโทเค็นที่เวิร์กโหลดแสดงWORKLOAD_SERVICEACCOUNT: บัญชีบริการของเวิร์กโหลด
gcloud compute instances create $WORKLOAD_VM \
--confidential-compute-type=SEV \
--shielded-secure-boot \
--maintenance-policy=TERMINATE \
--scopes=cloud-platform \
--zone=${PRIMUS_PROJECT_ZONE} \
--project=${PRIMUS_PROJECT_ID} \
--image-project=confidential-space-images \
--image-family=confidential-space \
--service-account=$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com \
--metadata "^~^tee-image-reference=${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG~tee-restart-policy=Never~tee-env-NODE_URL=$(gcloud compute instances describe ${ETHEREUM_NODE} --format='get(networkInterfaces[0].networkIP)' --zone=${PRIMUS_PROJECT_ZONE})~tee-env-RESULTS_BUCKET=$PRIMUS_RESULT_STORAGE_BUCKET~tee-env-KEY_BUCKET=$PRIMUS_INPUT_STORAGE_BUCKET~tee-env-PRIMUS_PROJECT_ID=$PRIMUS_PROJECT_ID~tee-env-PRIMUS_PROJECT_NUMBER=$(gcloud projects describe $PRIMUS_PROJECT_ID --format="value(projectNumber)")~tee-env-PRIMUS_WORKLOAD_IDENTITY_POOL=$PRIMUS_WORKLOAD_IDENTITY_POOL~tee-env-PRIMUS_PROJECT_LOCATION=${PRIMUS_PROJECT_LOCATION}~tee-env-PRIMUS_WIP_PROVIDER=$PRIMUS_WIP_PROVIDER~tee-env-PRIMUS_SERVICEACCOUNT=$PRIMUS_SERVICEACCOUNT~tee-env-PRIMUS_KEY=${PRIMUS_KEY}~tee-env-PRIMUS_KEYRING=${PRIMUS_KEYRING}"
ตรวจสอบผลลัพธ์ใน Cloud Storage
คุณดูใบเสร็จการทำธุรกรรมได้ใน Cloud Storage อาจใช้เวลา 2-3 นาทีในการบูต Confidential Space และให้ผลลัพธ์ปรากฏ คุณจะทราบว่าคอนเทนเนอร์เสร็จสมบูรณ์เมื่อ VM อยู่ในสถานะหยุด
- ไปที่หน้าเบราว์เซอร์ Cloud Storage
- คลิก
$PRIMUS_RESULT_STORAGE_BUCKET - คลิกไฟล์
transaction_receipt - คลิกดาวน์โหลดเพื่อดาวน์โหลดและดูการตอบกลับธุรกรรม
หรือจะเรียกใช้คำสั่งต่อไปนี้เพื่อดูผลลัพธ์ก็ได้
gcloud config set project $PRIMUS_PROJECT_ID
gsutil cat gs://$PRIMUS_RESULT_STORAGE_BUCKET/transaction_receipt
หมายเหตุ: หากผลลัพธ์ไม่ปรากฏ คุณสามารถไปที่ $WORKLOAD_VM ในหน้า Compute Engine Cloud Console แล้วคลิก "Serial port 1 (console)" เพื่อดูบันทึก
ตรวจสอบธุรกรรมบล็อกเชนของ Ganache
นอกจากนี้ คุณยังดูธุรกรรมในบันทึกบล็อกเชนได้ด้วย
- ไปที่หน้า Cloud Compute Engine
- คลิก
${ETHEREUM_NODE}VM - คลิก
SSHเพื่อเปิดหน้าต่าง SSH ในเบราว์เซอร์ - ในหน้าต่าง SSH ให้ป้อน
sudo docker psเพื่อดูคอนเทนเนอร์ Ganache ที่ทำงานอยู่ - ค้นหารหัสคอนเทนเนอร์สำหรับ
trufflesuite/ganache:v7.7.3 - ป้อน
sudo docker logs CONTAINER_IDโดยแทนที่ CONTAINER_ID ด้วยรหัสสำหรับtrufflesuite/ganache:v7.7.3 - ดูบันทึกสำหรับ Ganache และยืนยันว่ามีธุรกรรมแสดงอยู่ในบันทึก
5. ล้างข้อมูล
ที่นี่คือสคริปต์ที่ใช้ล้างข้อมูลทรัพยากรที่เราสร้างขึ้นเป็นส่วนหนึ่งของ Codelab นี้ การล้างข้อมูลนี้จะลบทรัพยากรต่อไปนี้
- ที่เก็บข้อมูลอินพุตที่ใช้จัดเก็บคีย์ที่เข้ารหัสแล้ว (
$PRIMUS_INPUT_STORAGE_BUCKET) - คีย์การเข้ารหัส (
$PRIMUS_KEY) - บัญชีบริการที่ใช้เพื่อเข้าถึงทรัพยากรที่ได้รับการปกป้อง (
$PRIMUS_SERVICEACCOUNT) - พูล Workload Identity (
$PRIMUS_WORKLOAD_IDENTITY_POOL) - บัญชีบริการของภาระงาน (
$WORKLOAD_SERVICEACCOUNT) - อินสแตนซ์การประมวลผลของภาระงาน (
$WORKLOAD_VMและ$ETHEREUM_NODE) - ที่เก็บข้อมูลผลลัพธ์ที่ใช้จัดเก็บผลลัพธ์ของธุรกรรม (
$PRIMUS_RESULT_STORAGE_BUCKET) - รีจิสทรีของอาร์ติแฟกต์ที่ใช้จัดเก็บอิมเมจของภาระงาน (
$PRIMUS_ARTIFACT_REPOSITORY)
./cleanup.sh
หากสำรวจเสร็จแล้ว โปรดพิจารณาลบโปรเจ็กต์
- ไปที่คอนโซล Cloud Platform
- เลือกโปรเจ็กต์ที่ต้องการปิด แล้วคลิก "ลบ" ที่ด้านบน ซึ่งจะเป็นการกำหนดเวลาให้ลบโปรเจ็กต์
สิ่งต่อไปที่ควรทำ
ลองดู Codelab ที่คล้ายกันเหล่านี้
- ข้อมูลที่แชร์อย่างปลอดภัยซึ่งใช้กับ Confidential Space
- Codelab เกี่ยวกับอิมเมจคอนเทนเนอร์ที่ลงนาม
- วิเคราะห์ข้อมูลที่เป็นความลับด้วยพื้นที่ลับ
อ่านเพิ่มเติม
- รู้สึกโดดเดี่ยวใช่ไหม Confidential Computing ช่วยคุณได้
- การประมวลผลข้อมูลลับใน GCP
- Confidential Space: อนาคตของการทำงานร่วมกันที่รักษาความเป็นส่วนตัว
- วิธีที่ Google และ Intel ทำให้การประมวลผลแบบเป็นความลับปลอดภัยยิ่งขึ้น
- ความเป็นส่วนตัวเทียบกับความก้าวหน้า - การรักษาความปลอดภัยที่ดียิ่งขึ้นด้วยการประมวลผลแบบเป็นความลับของ Google Cloud