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

1. نظرة عامة

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

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

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

أهداف الدورة التعليمية

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

المتطلبات

  • مشروع Google Cloud
  • متصفّح، مثل Chrome أو Firefox
  • الإلمام باستخدام Python 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. تثبيت مكتبة عميل Secret Manager للغة Python

ثبِّت مكتبة برامج Secret Manager:

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 سطر الأوامر، ولكن يمكن أيضًا إنشاؤها باستخدام Python.

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

اضبط رقم تعريف مشروعك ضِمن 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. الوصول إلى المفاتيح السرّية

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

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

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

انسخ الرمز التالي إلى جلسة 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 مع Cloud Functions

يمكنك الاستفادة من الأسرار في العديد من أقسام 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- كتابة دالة Cloud Function للوصول إلى المفاتيح السرية

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

باستخدام الدالة access_secret_version التي أنشأتها سابقًا، يمكنك استخدامها كأساس لـ Cloud Function.

انسخ الرمز التالي في ملف 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 فقط.

السماح بالوصول إلى سرّك

قبل أن تتمكّن من نشر الدالة، عليك السماح لخدمة Cloud Functions بالوصول إلى سرّك.

العودة إلى النافذة الطرفية:

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 Function

بعد إكمال عملية الإعداد في الأقسام السابقة، يمكنك الآن نشر دالة 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!

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

11. تهانينا!

تعرّفت على كيفية استخدام Secret Manager API باستخدام Python.

تَنظيم

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

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

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

الترخيص

يخضع هذا العمل لترخيص المشاع الإبداعي مع نسب العمل إلى مؤلفه 2.0 Generic License.