استخدام Secret Manager في Python

1. نظرة عامة

سوف تركز في هذا الدرس التطبيقي على كيفية استخدام Secret Manager في لغة Python.

يتيح لك Secret Manager تخزين المفاتيح السرّية وإدارتها والوصول إليها، مثل وحدات ثنائية أو سلاسل نصية. باستخدام الأذونات المناسبة، يمكنك عرض محتوى المفتاح السرّي.

يعمل "المدير السري" بشكل جيد لتخزين معلومات الإعداد، مثل كلمات مرور قاعدة البيانات أو مفاتيح واجهة برمجة التطبيقات أو شهادات بروتوكول أمان طبقة النقل (TLS) التي يحتاجها التطبيق في وقت التشغيل.

ما ستتعرَّف عليه

  • كيفية استخدام Cloud Shell
  • كيفية تثبيت مكتبة عملاء Secret Manager في Python
  • طريقة إنشاء المفاتيح السرّية والوصول إليها باستخدام مكتبة برامج Python
  • كيفية الوصول إلى المفاتيح السرّية في Cloud Functions باستخدام مكتبة برامج Python

المتطلبات

  • مشروع على Google Cloud
  • متصفح، مثل Chrome أو Firefox
  • الإلمام باستخدام بايثون 3

استطلاع

كيف ستستخدم هذا البرنامج التعليمي؟

القراءة فقط اقرأها وأكمِل التمارين

كيف تقيّم تجربتك مع Python؟

حديث متوسط بارع

ما هو تقييمك لتجربتك في استخدام خدمات Google Cloud؟

حديث متوسط بارع

2. الإعداد والمتطلبات

إعداد بيئة ذاتية

  1. سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديله في أي وقت.
  • يجب أن يكون رقم تعريف المشروع فريدًا في جميع مشاريع Google Cloud وغير قابل للتغيير (لا يمكن تغييره بعد ضبطه). تنشئ Cloud Console سلسلة فريدة تلقائيًا. فعادةً لا تهتم بما هو. في معظم الدروس التطبيقية حول الترميز، يجب الإشارة إلى رقم تعريف المشروع (يتم تحديده عادةً على أنّه PROJECT_ID). وإذا لم يعجبك المعرّف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. ويمكنك بدلاً من ذلك تجربة طلبك الخاص ومعرفة ما إذا كان متوفّرًا. ولا يمكن تغييره بعد هذه الخطوة وسيبقى طوال مدة المشروع.
  • لمعلوماتك، هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. اطّلِع على مزيد من المعلومات حول هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام الموارد/واجهات برمجة التطبيقات في Cloud. إنّ تنفيذ هذا الدرس التطبيقي حول الترميز لن يكون مكلفًا أو مكلفًا على الإطلاق. لإيقاف تشغيل الموارد حتى لا تتحمل الفوترة بعد هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع بالكامل. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج فترة تجريبية مجانية بقيمة 300 دولار أمريكي.

بدء Cloud Shell

مع أنّه يمكن إدارة Google Cloud عن بُعد من الكمبيوتر المحمول، ستستخدم في هذا الدرس التطبيقي Google Cloud Shell، وهي بيئة سطر أوامر يتم تشغيلها في السحابة الإلكترونية.

تفعيل Cloud Shell

  1. من Cloud Console، انقر على تفعيل Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

إذا لم يسبق لك بدء تشغيل Cloud Shell، ستظهر لك شاشة وسيطة (الجزء السفلي غير المرئي من الصفحة) تصف ماهيتها. إذا كان الأمر كذلك، فانقر على متابعة (ولن تراه مرة أخرى مطلقًا). إليك ما تبدو عليه هذه الشاشة التي تُستخدم لمرة واحدة:

9c92662c6a846a5c.png

من المفترَض أن تستغرق عملية إدارة الحسابات والاتصال بخدمة Cloud Shell بضع دقائق فقط.

9f0e51b578fecce5.png

يتم تحميل هذا الجهاز الافتراضي مع جميع أدوات التطوير التي تحتاجها. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. يمكنك تنفيذ معظم عملك، إن لم يكن كلّه، في هذا الدرس التطبيقي حول الترميز باستخدام متصفّح أو جهاز Chromebook.

بعد الربط بخدمة Cloud Shell، من المفترض أن ترى أنّه قد تمت مصادقتك وأنّ المشروع معيّن سبق أن تم ضبطه على رقم تعريف مشروعك.

  1. شغِّل الأمر التالي في Cloud Shell لتأكيد مصادقتك:
gcloud auth list

مخرجات الأمر

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. شغّل الأمر التالي في Cloud Shell للتأكد من معرفة الأمر gcloud بمشروعك:
gcloud config list project

مخرجات الأمر

[core]
project = <PROJECT_ID>

إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:

gcloud config set project <PROJECT_ID>

مخرجات الأمر

Updated property [core/project].

3- تفعيل واجهة برمجة تطبيقات Secret Manager API

قبل أن تبدأ في استخدام واجهة برمجة تطبيقات Secret Manager API، عليك تفعيل واجهة برمجة التطبيقات هذه. باستخدام Cloud Shell، يمكنك تفعيل واجهة برمجة التطبيقات باستخدام الأمر التالي:

gcloud services enable secretmanager.googleapis.com

من المفترض أن تظهر لك نتيجة على النحو التالي:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

4. تثبيت مكتبة عملاء "المدير السري" للغة بايثون

تثبيت مكتبة برامج المدير السرية:

pip3 install --user google-cloud-secret-manager==2.10.0

5- بدء لغة Python التفاعلية

في جزء من هذا البرنامج التعليمي، ستستخدم مترجمًا تفاعليًا بلغة Python يُسمى IPython، ويتم تثبيته مسبقًا في Cloud Shell. يمكنك بدء جلسة من خلال تشغيل ipython في Cloud Shell:

ipython

ينبغي أن تظهر لك على النحو التالي:

Python 3.9.2 (default, Feb 28 2021, 17:03:44)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.3.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

6- إنشاء الأسرار

يحتوي المفتاح السرّي على نسخة سرية واحدة أو أكثر. ويمكن إنشاؤها باستخدام سطر أوامر gcloud، ولكن يمكن إنشاؤها أيضًا باستخدام بايثون.

لاستخدام أحد المفاتيح السرّية، يجب أولاً إنشاء المفتاح السرّي باسم المفتاح السرّي ثم إضافة نسخة منه، وهي قيمة المفتاح السرّي.

اضبط رقم تعريف المشروع في IPython:

PROJECT_ID = "<PROJECT_ID>"

إنشاء مفتاح سرّي

انسخ الرمز التالي إلى جلسة IPython:

from google.cloud import secretmanager

def create_secret(secret_id):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the parent project.
    parent = f"projects/{PROJECT_ID}"

    # Build a dict of settings for the secret
    secret = {'replication': {'automatic': {}}}

    # Create the secret
    response = client.create_secret(secret_id=secret_id, parent=parent, secret=secret)

    # Print the new secret name.
    print(f'Created secret: {response.name}')   

استدعِ الدالة لإنشاء مفتاح سرّي جديد باسم my_secret_value:

create_secret("my_secret_value")

من المفترض أن يظهر لك الناتج التالي:

Created secret: projects/<PROJECT_NUM>/secrets/my_secret_value

إضافة إصدار سرّي

الآن بعد أن أصبح السر متوفرًا، يمكنك تحديد قيمة له عن طريق إنشاء نسخة.

انسخ الرمز التالي إلى جلسة IPython:

def add_secret_version(secret_id, payload):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the parent secret.
    parent = f"projects/{PROJECT_ID}/secrets/{secret_id}"

    # Convert the string payload into a bytes. This step can be omitted if you
    # pass in bytes instead of a str for the payload argument.
    payload = payload.encode('UTF-8')

    # Add the secret version.
    response = client.add_secret_version(parent=parent, payload={'data': payload})

    # Print the new secret version name.
    print(f'Added secret version: {response.name}')   

استدعِ الدالة لإنشاء إصدار سري جديد لإضافة إصدار سرّي جديد:

add_secret_version("my_secret_value", "Hello Secret Manager")

من المفترض أن يظهر لك الناتج التالي:

Added secret version: projects/<PROJECT_NUM>/secrets/my_secret_value/versions/1

يمكن أن يكون للأسرار إصدارات متعددة. استدع الدالة مرة أخرى بقيمة مختلفة:

add_secret_version("my_secret_value", "Hello Again, Secret Manager")

من المفترض أن يظهر لك الناتج التالي:

Added secret version: projects/<PROJECT_NUM>/secrets/my_secret_value/versions/2

لاحظ كيف أن النسخة الجديدة من سرنا أطول بكثير من النسخة الأصلية. ستتم الإشارة إلى هذه السمة لاحقًا.

7. الوصول إلى الأسرار

الوصول إلى نسخة سرية تؤدي إلى عرض المحتوى السري، بالإضافة إلى بيانات وصفية إضافية حول النسخة السرية. عند الوصول إلى إصدار سري، يمكنك إما تحديد إصدار معيّن أو طلب أحدث إصدار من خلال تحديد "الأحدث".

يجب الحفاظ على سرية الأسرار. تخزين بيانات اعتماد قاعدة البيانات كسرية ثم استخدامها للمصادقة أو تخزين الشهادات واستخدامها ولكن لا تطبع أسرارك بشكل مباشر، لأن ذلك يقوّض أغراض إبقائها سرية.

ستُجري عمليات على أسرارنا، ونقيّم قيمتها بدون طباعتها مباشرةً. بدلاً من ذلك، ستطبع جزءًا من قيمة المفتاح السرّي.

انسخ الرمز التالي إلى جلسة IPython:

def access_secret_version(secret_id, version_id="latest"):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the secret version.
    name = f"projects/{PROJECT_ID}/secrets/{secret_id}/versions/{version_id}"

    # Access the secret version.
    response = client.access_secret_version(name=name)

    # Return the decoded payload.
    return response.payload.data.decode('UTF-8')
    
import hashlib

def secret_hash(secret_value): 
  # return the sha224 hash of the secret value
  return hashlib.sha224(bytes(secret_value, "utf-8")).hexdigest()

استدعِ الدالة لاسترداد المفتاح السرّي كتجزئة لقيمته:

secret_hash(access_secret_version("my_secret_value"))

من المفترض أن تظهر لك نتيجة تشبه تجزئة (قد لا تتطابق القيمة الدقيقة مع هذا الناتج):

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

بما أنّك لم تحدّد إصدارًا، تم استرداد أحدث قيمة.

استدعِ الدالة التي تضيف رقم الإصدار المتوقع للتأكيد:

secret_hash(access_secret_version("my_secret_value", version_id=2))

من المفترض أن تظهر لك النتائج نفسها التي ظهرت في الأمر الأخير:

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

قم باستدعاء الدالة مرة أخرى، ولكن هذه المرة لتحديد الإصدار الأول:

secret_hash(access_secret_version("my_secret_value", version_id=1))

من المفترَض أن تظهر لك تجزئة مختلفة هذه المرة، تشير إلى ناتج مختلف:

9a3fc8b809ddc611c82aee950c636c7557e220893560ec2c1eeeb177

8. استخدام Secret Manager مع دوال السحابة

يمكنك الاستفادة من الأسرار في العديد من أجزاء Google Cloud. في هذا القسم، ستركّز على Cloud Functions، وهي ميزة من Google توفّر حوسبة بدون خادم.

إذا أردت استخدام Python في Cloud Functions، يمكنك اتّباع HTTP Google Cloud Functions في الدرس التطبيقي حول ترميز Python.

أغلق IPython عن طريق استدعاء الدالة exit:

exit

من المفترض أن تتم إعادتك إلى Cloud Shell:

yourname@cloudshell:~ (<PROJECT_ID>)$

يجب تفعيل واجهة برمجة التطبيقات أولاً قبل أن تتمكّن من البدء في استخدام Cloud Functions API. باستخدام Cloud Shell، يمكنك تفعيل واجهة برمجة التطبيقات باستخدام الأمر التالي:

gcloud services enable cloudfunctions.googleapis.com cloudbuild.googleapis.com

أنشِئ مجلدًا جديدًا لإنشاء الدالة، وإنشاء ملفات فارغة للكتابة إليها:

mkdir secret-manager-api-demo
cd secret-manager-api-demo
touch main.py
touch requirements.txt

افتح محرِّر الرموز من أعلى يسار Cloud Shell:

7651a97c51e11a24.png

انتقِل إلى ملف main.py داخل المجلد secret-manager-api-demo. هذا هو المكان الذي ستضع فيه جميع تعليماتك البرمجية.

9. كتابة دالة سحابية للوصول إلى الأسرار

فيما يعتبر تخزين واسترداد القيم السرية من سطر الأوامر أو الوحدة الطرفية في IPython أمرًا مفيدًا، فالأفضل بكثير أن تكون قادرًا على الوصول إلى هذه الأسرار داخل دالة.

باستخدام الدالة access_secret_version التي أنشأتها سابقًا، يمكنك استخدامها كأساس لدالة السحابة الإلكترونية.

انسخ الرمز التالي في ملف main.py:

main.py

import os

from google.cloud import secretmanager

project_id = os.environ["PROJECT_ID"]

client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/my_secret_value/versions/latest"
response = client.access_secret_version(name=name)
my_secret_value = response.payload.data.decode("UTF-8")


def secret_hello(request):
    if "Again" in my_secret_value:
        return "We meet again!\n"

    return "Hello there.\n"

قبل أن تتمكن من نشر الدالة، تحتاج إلى إنهاء إعداد البيئة. يتطلب هذا إعداد تبعية الدالة.

أنشئ ملفًا جديدًا باسم requirements.txt، وأضِف حزمة google-cloud-secret-manager إليه:

requirements.txt

google-cloud-secret-manager==2.10.0

من المفترض أن يكون لديك الآن مجلّد يحتوي على main.py وrequirements.txt فقط.

السماح بالوصول إلى المفتاح السرّي

قبل أن تتمكن من نشر الدالة، يجب أن تسمح للوظائف السحابية بإمكانية الوصول إلى المفتاح السرّي.

التبديل مرة أخرى إلى الوحدة الطرفية:

c5b686edf94b5222.png

يمكنك منح إذن الوصول إلى حساب خدمة Cloud Functions لتتمكّن من الوصول إلى المفتاح السرّي:

export PROJECT_ID=$(gcloud config get-value core/project)

gcloud secrets add-iam-policy-binding my_secret_value \
    --role roles/secretmanager.secretAccessor \
    --member serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com

من المفترض أن يظهر لك الناتج التالي:

Updated IAM policy for secret [my_secret_value].
bindings:
- members:
  - serviceAccount:<PROJECT_ID>@appspot.gserviceaccount.com
  role: roles/secretmanager.secretAccessor
etag: BwWiRUt2oB4=
version: 1

10. نشر دالة Cloud

وفقًا لعملية الإعداد في الأقسام السابقة، يمكنك الآن نشر دالة Cloud واختبارها.

داخل المجلد الذي يحتوي على الملفين اللذين أنشأتهما فقط، انشر الدالة:

gcloud functions deploy secret_hello \
    --runtime python39 \
    --set-env-vars PROJECT_ID=${PROJECT_ID} \
    --trigger-http \
    --allow-unauthenticated

من المفترض أن يظهر لك الناتج التالي (مقطوع):

Deploying function (may take a while - up to 2 minutes)...done.

...

entryPoint: secret_hello
httpsTrigger:
  url: https://<REGION>-<PROJECT_ID>.cloudfunctions.net/secret_hello
...
status: ACTIVE
...

يمكنك استرداد عنوان URL للدالة (بيانات httpsTrigger.url الوصفية) باستخدام الأمر التالي:

FUNCTION_URL=$(gcloud functions describe secret_hello --format 'value(httpsTrigger.url)')

الآن، اختبار يمكن الوصول إلى الدالة باستخدام القيمة المعروضة المتوقعة، عن طريق استدعاء الدالة:

curl $FUNCTION_URL

من المفترض أن يظهر لك الناتج التالي:

We meet again!

تشير هذه الدالة إلى أحدث إصدار من المفتاح السرّي الذي تم ضبطه ليتضمّن السلسلة "Aمرة"، لذا تعمل هذه الدالة على النحو المتوقّع.

11. تهانينا

لقد تعلمت كيفية استخدام واجهة برمجة تطبيقات Secret Manager باستخدام Python!

تَنظيم

لتجنُّب تحمُّل الرسوم المفروضة على حسابك على Google Cloud مقابل الموارد المستخدَمة في هذا البرنامج التعليمي:

  • في Cloud Console، انتقِل إلى صفحة إدارة الموارد.
  • في قائمة المشاريع، اختَر مشروعك، ثم انقر على حذف.
  • في مربّع الحوار، اكتب رقم تعريف المشروع ثم انقر على إيقاف التشغيل لحذف المشروع.

مزيد من المعلومات

الترخيص

هذا العمل مرخّص بموجب رخصة المشاع الإبداعي 2.0 مع نسب العمل إلى مؤلف عام.