1. ภาพรวม
ก่อนจะเริ่มต้น แม้ว่าจะไม่ใช่สิ่งจําเป็นทั้งหมด แต่ความรู้เกี่ยวกับฟีเจอร์และแนวคิดต่อไปนี้จะเป็นประโยชน์ในโค้ดแล็บนี้
- พื้นที่เก็บข้อมูลระบบคลาวด์ โดยเฉพาะที่เก็บข้อมูล
- Compute Engine โดยเฉพาะ Confidential VM
- บัญชีบริการ
- คอนเทนเนอร์และที่เก็บข้อมูลระยะไกล
- การรวมศูนย์ Workload Identity และเงื่อนไขแอตทริบิวต์
สิ่งที่คุณจะได้เรียนรู้
ห้องทดลองนี้แสดงการใช้งานอ้างอิงสำหรับการลงนามบล็อกเชนที่เป็นไปตามข้อกำหนด MPC โดยใช้พื้นที่ส่วนบุคคล เราจะอธิบายแนวคิดนี้โดยใช้สถานการณ์สมมติที่บริษัท Primus ต้องการโอนเนื้อหาดิจิทัลไปยังบริษัท Secundus ในกรณีนี้ บริษัท Primus ใช้รูปแบบที่เป็นไปตาม MPC ซึ่งหมายความว่าจะใช้ส่วนแบ่งคีย์ที่กระจายแทนการใช้คีย์ส่วนตัวแต่ละรายการ บุคคลหลายฝ่ายจะถือครองส่วนแบ่งคีย์เหล่านี้ ซึ่งในกรณีนี้ได้แก่ ขวัญใจและบัญชา แนวทางนี้ให้ประโยชน์หลายประการแก่ Company Primus ซึ่งรวมถึงประสบการณ์การใช้งานที่ง่ายขึ้น ประสิทธิภาพการปฏิบัติงาน และการควบคุมคีย์ส่วนตัว
เราจะอธิบายแง่มุมพื้นฐานของกระบวนการนี้โดยละเอียด รวมถึงอธิบายการตั้งค่าทางเทคนิคและแนะนำขั้นตอนอนุมัติและการลงนามที่เริ่มต้นการโอนเนื้อหาดิจิทัลจากบริษัท Primus ไปยังบริษัท Secundus โปรดทราบว่า Bob และ Alice ซึ่งเป็นพนักงานของบริษัท Primus จะต้องอนุมัติธุรกรรม
แม้ว่าการใช้งานอ้างอิงนี้จะสาธิตการดำเนินการเกี่ยวกับลายเซ็น แต่ก็ไม่ได้ครอบคลุมทุกแง่มุมของการจัดการคีย์ MPC ตัวอย่างเช่น เราไม่พูดถึงการสร้างคีย์ นอกจากนี้ ยังมีแนวทางอื่นๆ ที่ใช้ร่วมกันได้ เช่น การใช้บริการที่ไม่ใช่ Google Cloud เพื่อสร้างลายเซ็นร่วม หรือให้ผู้ร่วมลงนามสร้างลายเซ็นบล็อกเชนในสภาพแวดล้อมของตนเอง ซึ่งเป็นสถาปัตยกรรมแบบกระจายอำนาจมากขึ้น เราหวังว่าห้องทดลองนี้จะสร้างแรงบันดาลใจให้ใช้แนวทางต่างๆ กับ MPC ใน Google Cloud
คุณจะต้องทำงานกับเวิร์กโหลดง่ายๆ ที่ลงนามในธุรกรรม Ethereum ในพื้นที่ทำงานที่เป็นความลับโดยใช้วัสดุคีย์ของผู้ร่วมลงนาม การรับรองธุรกรรม Ethereum คือกระบวนการที่ผู้ใช้สามารถให้สิทธิ์ธุรกรรมในบล็อกเชน Ethereum หากต้องการส่งธุรกรรม Ethereum คุณต้องลงนามด้วยคีย์ส่วนตัว ซึ่งจะพิสูจน์ว่าคุณเป็นเจ้าของบัญชีและได้รับอนุญาตให้ทำธุรกรรม ขั้นตอนการลงนามมีดังนี้
- ผู้ส่งจะสร้างออบเจ็กต์ธุรกรรมที่ระบุที่อยู่ผู้รับ จำนวน ETH ที่จะส่ง และข้อมูลอื่นๆ ที่เกี่ยวข้อง
- ระบบจะใช้คีย์ส่วนตัวของผู้ส่งเพื่อแฮชข้อมูลธุรกรรม
- จากนั้นจึงใช้คีย์ส่วนตัวลงนามแฮช
- ลายเซ็นจะแนบอยู่กับออบเจ็กต์ธุรกรรม
- ระบบจะออกอากาศธุรกรรมไปยังเครือข่าย Ethereum
เมื่อโหนดในเครือข่ายได้รับธุรกรรม โหนดจะยืนยันลายเซ็นเพื่อให้แน่ใจว่าธุรกรรมดังกล่าวลงนามโดยเจ้าของบัญชี หากลายเซ็นถูกต้อง โหนดจะเพิ่มธุรกรรมลงในบล็อกเชน
ในการเริ่มต้น คุณจะต้องกำหนดค่าทรัพยากร Cloud ที่จำเป็น จากนั้นคุณจะเรียกใช้เวิร์กโหลดในพื้นที่ทำงานที่ปลอดภัย โค้ดแล็บนี้จะแนะนำขั้นตอนระดับสูงต่อไปนี้
- วิธีกำหนดค่าทรัพยากรในระบบคลาวด์ที่จำเป็นสำหรับเรียกใช้พื้นที่ทำงานที่มีข้อมูลลับ
- วิธีให้สิทธิ์เข้าถึงทรัพยากรที่มีการป้องกันตามแอตทริบิวต์ของสิ่งต่อไปนี้
- สิ่งที่ต้องระบุ: คอนเทนเนอร์ของภาระงาน
- ตำแหน่ง: สภาพแวดล้อมของพื้นที่ทำงานที่เป็นความลับ (อิมเมจพื้นที่ทำงานที่เป็นความลับใน Confidential VM)
- ผู้ใช้: บัญชีที่ใช้งานเวิร์กโหลด
- วิธีเรียกใช้เวิร์กโหลดใน VM ที่เป็นความลับซึ่งใช้รูปภาพ VM ของพื้นที่ทำงานที่เป็นความลับ
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. ตั้งค่าทรัพยากรระบบคลาวด์
ก่อนเริ่มต้น
- โคลน ที่เก็บนี้โดยใช้คําสั่งด้านล่างเพื่อรับสคริปต์ที่จําเป็นซึ่งใช้ในโค้ดแล็บนี้
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
- เปลี่ยนไดเรกทอรีของ Codelab นี้
cd confidential-space/codelabs/digital_asset_transaction_codelab/scripts
- ตรวจสอบว่าคุณได้ตั้งค่าตัวแปรสภาพแวดล้อมของโปรเจ็กต์ที่จําเป็นดังที่แสดงด้านล่าง ดูข้อมูลเพิ่มเติมเกี่ยวกับการตั้งค่าโปรเจ็กต์ GCP ได้ที่ โค้ดแล็บนี้ โปรดดูรายละเอียดเกี่ยวกับวิธีเรียกข้อมูลรหัสโปรเจ็กต์และความแตกต่างระหว่างรหัสโปรเจ็กต์กับชื่อโปรเจ็กต์และหมายเลขโปรเจ็กต์ได้ที่นี่ .
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 ซึ่งมีเงื่อนไขแอตทริบิวต์ที่จะใช้กับโทเค็นที่บริการเวิร์กโหลด MPC ลงนาม |
$PRIMUS_SERVICEACCOUNT | บัญชีบริการที่ $PRIMUS_WORKLOAD_IDENTITY_POOL ใช้เข้าถึงทรัพยากรที่ได้รับการปกป้อง บัญชีบริการนี้จะมีสิทธิ์ดูคีย์ที่เข้ารหัสซึ่งจัดเก็บอยู่ในที่เก็บข้อมูล $PRIMUS_INPUT_STORAGE_BUCKET |
$PRIMUS_ARTIFACT_REPOSITORY | ที่เก็บอาร์ติแฟกต์สำหรับจัดเก็บอิมเมจคอนเทนเนอร์ของภาระงาน |
$WORKLOAD_SERVICEACCOUNT | บัญชีบริการที่มีสิทธิ์เข้าถึง 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
เพื่ออ่านข้อมูลจากที่เก็บข้อมูล Cloud Storage ของ$PRIMUS_INPUT_STORAGE_BUCKET
objectUser
เพื่อเขียนผลลัพธ์ของภาระงานไปยังที่เก็บข้อมูล Cloud Storage ของ$PRIMUS_RESULT_STORAGE_BUCKET
./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 เป็นเท็จ ป้ายกํากับ "tee.launch_policy.allow_env_override" จะบอกพื้นที่ทำงานแบบจำกัดว่าผู้ใช้รูปภาพตัวแปรสภาพแวดล้อมใดบ้างที่ใช้ได้
เรียกใช้สคริปต์ต่อไปนี้เพื่อสร้างภาระงานที่จะทำตามขั้นตอนต่อไปนี้
- สร้าง Artifact Registry(
$PRIMUS_ARTIFACT_REPOSITORY
) เพื่อจัดเก็บอิมเมจ Docker ของ Workload - อัปเดตโค้ดภาระงานด้วยชื่อทรัพยากรที่จำเป็น ที่นี่คือรหัสเวิร์กโหลดที่ใช้สำหรับ Codelab นี้
- สร้าง Dockerfile สำหรับการสร้างอิมเมจ Docker ของโค้ดภาระงาน ดู Dockerfile ได้ที่นี่
- สร้างและเผยแพร่อิมเมจ Docker ไปยัง Artifact Registry (
$PRIMUS_ARTIFACT_REPOSITORY
) ที่สร้างขึ้นในขั้นตอนก่อนหน้า - ให้สิทธิ์อ่าน
$PRIMUS_ARTIFACT_REPOSITORY
แก่$WORKLOAD_SERVICEACCOUNT
ซึ่งจําเป็นเพื่อให้คอนเทนเนอร์ภาระงานดึงอิมเมจ Docker ของภาระงานจาก Artifact Registry ได้
./create_workload.sh
สร้างโหนด Blockchain
โหนด Ganache Ethereum
เราต้องสร้างอินสแตนซ์ 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"
เรียกใช้ภาระงาน
ส่วนนี้จะอธิบายวิธีเรียกใช้เวิร์กโหลดใน VM ข้อมูลที่เป็นความลับ โดยเราจะส่งอาร์กิวเมนต์ TEE ที่จำเป็นโดยใช้ Flag ข้อมูลเมตา นอกจากนี้ เราจะตั้งค่าตัวแปรสภาพแวดล้อมสำหรับคอนเทนเนอร์ของภาระงานโดยใช้ Flag "tee-env-*" รูปภาพมีตัวแปรต่อไปนี้
NODE_URL
: URL ของโหนด Ethereum ที่จะประมวลผลธุรกรรมที่ลงนามRESULTS_BUCKET
: ที่เก็บข้อมูลผลลัพธ์ธุรกรรม mpcKEY_BUCKET
: ที่เก็บข้อมูลซึ่งจัดเก็บคีย์ที่เข้ารหัส mpcPRIMUS_PROJECT_NUMBER
: หมายเลขโปรเจ็กต์ที่ใช้สำหรับไฟล์การกําหนดค่าข้อมูลเข้าสู่ระบบPRIMUS_PROJECT_ID
: รหัสโปรเจ็กต์ที่ใช้สำหรับไฟล์การกําหนดค่าข้อมูลเข้าสู่ระบบ ระบบจะเผยแพร่ผลลัพธ์ของการดำเนินการเวิร์กโหลดไปยัง$PRIMUS_RESULT_STORAGE_BUCKET
PRIMUS_WORKLOAD_IDENTITY_POOL
: พูล Workload Identity ที่ใช้ตรวจสอบการอ้างสิทธิ์PRIMUS_WIP_POROVIDER
: ผู้ให้บริการพูล Workload Identity ซึ่งมีเงื่อนไขแอตทริบิวต์ที่จะใช้ตรวจสอบโทเค็นที่แสดงโดยเวิร์กโหลด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 นาทีจึงจะบูตพื้นที่ทำงานที่ปลอดภัยและแสดงผลลัพธ์ คุณจะทราบว่าคอนเทนเนอร์เสร็จแล้วเมื่อ 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 ในหน้า Cloud Console ของ Compute Engine แล้วคลิก "พอร์ตซีเรียล 1 (คอนโซล)" เพื่อดูบันทึก
ตรวจสอบธุรกรรม Blockchain ของ 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 Compute Instance (
$WORKLOAD_VM
และ$ETHEREUM_NODE
) - ที่เก็บข้อมูลผลลัพธ์ที่ใช้จัดเก็บผลลัพธ์ธุรกรรม (
$PRIMUS_RESULT_STORAGE_BUCKET
) - Artifact Registry ที่ใช้ในการจัดเก็บรูปภาพภาระงาน (
$PRIMUS_ARTIFACT_REPOSITORY
)
./cleanup.sh
หากสำรวจเสร็จแล้ว โปรดพิจารณาลบโปรเจ็กต์
- ไปที่คอนโซลแพลตฟอร์มระบบคลาวด์
- เลือกโปรเจ็กต์ที่ต้องการปิด แล้วคลิก "ลบ" ที่ด้านบน ซึ่งจะกำหนดเวลาการลบโปรเจ็กต์
ขั้นตอนถัดไป
ลองดู Codelab ที่คล้ายกันเหล่านี้...
- ข้อมูลที่แชร์อย่างปลอดภัยที่ใช้กับพื้นที่ทำงานที่ปลอดภัย
- Codelab อิมเมจคอนเทนเนอร์ที่เซ็นชื่อกำกับ
- วิเคราะห์ข้อมูลที่เป็นความลับด้วยพื้นที่ทำงานที่เป็นความลับ
อ่านเพิ่มเติม
- หากรู้สึกโดดเดี่ยว การใช้ระบบประมวลผลข้อมูลที่เป็นความลับช่วยแก้ปัญหาได้
- การประมวลผลข้อมูลที่เป็นความลับใน GCP
- พื้นที่ทำงานที่เป็นความลับ: อนาคตของการทำงานร่วมกันที่รักษาความเป็นส่วนตัว
- วิธีที่ Google และ Intel ทําให้ระบบประมวลผลข้อมูลที่เป็นความลับปลอดภัยยิ่งขึ้น
- ความเป็นส่วนตัวกับการพัฒนา - ยกระดับความปลอดภัยด้วย Google Cloud Confidential Computing