गोपनीय स्पेस का इस्तेमाल सुरक्षित संसाधनों के साथ करें, जिन्हें क्लाउड सेवा देने वाली कंपनी के पास सेव नहीं किया जाता

1. खास जानकारी

Confidential Space, कई पक्षों के साथ डेटा को सुरक्षित तरीके से शेयर करने और मिलकर काम करने की सुविधा देता है. साथ ही, संगठनों को अपने डेटा की गोपनीयता बनाए रखने की अनुमति देता है. इसका मतलब है कि संगठन एक-दूसरे के साथ मिलकर काम कर सकते हैं. हालांकि, वे अपने डेटा का ऐक्सेस कंट्रोल कर सकते हैं और उसे बिना अनुमति के ऐक्सेस से सुरक्षित रख सकते हैं.

Confidential Space की मदद से, ऐसे मामलों में फ़ायदा पाया जा सकता है जहां आपको संवेदनशील डेटा को इकट्ठा और उसका विश्लेषण करके, दोनों पक्षों को फ़ायदा पहुंचाना हो. साथ ही, आपको डेटा पर पूरा कंट्रोल रखना हो. कॉन्फ़िडेंशियल स्पेस की मदद से, संगठन संवेदनशील डेटा को इकट्ठा और उसका विश्लेषण करके, एक-दूसरे को फ़ायदा पहुंचा सकते हैं. जैसे, व्यक्तिगत पहचान से जुड़ी जानकारी (पीआईआई), स्वास्थ्य की सुरक्षित जानकारी (पीएचआई), बौद्धिक संपत्ति, और क्रिप्टोग्राफ़िक सीक्रेट. साथ ही, वे इस डेटा पर पूरा कंट्रोल बनाए रख सकते हैं.

आपको इन चीज़ों की ज़रूरत होगी

आपको क्या सीखने को मिलेगा

  • कॉन्फ़िडेंशियल स्पेस को चलाने के लिए, ज़रूरी क्लाउड संसाधनों को कॉन्फ़िगर करने का तरीका
  • कॉन्फ़िडेंशियल स्पेस इमेज चलाने वाले कॉन्फ़िडेंशियल वीएम में वर्कलोड को कैसे चलाया जाता है
  • वर्कलोड कोड (क्या), कॉन्फ़िडेंशियल स्पेस एनवायरमेंट (कहां), और वर्कलोड चलाने वाले खाते (कौन) के एट्रिब्यूट के आधार पर, सुरक्षित संसाधनों को ऐक्सेस करने की अनुमति कैसे दी जाती है.

इस कोडलैब में, Google Cloud के अलावा किसी और जगह पर होस्ट किए गए सुरक्षित संसाधनों के साथ Confidential Space का इस्तेमाल करने के तरीके के बारे में बताया गया है. आपको यह पता चलेगा कि Google Attestation Service से कस्टम और सेल्फ कंटेन्ड टोकन का अनुरोध कैसे किया जाता है. इसके लिए, आपको नॉनस, ऑडियंस, और पीकेआई टोकन टाइप देना होगा.

इस कोडलैब में, आपको एक काल्पनिक प्रॉडक्ट - USleep, कंटेनर में मौजूद ऐप्लिकेशन, और एक काल्पनिक प्रॉडक्ट - UWear, कनेक्ट किया गया पहनने योग्य डिवाइस के बीच कॉन्फ़िडेंशियल स्पेस सेट अप करना होगा. इससे आपकी नींद की क्वालिटी का हिसाब लगाया जा सकेगा. UWear, स्वास्थ्य की सुरक्षित जानकारी (पीएचआई) को USleep के साथ सुरक्षित, अलग, और भरोसेमंद तरीके से शेयर करेगा. इसे ट्रस्टेड एक्ज़ीक्यूशन एनवायरमेंट (टीईई) भी कहा जाता है. इससे डेटा के मालिकों की पूरी निजता बनी रहेगी.

UWear, वर्कलोड ऑडिटर और डेटा का मालिक, दोनों है. वर्कलोड ऑडिटर के तौर पर यह,चल रहे वर्कलोड में मौजूद कोड की समीक्षा करता है और इमेज डाइजेस्ट का ध्यान रखता है. डेटा के मालिक के तौर पर UWear, पुष्टि करने का लॉजिक लिखता है. इससे टोकन और उसके हस्ताक्षर की वैधता की जांच की जाती है. यह ऑडिट किए गए वर्कलोड के इमेज डाइजेस्ट का इस्तेमाल करके, पुष्टि करने की नीति लिखता है. इससे किसी खास इमेज डाइजेस्ट को किसी खास एनवायरमेंट में, संवेदनशील डेटा का ऐक्सेस मिलता है.

इस कोडलैब में, USleep कंटेनर वाले ऐप्लिकेशन को डिप्लॉय कर रहा है. USleep के पास संवेदनशील डेटा का ऐक्सेस नहीं होता. हालांकि, यह ऐसे वर्कलोड को चलाता है जिसे संवेदनशील डेटा का ऐक्सेस दिया गया है.

इस कोडलैब में ये चरण शामिल हैं:

  • पहला चरण: कोडलैब के लिए ज़रूरी क्लाउड संसाधन सेट अप करें. प्रोजेक्ट, बिलिंग, और अनुमतियां सेट अप करें. कोड लैब का सोर्स कोड डाउनलोड करें और एनवायरमेंट वैरिएबल सेट करें.
  • दूसरा चरण: रूट सर्टिफ़िकेट डाउनलोड करें और इसे अपने UWear सोर्स कोड के साथ सेव करें.
  • तीसरा चरण: अलग-अलग वर्कलोड सेवा खाते बनाएं. इनका इस्तेमाल, USleep और UWear के लिए वर्कलोड वीएम करेगा.
  • चौथा चरण: USleep वर्कलोड बनाएं, जो पुष्टि करने वाला टोकन उपलब्ध कराता है.
  • पांचवां चरण: UWear वर्कलोड बनाएं. यह वर्कलोड, पुष्टि करने वाले टोकन की पुष्टि करता है. साथ ही, अगर टोकन स्वीकार कर लिया जाता है, तो संवेदनशील डेटा भेजता है.
  • छठा चरण: USleep और UWear वर्कलोड चलाएं. UWear, संवेदनशील डेटा उपलब्ध कराएगा. वहीं, USleep इस डेटा पर नींद का एल्गोरिदम चलाएगा और नतीजे देगा.
  • सातवां चरण: (ज़रूरी नहीं) बिना अनुमति के USleep वर्कलोड चलाएं और पुष्टि करें कि UWear से संवेदनशील डेटा नहीं मिला है.
  • आठवां चरण: सभी संसाधनों को मिटाएं.

वर्कफ़्लो को समझना

USleep, गोपनीय स्पेस में वर्कलोड चलाएगा. वर्कलोड को चलाने के लिए, इसे UWear के पीएचआई का ऐक्सेस चाहिए. ऐक्सेस पाने के लिए, USleep वर्कलोड पहले एक सुरक्षित टीएलएस सेशन बनाता है. इसके बाद, USleep भी Google Attestation Service से पुष्टि करने वाले टोकन का अनुरोध करेगा. इसके लिए, वह payload का इस्तेमाल करेगा.

USleep, पुष्टि करने वाले टोकन का अनुरोध करेगा. इसमें एक JSON पेलोड होगा. इसमें ये तीन चीज़ें शामिल होंगी:

  1. टीएलएस सेशन से जुड़ा एक अटेस्टेशन टोकन. अटेस्टेशन टोकन को टीएलएस सेशन से बाइंड करने के लिए, नॉनस वैल्यू टीएलएस एक्सपोर्टेड कीइंग मटीरियल का हैश होगी. टोकन को टीएलएस सेशन से बाइंड करने से यह पक्का होता है कि मशीन-इन-द-मिडल के हमले नहीं हो रहे हैं. ऐसा इसलिए, क्योंकि टीएलएस सेशन में शामिल दोनों पक्ष ही नॉनस वैल्यू जनरेट कर पाएंगे.
  2. "uwear" के लिए ऑडियंस उपलब्ध कराई जाएगी. UWear यह पुष्टि करेगा कि यह एटेस्टेशन टोकन के लिए तय की गई ऑडियंस है.
  3. "PKI" टाइप का टोकन. "PKI" टोकन टाइप का मतलब है कि USleep, एक ऐसा टोकन चाहता है जिसमें सभी ज़रूरी जानकारी शामिल हो. सेल्फ़ कंटेन्ड टोकन की पुष्टि की जा सकती है कि इस पर Google ने हस्ताक्षर किया है. इसके लिए, Confidential Space के जाने-माने पीकेआई एंडपॉइंट से डाउनलोड किए गए रूट का इस्तेमाल करें. यह डिफ़ॉल्ट ओआईडीसी टोकन टाइप से अलग है. इसके हस्ताक्षर की पुष्टि, सार्वजनिक पासकोड का इस्तेमाल करके की जाती है. यह पासकोड नियमित तौर पर बदलता रहता है.

bb013916a3222ce7.png

USleep वर्कलोड को पुष्टि करने वाला टोकन मिलता है. इसके बाद, UWear, USleep के साथ टीएलएस कनेक्शन में शामिल हो जाता है और USleep का अटेस्टेशन टोकन वापस पा लेता है. UWear, टोकन की पुष्टि करेगा. इसके लिए, वह रूट सर्टिफ़िकेट के ख़िलाफ़ x5c दावे की जांच करेगा.

UWear, USleep वर्कलोड को तब मंज़ूरी देगा, जब:

  1. टोकन, पीकेआई की पुष्टि करने वाले लॉजिक को पूरा करता हो.
  2. UWear, टोकन की पुष्टि करेगा. इसके लिए, वह x5c दावे की तुलना रूट सर्टिफ़िकेट से करेगा. साथ ही, यह देखेगा कि टोकन पर लीफ़ सर्टिफ़िकेट के हस्ताक्षर हैं या नहीं. इसके बाद, वह यह देखेगा कि डाउनलोड किया गया रूट सर्टिफ़िकेट, x5c दावे में मौजूद रूट सर्टिफ़िकेट के जैसा ही है या नहीं.
  3. टोकन में, वर्कलोड मेज़रमेंट से जुड़े दावे, OPA नीति में बताई गई एट्रिब्यूट की शर्तों से मेल खाते हों. OPA एक ओपन सोर्स है. यह सामान्य मकसद के लिए इस्तेमाल किया जाने वाला नीति इंजन है. यह पूरे स्टैक में नीति लागू करने की प्रोसेस को एक साथ करता है. ओपीए, दस्तावेज़ों का इस्तेमाल करता है. इनका सिंटैक्स JSON के जैसा होता है. इनकी मदद से, बेसलाइन वैल्यू सेट की जाती हैं. इन वैल्यू के आधार पर, नीति की पुष्टि की जाती है. नीति किन वैल्यू की जांच करती है, इसका उदाहरण देखने के लिए ओपीए की बेसलाइन वैल्यू देखें.
  4. नॉनस, अनुमानित नॉनस (TLS एक्सपोर्ट किया गया कीइंग मटीरियल) से मेल खाता है. इसकी पुष्टि, ऊपर दी गई ओपीए की नीति में की गई है.

इन सभी जांचों के पूरा होने और पास होने के बाद, UWear इस बात की पुष्टि कर सकता है कि डेटा सुरक्षित तरीके से भेजा और प्रोसेस किया जाएगा. इसके बाद, UWear उसी टीएलएस सेशन में संवेदनशील पीएचआई के साथ जवाब देगा. साथ ही, USleep उस डेटा का इस्तेमाल करके, ग्राहक की नींद की क्वालिटी का हिसाब लगा पाएगा.

2. क्लाउड संसाधन सेट अप करना

शुरू करने से पहले

  1. USleep और UWear के लिए, दो Google Cloud प्रोजेक्ट सेट अप करें. Google Cloud प्रोजेक्ट बनाने के बारे में ज़्यादा जानने के लिए, कृपया "अपना पहला Google प्रोजेक्ट सेट अप करना और उसे नेविगेट करना" कोडलैब देखें. प्रोजेक्ट आईडी को वापस पाने का तरीका जानने के लिए, प्रोजेक्ट बनाना और मैनेज करना लेख पढ़ें. साथ ही, यह भी जानें कि प्रोजेक्ट आईडी, प्रोजेक्ट के नाम और प्रोजेक्ट नंबर से कैसे अलग होता है.
  2. अपने प्रोजेक्ट के लिए, बिलिंग की सुविधा चालू करें.
  3. अपने किसी एक Google प्रोजेक्ट के Cloud Shell में, प्रोजेक्ट के ज़रूरी एनवायरमेंट वैरिएबल सेट करें. इसके लिए, यहां दिया गया तरीका अपनाएं.
export UWEAR_PROJECT_ID=<Google Cloud project id of UWear>
export USLEEP_PROJECT_ID=<Google Cloud project id of USleep>
  1. दोनों प्रोजेक्ट के लिए, Confidential Computing API और यहां दिए गए एपीआई चालू करें.
gcloud config set project $UWEAR_PROJECT_ID
gcloud services enable \
    cloudapis.googleapis.com \
    cloudshell.googleapis.com \
    container.googleapis.com \
    containerregistry.googleapis.com \
    confidentialcomputing.googleapis.com

gcloud config set project $USLEEP_PROJECT_ID
gcloud services enable \
    cloudapis.googleapis.com \
    cloudshell.googleapis.com \
    container.googleapis.com \
    containerregistry.googleapis.com \
    confidentialcomputing.googleapis.com
  1. इनमें से किसी एक तरीके का इस्तेमाल करके, अपना प्रिंसिपल आइडेंटिफ़ायर वापस पाएं
gcloud auth list

# Output should contain
# ACCOUNT: <Principal Identifier>

# Set your member variable
export MEMBER='user:<Principal Identifier>'
  1. इन दोनों प्रोजेक्ट के लिए अनुमतियां जोड़ें. आईएएम की भूमिका असाइन करने वाले वेबपेज पर दी गई जानकारी को पढ़कर, अनुमतियां जोड़ी जा सकती हैं.
gcloud config set project $UWEAR_PROJECT_ID

# Add Artifact Registry Administrator role
gcloud projects add-iam-policy-binding $UWEAR_PROJECT_ID --member=$MEMBER --role='roles/iam.serviceAccountAdmin'

# Add Service Account Administrator role
gcloud projects add-iam-policy-binding $UWEAR_PROJECT_ID --member=$MEMBER --role='roles/artifactregistry.admin'
gcloud config set project $USLEEP_PROJECT_ID

# Add Service Account Administrator role
gcloud projects add-iam-policy-binding $USLEEP_PROJECT_ID --member=$MEMBER --role='roles/iam.serviceAccountAdmin'

# Add Artifact Registry Administrator role
gcloud projects add-iam-policy-binding $USLEEP_PROJECT_ID --member=$MEMBER --role='roles/artifactregistry.admin'

# Add Compute Administrator role
gcloud projects add-iam-policy-binding $USLEEP_PROJECT_ID --member=$MEMBER --role='roles/compute.admin'

# Add Storage Administrator role
gcloud projects add-iam-policy-binding $USLEEP_PROJECT_ID --member=$MEMBER --role='roles/compute.storageAdmin'
  1. अपने किसी Google Cloud प्रोजेक्ट के Cloud Shell में, Confidential Space Codelab Github Repository को क्लोन करें. इसके लिए, नीचे दिए गए कमांड का इस्तेमाल करें. इससे आपको वे ज़रूरी स्क्रिप्ट मिलेंगी जिनका इस्तेमाल इस कोडलैब में किया गया है.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  1. स्वास्थ्य से जुड़े डेटा के कोडलैब के लिए, डायरेक्ट्री को स्क्रिप्ट डायरेक्ट्री में बदलें.
cd confidential-space/codelabs/health_data_analysis_codelab/scripts
  1. codelabs/health_data_analysis_codelab/scripts डायरेक्ट्री में मौजूद, config_env.sh स्क्रिप्ट की इन दो लाइनों को अपडेट करें. USleep और UWear के लिए, अपने प्रोजेक्ट आईडी से प्रोजेक्ट आईडी अपडेट करें. लाइन की शुरुआत में मौजूद टिप्पणी के निशान "#" को हटाना न भूलें.
# TODO: Populate UWear and USleep Project IDs
export UWEAR_PROJECT_ID=your-uwear-project-id
export USLEEP_PROJECT_ID=your-usleep-project-id
  1. ज़रूरी नहीं: कोई भी पहले से मौजूद वैरिएबल सेट करें. इन वैरिएबल (जैसे, export UWEAR_ARTIFACT_REPOSITORY='my-artifact-repository') का इस्तेमाल करके, संसाधन के नामों को बदला जा सकता है
  • मौजूदा क्लाउड संसाधन के नामों के साथ, इन वैरिएबल को सेट किया जा सकता है. अगर वैरिएबल सेट है, तो प्रोजेक्ट के मौजूदा क्लाउड संसाधन का इस्तेमाल किया जाएगा. अगर वैरिएबल सेट नहीं किया जाता है, तो क्लाउड रिसॉर्स का नाम, config_env.sh स्क्रिप्ट में मौजूद वैल्यू से जनरेट किया जाएगा.
  1. संसाधन के नामों के लिए, अपने प्रोजेक्ट आईडी के आधार पर बाकी वैरिएबल के नामों को वैल्यू पर सेट करने के लिए, config_env.sh स्क्रिप्ट चलाएं.
# Navigate to the scripts folder
cd ~/confidential-space/codelabs/health_data_analysis_codelab/scripts

# Run the config_env script
source config_env.sh

# Verify the variables were set
# Expected output for default variable should be `workload-sa`
echo $USLEEP_WORKLOAD_SERVICE_ACCOUNT

3. रूट सर्टिफ़िकेट डाउनलोड करना

  1. अटेस्टेशन सेवा से मिले, खुद में शामिल टोकन की पुष्टि करने के लिए, UWear को कॉन्फ़िडेंशियल स्पेस के रूट सर्टिफ़िकेट के ख़िलाफ़ हस्ताक्षर की पुष्टि करनी होगी. UWear को रूट सर्टिफ़िकेट डाउनलोड करना होगा और इसे लोकल स्टोरेज में सेव करना होगा. अपने किसी Google Cloud प्रोजेक्ट के कंसोल में, ये कमांड चलाएं:
cd ~/confidential-space/codelabs/health_data_analysis_codelab/src/uwear

wget https://confidentialcomputing.googleapis.com/.well-known/confidential_space_root.crt -O confidential_space_root.pem
  1. डाउनलोड किए गए रूट सर्टिफ़िकेट का फ़िंगरप्रिंट जनरेट करें
openssl x509 -fingerprint -in confidential_space_root.pem -noout
  1. पुष्टि करें कि फ़िंगरप्रिंट, यहां दिए गए SHA-1 डाइजेस्ट से मेल खाता हो:
B9:51:20:74:2C:24:E3:AA:34:04:2E:1C:3B:A3:AA:D2:8B:21:23:21

4. वर्कलोड सेवा खाता बनाना

अब आपको दो सेवा खाते बनाने होंगे. एक USleep के लिए और दूसरा UWear के वर्कलोड के लिए. USleep और UWear प्रोजेक्ट में वर्कलोड सेवा खाते बनाने के लिए, create_service_accounts.sh स्क्रिप्ट चलाएं. वर्कलोड चलाने वाले वीएम, इन सेवा खातों का इस्तेमाल करेंगे.

# Navigate to the scripts folder
cd ~/confidential-space/codelabs/health_data_analysis_codelab/scripts

# Run the create_service_accounts script
./create_service_accounts.sh

स्क्रिप्ट:

  • यह iam.serviceAccountUser भूमिका असाइन करता है. इससे सेवा खाते को वर्कलोड से जोड़ा जाता है.
  • यह वर्कलोड सेवा खाते को confidentialcomputing.workloadUser भूमिका असाइन करता है . इससे उपयोगकर्ता खाते को पुष्टि करने वाला टोकन जनरेट करने की अनुमति मिल जाएगी.
  • इस भूमिका से, वर्कलोड सेवा खाते को logging.logWriter की अनुमति मिलती है. इससे Confidential Space एनवायरमेंट, सीरियल कंसोल के साथ-साथ Cloud Logging में भी लॉग लिख सकता है. इसलिए, वीएम बंद होने के बाद भी लॉग उपलब्ध रहते हैं. वर्कलोड बनाएं

5. USleep वर्कलोड बनाना

इस चरण के तहत, आपको इस कोडलैब में इस्तेमाल किए गए वर्कलोड के लिए Docker इमेज बनानी होंगी. USleep वर्कलोड, Golang का एक सामान्य ऐप्लिकेशन है. यह पहनने योग्य डिवाइस पर मौजूद निजी स्वास्थ्य जानकारी का इस्तेमाल करके, ग्राहक की नींद की क्वालिटी का पता लगाता है.

USleep वर्कलोड के बारे में जानकारी

USleep वर्कलोड एक सामान्य Golang ऐप्लिकेशन है. यह पहनने लायक डिवाइस पर मौजूद निजी स्वास्थ्य जानकारी का इस्तेमाल करके, ग्राहक की नींद की क्वालिटी का पता लगाता है. USleep वर्कलोड में तीन मुख्य चीज़ें शामिल हैं:

  1. TLS सेशन सेट अप करना और एक्सपोर्ट किया गया कीइंग मटीरियल निकालना
func handleConnectionRequest(w http.ResponseWriter, r *http.Request) {
  // Upgrade HTTP Connection to a websocket.
  conn, err := upgrader.Upgrade(w, r, nil)
  if err != nil {
    fmt.Printf("failed to upgrade connection to a websocket with err: %v\n", err)
    return
  }
  defer conn.Close()

  // Get EKM
  hash, err := getEKMHashFromRequest(r)
  if err != nil {
    fmt.Printf("Failed to get EKM: %v", err)
  }
  ...
}

func getEKMHashFromRequest(r *http.Request) (string, error) {
  ekm, err := r.TLS.ExportKeyingMaterial("testing_nonce", nil, 32)
  if err != nil {
    err := fmt.Errorf("failed to get EKM from inbound http request: %w", err)
    return "", err
  }

  sha := sha256.New()
  sha.Write(ekm)
  hash := base64.StdEncoding.EncodeToString(sha.Sum(nil))

  fmt.Printf("EKM: %v\nSHA hash: %v", ekm, hash)
  return hash, nil
}
  1. ऑडियंस, नॉनस, और पीकेआई टोकन टाइप के साथ, Attestation Service से टोकन का अनुरोध करना.
func handleConnectionRequest(w http.ResponseWriter, r *http.Request) {
  ...

  // Request token with TLS Exported Keying Material (EKM) hashed.
  token, err := getCustomToken(hash)
  if err != nil {
    fmt.Printf("failed to get custom token from token endpoint: %v", err)
    return
  }

  // Respond to the client with the token.
  conn.WriteMessage(websocket.TextMessage, token)

  ...
}

var (
        socketPath    = "/run/container_launcher/teeserver.sock"
        tokenEndpoint = "http://localhost/v1/token"
        contentType   = "application/json"
)


func getCustomToken(nonce string) ([]byte, error) {
  httpClient := http.Client{
    Transport: &http.Transport{
      // Set the DialContext field to a function that creates
      // a new network connection to a Unix domain socket
      DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
        return net.Dial("unix", socketPath)
      },
    },
  }

  body := fmt.Sprintf(`{
    "audience": "uwear",
    "nonces": ["%s"],
    "token_type": "PKI"
  }`, nonce)

  resp, err := httpClient.Post(tokenEndpoint, contentType, strings.NewReader(body))
  if err != nil {
    return nil, err
  }

  fmt.Printf("Response from launcher: %v\n", resp)
  text, err := io.ReadAll(resp.Body)
  if err != nil {
    return nil, fmt.Errorf("Failed to read resp.Body: %w", err)
  }
  fmt.Printf("Token from the attestation service: %s\n", text)

  return text, nil
}
  1. संवेदनशील डेटा पाना और उपयोगकर्ता की नींद की क्वालिटी का हिसाब लगाना
func handleConnectionRequest(w http.ResponseWriter, r *http.Request) {
  ...

  // Read the sensitive data
  _, content, err := conn.ReadMessage()
  if err != nil {
    fmt.Printf("failed to read message from the connection: %v\n", err)
  }
  fmt.Printf("Received content from other side, %v\n", string(content))

 // TODO: Handle sensitive data
  ...
}

USleep वर्कलोड बनाने का तरीका

  1. USleep वर्कलोड बनाने के लिए, create_usleep_workload.sh स्क्रिप्ट चलाएं. यह स्क्रिप्ट:
  • यह UWear के मालिकाना हक वाला Artifact Registry ($USLEEP_ARTIFACT_REPOSITORY) बनाता है. इसमें वर्कलोड पब्लिश किया जाएगा.
  • यह usleep/workload.go कोड बनाता है और इसे Docker इमेज में पैकेज करता है. USleep के लिए, Dockerfile कॉन्फ़िगरेशन देखें.
  • यह Docker इमेज को UWear के मालिकाना हक वाले Artifact Registry ($USLEEP_ARTIFACT_REPOSITORY) में पब्लिश करता है.
  • यह सेवा खाते को Artifact Registry ($USLEEP_ARTIFACT_REPOSITORY) के लिए $USLEEP_WORKLOAD_SERVICE_ACCOUNT पढ़ने की अनुमति देता है.
./create_usleep_workload.sh
  1. अहम जानकारी: आउटपुट लॉग में, USleep के लिए इमेज डाइजेस्ट निकालें.
latest: digest: sha256:<USLEEP_IMAGE_DIGEST> size: 945
  1. UWear डायरेक्ट्री पर जाएं
cd ~/confidential-space/codelabs/health_data_analysis_codelab/src/uwear
  1. opa_validation_values.json में मौजूद "allowed_submods_container_image_digest" की वैल्यू को USLEEP_IMAGE_DIGEST से बदलें.
# Replace the image digest
sed -i 's/sha256:bc4c32cb2ca046ba07dcd964b07a320b7d0ca88a5cf8e979da15cae68a2103ee/sha256:<USLEEP_IMAGE_DIGEST>/' ~/confidential-space/codelabs/health_data_analysis_codelab/src/uwear/opa_validation_values.json

6. UWear वर्कलोड बनाना

UWear Workload के बारे में जानकारी

UWear वर्कलोड में चार मुख्य हिस्से होते हैं:

  1. USleep के वर्कलोड में बनाए गए उसी टीएलएस सेशन में शामिल होना और सुरक्षित टीएलएस सेशन के ज़रिए USleep से पुष्टि करने वाला टोकन वापस पाना.
func main() {
  fmt.Println("Initializing client...")

  tlsconfig := &tls.Config{
    // Skipping client verification of the server's certificate chain and host name since we are
    // doing custom verification using the attestation token.
    InsecureSkipVerify: true,
  }

  dialer := websocket.Dialer{
    TLSClientConfig:  tlsconfig,
    HandshakeTimeout: 5 * time.Second,
  }

  ipAddress := os.Getenv(ipAddrEnvVar)
  url := fmt.Sprintf("wss://%s:8081/connection", ipAddress)

  fmt.Printf("Attempting to dial to url %v...\n", url)
  conn, _, err := dialer.Dial(url, nil)
  if err != nil {
    fmt.Printf("Failed to dial to url %s, err %v\n", url, err)
    return
  }

  defer conn.Close()

  tokenString, ekm, err := retrieveTokenAndEKMFromConn(conn)
  if err != nil {
    fmt.Printf("Failed to retrieve token and EKM from connection: %v\n", err)
    return
  }

  fmt.Printf("token: %v\n", tokenString)

  ...
}
  1. सेल्फ़ कंटेन्ड टोकन की पुष्टि करने के लिए:
  • x5c दावे की जांच करने पर पता चलता है कि इसमें एक सर्टिफ़िकेट चेन है. यह चेन, लीफ़ सर्टिफ़िकेट से इंटरमीडिएट और आखिर में रूट सर्टिफ़िकेट तक सही तरीके से जुड़ी हुई है.
  • जांच करना कि टोकन पर x5c दावे में मौजूद लीफ़ सर्टिफ़िकेट से हस्ताक्षर किया गया है.
  • यह जांचना कि डाउनलोड किया गया / सेव किया गया रूट सर्टिफ़िकेट, x5c दावे में मौजूद रूट सर्टिफ़िकेट जैसा ही है.
func main() {
  ...

  token, err := validatePKIToken(tokenString)
  if err != nil {
    fmt.Printf("Failed to validate PKI token, err: %v\n.", err)
    return
  }
  fmt.Println("PKI token validated successfully")
 
  ...
}

// validatePKIToken validates the PKI token returned from the attestation service.
// It verifies the token the certificate chain and that the token is signed by Google
// Returns a jwt.Token or returns an error if invalid.
func validatePKIToken(attestationToken string) (jwt.Token, error) {
  // IMPORTANT: The attestation token should be considered untrusted until the certificate chain and
  // the signature is verified.
  rawRootCertificate, err := readFile(rootCertificateFile)
  if err != nil {
    return jwt.Token{}, fmt.Errorf("readFile(%v) - failed to read root certificate: %w", rootCertificateFile, err)
  }

  storedRootCert, err := decodeAndParsePEMCertificate(string(rawRootCertificate))
  if err != nil {
    return jwt.Token{}, fmt.Errorf("DecodeAndParsePEMCertificate(string) - failed to decode and parse root certificate: %w", err)
  }

  jwtHeaders, err := extractJWTHeaders(attestationToken)
  if err != nil {
    return jwt.Token{}, fmt.Errorf("ExtractJWTHeaders(token) - failed to extract JWT headers: %w", err)
  }

  if jwtHeaders["alg"] != "RS256" {
    return jwt.Token{}, fmt.Errorf("ValidatePKIToken(attestationToken, ekm) - got Alg: %v, want: %v", jwtHeaders["alg"], "RS256")
  }

  // Additional Check: Validate the ALG in the header matches the certificate SPKI.
  // https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.7
  // This is included in Golang's jwt.Parse function

  x5cHeaders := jwtHeaders["x5c"].([]any)
  certificates, err := extractCertificatesFromX5CHeader(x5cHeaders)
  if err != nil {
    return jwt.Token{}, fmt.Errorf("ExtractCertificatesFromX5CHeader(x5cHeaders) returned error: %w", err)
  }

  // Verify the leaf certificate signature algorithm is an RSA key
  if certificates.LeafCert.SignatureAlgorithm != x509.SHA256WithRSA {
    return jwt.Token{}, fmt.Errorf("leaf certificate signature algorithm is not SHA256WithRSA")
  }

  // Verify the leaf certificate public key algorithm is RSA
  if certificates.LeafCert.PublicKeyAlgorithm != x509.RSA {
    return jwt.Token{}, fmt.Errorf("leaf certificate public key algorithm is not RSA")
  }

  // Verify the storedRootCertificate is the same as the root certificate returned in the token
  // storedRootCertificate is downloaded from the confidential computing well known endpoint
  // https://confidentialcomputing.googleapis.com/.well-known/attestation-pki-root
  err = compareCertificates(*storedRootCert, *certificates.RootCert)
  if err != nil {
    return jwt.Token{}, fmt.Errorf("failed to verify certificate chain: %w", err)
  }

  err = verifyCertificateChain(certificates)
  if err != nil {
    return jwt.Token{}, fmt.Errorf("VerifyCertificateChain(CertificateChain) - error verifying x5c chain: %v", err)
  }

  keyFunc := func(token *jwt.Token) (any, error) {
    return certificates.LeafCert.PublicKey, nil
  }

  verifiedJWT, err := jwt.Parse(attestationToken, keyFunc)
  return *verifiedJWT, err
}



// verifyCertificateChain verifies the certificate chain from leaf to root.
// It also checks that all certificate lifetimes are valid.
func verifyCertificateChain(certificates CertificateChain) error {
    // Additional check: Verify that all certificates in the cert chain are valid.
    // Note: The *x509.Certificate Verify method in Golang already validates this but for other coding
    // languages it is important to make sure the certificate lifetimes are checked.
    if isCertificateLifetimeValid(certificates.LeafCert) {
        return fmt.Errorf("leaf certificate is not valid")
    }

    if isCertificateLifetimeValid(certificates.IntermediateCert) {
        return fmt.Errorf("intermediate certificate is not valid")
    }
    interPool := x509.NewCertPool()
    interPool.AddCert(certificates.IntermediateCert)

    if isCertificateLifetimeValid(certificates.RootCert) {
        return fmt.Errorf("root certificate is not valid")
    }
    rootPool := x509.NewCertPool()
    rootPool.AddCert(certificates.RootCert)

    _, err := certificates.LeafCert.Verify(x509.VerifyOptions{
        Intermediates: interPool,
        Roots:         rootPool,
        KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
    })

    if err != nil {
        return fmt.Errorf("failed to verify certificate chain: %v", err)
    }

    return nil
}
  1. इसके बाद, UWear वर्कलोड यह देखेगा कि टोकन में मौजूद वर्कलोड मेज़रमेंट के दावे, OPA नीति में बताई गई एट्रिब्यूट की शर्तों से मेल खाते हैं या नहीं. OPA एक ओपन सोर्स है. यह सामान्य मकसद के लिए इस्तेमाल किया जाने वाला नीति इंजन है. यह पूरे स्टैक में नीति लागू करने की प्रोसेस को एक साथ करता है. ओपीए, दस्तावेज़ों का इस्तेमाल करता है. इनका सिंटैक्स JSON के जैसा होता है. इनकी मदद से, बेसलाइन वैल्यू सेट की जाती हैं. इन वैल्यू के आधार पर, नीति की पुष्टि की जाती है.
func main() {
  ...

  err = validateClaimsAgainstOPAPolicy(token, ekm)
  if err != nil {
    fmt.Printf("Failed to validate claims against OPA policy: %v\n", err)
  return
  }

  fmt.Println("Validated token and claims. Sending sensitive data")

  ...
}

// validateClaimsAgainstOPAPolicy validates the claims in the JWT token against the OPA policy.
func validateClaimsAgainstOPAPolicy(token jwt.Token, ekm string) error {
        data, err := os.ReadFile("opa_validation_values.json")
        authorized, err := evaluateOPAPolicy(context.Background(), token, ekm, string(data))
        if err != nil {
                fmt.Println("Error evaluating OPA policy:", err)
                return fmt.Errorf("failed to evaluate OPA policy: %w", err)
        }
        if !authorized {
                fmt.Println("Remote TEE's JWT failed policy check.")
                return fmt.Errorf("remote TEE's JWT failed policy check")
        }
        fmt.Println("JWT is authorized.")
        return nil
}


// evaluateOPAPolicy returns boolean indicating if OPA policy is satisfied or not, or error if occurred
func evaluateOPAPolicy(ctx context.Context, token jwt.Token, ekm string, policyData string) (bool, error) {
        var claims jwt.MapClaims
        var ok bool
        if claims, ok = token.Claims.(jwt.MapClaims); !ok {
                return false, fmt.Errorf("failed to get the claims from the JWT")
        }

        module := fmt.Sprintf(opaPolicy, ekm)

        var json map[string]any
        err := util.UnmarshalJSON([]byte(policyData), &json)
        store := inmem.NewFromObject(json)

        // Bind 'allow' to the value of the policy decision
        // Bind 'hw_verified', 'image_verified', 'audience_verified, 'nonce_verified' to their respective policy evaluations
        query, err := rego.New(
                rego.Query(regoQuery),                          // Argument 1 (Query string)
                rego.Store(store),                              // Argument 2 (Data store)
                rego.Module("confidential_space.rego", module), // Argument 3 (Policy module)
        ).PrepareForEval(ctx)

        if err != nil {
                fmt.Printf("Error creating query: %v\n", err)
                return false, err
        }

        fmt.Println("Performing OPA query evaluation...")
        results, err := query.Eval(ctx, rego.EvalInput(claims))

        if err != nil {
                fmt.Printf("Error evaluating OPA policy: %v\n", err)
                return false, err
        } else if len(results) == 0 {
                fmt.Println("Undefined result from evaluating OPA policy")
                return false, err
        } else if result, ok := results[0].Bindings["allow"].(bool); !ok {
                fmt.Printf("Unexpected result type: %v\n", ok)
                fmt.Printf("Result: %+v\n", result)
                return false, err
        }

        fmt.Println("OPA policy evaluation completed.")

        fmt.Println("OPA policy result values:")
        for key, value := range results[0].Bindings {
                fmt.Printf("[ %s ]: %v\n", key, value)
        }
        result := results[0].Bindings["allow"]
        if result == true {
                fmt.Println("Policy check PASSED")
                return true, nil
        }
        fmt.Println("Policy check FAILED")
        return false, nil
}
{
  "allowed_submods_container_image_digest": [
    "sha256:<USLEEP_IMAGE_DIGEST>"
  ],
  "allowed_hwmodel": [
    "GCP_INTEL_TDX",
    "GCP_SHIELDED_VM",
    "GCP_AMD_SEV_ES",
    "GCP_AMD_SEV"
  ],
  "allowed_aud": [
    "uwear"
  ],
  "allowed_issuer": [
    "https://confidentialcomputing.googleapis.com"
  ],
  "allowed_secboot": [
    true
  ],
  "allowed_sw_name": [
    "CONFIDENTIAL_SPACE"
  ]
}
  • Rego में लिखी गई OPA नीति का उदाहरण.
package confidential_space

import rego.v1

default allow := false
default hw_verified := false
default image_digest_verified := false
default audience_verified := false
default nonce_verified := false
default issuer_verified := false
default secboot_verified := false
default sw_name_verified := false

allow if {
  hw_verified
  image_digest_verified
  audience_verified
  nonce_verified
  issuer_verified
  secboot_verified
  sw_name_verified
}

hw_verified if input.hwmodel in data.allowed_hwmodel
image_digest_verified if input.submods.container.image_digest in data.allowed_submods_container_image_digest
audience_verified if input.aud in data.allowed_aud
issuer_verified if input.iss in data.allowed_issuer
secboot_verified if input.secboot in data.allowed_secboot
sw_name_verified if input.swname in data.allowed_sw_name
nonce_verified if {
  input.eat_nonce == "%s"
}
  • Rego क्वेरी का उदाहरण.
regoQuery = "
    allow = data.confidential_space.allow;
    hw_verified = data.confidential_space.hw_verified;
    image__digest_verified = data.confidential_space.image_digest_verified;
    audience_verified = data.confidential_space.audience_verified;
    nonce_verified = data.confidential_space.nonce_verified;
    issuer_verified = data.confidential_space.issuer_verified;
    secboot_verified = data.confidential_space.secboot_verified;
    sw_name_verified = data.confidential_space.sw_name_verified
"

ईकेएम हैश पाने के लिए कोड का उदाहरण:

func getEKMHashFromConn(c *websocket.Conn) (string, error) {
  conn, ok := c.NetConn().(*tls.Conn)
  if !ok {
    return "", fmt.Errorf("failed to cast NetConn to *tls.Conn")
  }

  state := conn.ConnectionState()
  ekm, err := state.ExportKeyingMaterial("testing_nonce", nil, 32)
  if err != nil {
    return "", fmt.Errorf("failed to get EKM from TLS connection: %w", err)
  }

  sha := sha256.New()
  sha.Write(ekm)
  hash := base64.StdEncoding.EncodeToString(sha.Sum(nil))

  return hash, nil
}
  1. इन सभी जांचों के पूरा होने और पास होने के बाद, UWear इस बात की पुष्टि कर सकता है कि डेटा को सुरक्षित तरीके से भेजा और प्रोसेस किया जाएगा. इसके बाद, UWear उसी टीएलएस सेशन में संवेदनशील पीएचआई के साथ जवाब देगा. साथ ही, USleep उस डेटा का इस्तेमाल करके, ग्राहक की नींद की क्वालिटी का हिसाब लगा पाएगा.
func main() {
  ...

  fmt.Println("Validated token and claims. Sending sensitive data")

  data, err := readFile(mySensitiveDataFile)
  if err != nil {
    fmt.Printf("Failed to read data from the file: %v\n", err)
  }

  conn.WriteMessage(websocket.BinaryMessage, data)
  fmt.Println("Sent payload. Closing the connection")
  conn.Close()
  
  ...
}

USleep वर्कलोड बनाने का तरीका

  1. स्क्रिप्ट डायरेक्ट्री पर जाएं
cd ~/confidential-space/codelabs/health_data_analysis_codelab/scripts
  1. UWear वर्कलोड बनाने के लिए, create_uwear_workload.sh स्क्रिप्ट चलाएं:
  • यह UWear के मालिकाना हक वाला Artifact Registry ($UWEAR_ARTIFACT_REPOSITORY) बनाता है. इसमें वर्कलोड पब्लिश किया जाएगा.
  • यह uwear/workload.go कोड बनाता है और इसे Docker इमेज में पैकेज करता है. USleep के लिए, Dockerfile कॉन्फ़िगरेशन देखें.
  • यह Docker इमेज को UWear के मालिकाना हक वाले Artifact Registry ($UWEAR_ARTIFACT_REPOSITORY) में पब्लिश करता है.
  • यह सेवा खाते को Artifact Registry ($UWEAR_ARTIFACT_REPOSITORY) के लिए $UWEAR_WORKLOAD_SERVICE_ACCOUNT पढ़ने की अनुमति देता है.
./create_uwear_workload.sh

7. USleep और UWear वर्कलोड चलाएं

USleep वर्कलोड चलाना

gcloud config set project $USLEEP_PROJECT_ID


gcloud compute instances create \
 --confidential-compute-type=SEV \
 --shielded-secure-boot \
 --maintenance-policy=MIGRATE \
 --scopes=cloud-platform --zone=${USLEEP_PROJECT_ZONE} \
 --image-project=confidential-space-images \
 --image-family=confidential-space \
--service-account=${USLEEP_WORKLOAD_SERVICE_ACCOUNT}@${USLEEP_PROJECT_ID}.iam.gserviceaccount.com \
 --metadata ^~^tee-image-reference=${USLEEP_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${USLEEP_PROJECT_ID}/${USLEEP_ARTIFACT_REPOSITORY}/${USLEEP_WORKLOAD_IMAGE_NAME}:${USLEEP_WORKLOAD_IMAGE_TAG}~tee-restart-policy=Never~tee-container-log-redirect=true usleep

जवाब में STATUS: RUNNING दिखना चाहिए. साथ ही, EXTERNAL_IP भी इसी तरह दिखना चाहिए:

NAME: usleep
ZONE: us-west1-b
MACHINE_TYPE: n2d-standard-2
PREEMPTIBLE:
INTERNAL_IP: 10.138.0.6
EXTERNAL_IP: 34.168.56.10
STATUS: RUNNING

बाहरी आईपी को किसी वैरिएबल में सेव करना

export USLEEP_EXTERNAL_IP=<add your external IP> 

पुष्टि करें कि USleep Workload सही तरीके से चला हो

यह पुष्टि करने के लिए कि USleep वर्कलोड सही तरीके से चल रहा है, USleep प्रोजेक्ट में वीएम इंस्टेंस पेज पर जाएं. "usleep" इंस्टेंस पर क्लिक करें. इसके बाद, लॉग सेक्शन में जाकर "सीरियल पोर्ट 1(कंसोल)" दबाएं. सर्वर चालू होने के बाद, लॉग में सबसे नीचे, लॉग में कुछ इस तरह की जानकारी दिखनी चाहिए.

2024/09/13 17:00:00 workload task started
#####----- Local IP Address is <YOUR-LOCAL-IP> -----#####
Starting Server..

UWear वर्कलोड चलाना

gcloud config set project $UWEAR_PROJECT_ID

gcloud compute instances create \
 --confidential-compute-type=SEV \
 --shielded-secure-boot \
 --maintenance-policy=MIGRATE \
 --scopes=cloud-platform --zone=${UWEAR_PROJECT_ZONE} \
 --image-project=confidential-space-images \
 --image-family=confidential-space \
--service-account=${UWEAR_WORKLOAD_SERVICE_ACCOUNT}@${UWEAR_PROJECT_ID}.iam.gserviceaccount.com \
 --metadata ^~^tee-image-reference=${UWEAR_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${UWEAR_PROJECT_ID}/${UWEAR_ARTIFACT_REPOSITORY}/${UWEAR_WORKLOAD_IMAGE_NAME}:${UWEAR_WORKLOAD_IMAGE_TAG}~tee-restart-policy=Never~tee-container-log-redirect=true~tee-env-remote_ip_addr=$USLEEP_EXTERNAL_IP uwear

पुष्टि करें कि UWear वर्कलोड सही तरीके से चला

UWear वर्कलोड के लॉग देखने के लिए, UWear प्रोजेक्ट में VM इंस्टेंस पेज पर जाएं. "uwear" इंस्टेंस पर क्लिक करें. इसके बाद, लॉग सेक्शन में जाकर "सीरियल पोर्ट 1(कंसोल)" दबाएं.

इंस्टेंस पूरी तरह से शुरू होने के बाद, लॉग आउटपुट ऐसा दिखना चाहिए

UWear प्रोजेक्ट में, सीरियल लॉग में कुछ ऐसा दिखना चाहिए

token: eyJ[...]MrXUg
PKI token validated successfully
Performing OPA query evaluation...
OPA policy evaluation completed.
OPA policy result values:
[ hw_verified ]: true
[ image__digest_verified ]: true
[ audience_verified ]: true
[ nonce_verified ]: true
[ issuer_verified ]: true
[ secboot_verified ]: true
[ sw_name_verified ]: true
[ allow ]: true
Policy check PASSED
JWT is authorized.
Validated token and claims. Sending sensitive data
Sent payload. Closing the connection

अगर आपका UWear वर्कलोड इस तरह नहीं दिखता है, तो निर्देशों के लिए यहां दिए गए नोट देखें.

USleep के नतीजे देखना

नतीजे देखने के लिए, USleep प्रोजेक्ट में VM इंस्टेंस पेज पर वापस जाएं. "usleep" इंस्टेंस पर क्लिक करें. इसके बाद, लॉग सेक्शन में जाकर "Serial port 1(console)" दबाएं. लॉग में सबसे नीचे, वर्कलोड के नतीजे देखें. ये नीचे दिए गए सैंपल की तरह दिखने चाहिए.

Token from the attestation service: eyJhbGci...Ii5A3CJBuDM2o5Q
Received content from other side, {
  "name": "Amy",
  "age": 29,
  "sleep": {
      "light": {
          "minutes": 270
      },
      "deep": {
          "minutes": 135
      },
      "rem": {
          "minutes": 105
      }
  }
}
Sleep quality result: total sleep time is less than 8 hours

नतीजा "total sleep time is less than 8 hours". होना चाहिए

बधाई हो! आपने UWear और USleep के बीच एक कॉन्फ़िडेंशियल स्पेस बना लिया है. अब यहां संवेदनशील जानकारी शेयर की जा सकती है!

8. (ज़रूरी नहीं) बिना अनुमति के वर्कलोड चलाना

अगले चरण में, USleep कोड को अपडेट करता है. साथ ही, UWear से मिले नींद के डेटा पर अलग वर्कलोड चलाता है. UWear ने इस नए वर्कलोड के लिए सहमति नहीं दी है. साथ ही, उसने नई इमेज डाइजेस्ट की अनुमति देने के लिए, OPA की नीति को अपडेट नहीं किया है. हम पुष्टि करेंगे कि UWear, अपने संवेदनशील डेटा को बिना अनुमति वाले वर्कलोड पर नहीं भेजेगा.

USleep अपने वर्कलोड में बदलाव करता है

  1. प्रोजेक्ट को $USLEEP_PROJECT_ID पर सेट करें.
gcloud config set project $USLEEP_PROJECT_ID
  1. USleep VM इंस्टेंस मिटाएं.
gcloud compute instances delete usleep --zone $USLEEP_PROJECT_ZONE
  1. usleep/workload.go डायरेक्ट्री पर जाएं.
cd ~/confidential-space/codelabs/health_data_analysis_codelab/src/usleep
  1. usleep/workload.go फ़ाइल में. लाइन "audience": "uwear". अपडेट करें इस उदाहरण में, इमेज डाइजेस्ट बदलने के लिए हम ऑडियंस को ऐसी वैल्यू पर अपडेट करेंगे जिसे UWear ने मंज़ूरी नहीं दी है. इसलिए, UWear को इसे दो वजहों से अस्वीकार करना चाहिए - इमेज डाइजेस्ट को मंज़ूरी नहीं मिली है और ऑडियंस गलत है.
"audience": "anotherCompany.com",
  1. USleep का नया वर्कलोड बनाएं
cd ~/confidential-space/codelabs/health_data_analysis_codelab/scripts

./create_usleep_workload.sh
  1. नया USleep VM इंस्टेंस बनाएं और वर्कलोड चलाएं
gcloud compute instances create \
 --confidential-compute-type=SEV \
 --shielded-secure-boot \
 --maintenance-policy=MIGRATE \
 --scopes=cloud-platform --zone=${USLEEP_PROJECT_ZONE} \
 --image-project=confidential-space-images \
 --image-family=confidential-space \
--service-account=${USLEEP_WORKLOAD_SERVICE_ACCOUNT}@${USLEEP_PROJECT_ID}.iam.gserviceaccount.com \
 --metadata ^~^tee-image-reference=${USLEEP_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${USLEEP_PROJECT_ID}/${USLEEP_ARTIFACT_REPOSITORY}/${USLEEP_WORKLOAD_IMAGE_NAME}:${USLEEP_WORKLOAD_IMAGE_TAG}~tee-restart-policy=Never~tee-container-log-redirect=true usleep
  1. बाद में इस्तेमाल करने के लिए, USleep का नया एक्सटर्नल आईपी पता निकालें
export USLEEP_EXTERNAL_IP=<add your external IP>

वर्कलोड को फिर से चलाएं

  1. UWear VM इंस्टेंस मिटाना
gcloud config set project $UWEAR_PROJECT_ID

gcloud compute instances delete uwear --zone $UWEAR_PROJECT_ZONE
  1. नए बाहरी आईपी का इस्तेमाल करके, UWear VM इंस्टेंस को फिर से बनाएं
gcloud compute instances create \
 --confidential-compute-type=SEV \
 --shielded-secure-boot \
 --maintenance-policy=MIGRATE \
 --scopes=cloud-platform --zone=${UWEAR_PROJECT_ZONE} \
 --image-project=confidential-space-images \
 --image-family=confidential-space \
--service-account=${UWEAR_WORKLOAD_SERVICE_ACCOUNT}@${UWEAR_PROJECT_ID}.iam.gserviceaccount.com \
 --metadata ^~^tee-image-reference=${UWEAR_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${UWEAR_PROJECT_ID}/${UWEAR_ARTIFACT_REPOSITORY}/${UWEAR_WORKLOAD_IMAGE_NAME}:${UWEAR_WORKLOAD_IMAGE_TAG}~tee-restart-policy=Never~tee-container-log-redirect=true~tee-env-remote_ip_addr=$USLEEP_EXTERNAL_IP uwear
  1. UWear के सीरियल लॉग में यह मैसेज दिखना चाहिए. साथ ही, USleep VM को कोई भी संवेदनशील डेटा नहीं मिलना चाहिए
OPA policy result values:
[ nonce_verified ]: true
[ issuer_verified ]: true
[ secboot_verified ]: true
[ sw_name_verified ]: true
[ allow ]: false
[ hw_verified ]: true
[ image__digest_verified ]: false
[ audience_verified ]: false
Policy check FAILED
Remote TEE's JWT failed policy check.
Failed to validate claims against OPA policy: remote TEE's JWT failed policy check

9. क्लीन अप करें

इस कोडलैब के तहत बनाए गए संसाधनों को हटाने के लिए, क्लीनअप स्क्रिप्ट का इस्तेमाल किया जा सकता है. इस क्लीनअप के तहत, ये संसाधन मिटा दिए जाएंगे:

  • UWear का सेवा खाता ($UWEAR_SERVICE_ACCOUNT).
  • UWear का आर्टफ़ैक्ट रजिस्ट्री ($UWEAR_ARTIFACT_REPOSITORY).
  • UWear Compute Instance
  • USleep का सेवा खाता ($USLEEP_SERVICE_ACCOUNT).
  • USleep का आर्टफ़ैक्ट रजिस्ट्री ($USLEEP_ARTIFACT_REPOSITORY).
  • USleep कंप्यूट इंस्टेंस
./cleanup.sh

अगर आपने एक्सप्लोर कर लिया है, तो कृपया इन निर्देशों का पालन करके अपना प्रोजेक्ट मिटा दें.

बधाई हो

बधाई हो, आपने कोडलैब पूरा कर लिया है!

आपने गोपनीय स्पेस का इस्तेमाल करके, डेटा की गोपनीयता बनाए रखते हुए उसे सुरक्षित तरीके से शेयर करने का तरीका सीखा.

आगे क्या करना है?

इस तरह के कुछ और कोडलैब देखें...

इस बारे में और पढ़ें