EduFlow
أساسيات AWS السحابية
⁦0%⁩

الوحدة 2 · الهوية والأمان

قراءة سياسات IAM وكتابتها

20 دقراءة 4 داكتشف الخطأ

الدرس في لمحة

اقرأ أي سياسة IAM عبارةً عبارة، واكتب سياسات بمبدأ أقل الصلاحيات مع ARNs دقيقة، وأضف شروطًا مثل MFA وTLS تضيّق متى ينطبق السماح.

  1. 1تشريح العبارة
  2. 2ARN الـ bucket أم ARN الكائن؟
  3. 3أقل الصلاحيات عمليًا
  4. 4الشروط: متى ينطبق السماح
  5. 5تحقّق قبل أن ترفق

لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.

في الدرس السابق تعلّمت كيف يقرّر IAM. والآن تكتب ما يقرّر بناءً عليه. يحتاج Lantern إلى سياسة للدالة التي تستقبل الملصقات المرفوعة، وسياسة للمطوّرين، وسياسة bucket تحمي الملصقات. والثلاث مكتوبة بلغة JSON الصغيرة نفسها.

تشريح العبارة

إليك سياسة دالة الرفع في Lantern، التي تحفظ الملصقات تحت uploads/ وتسرد أحيانًا ما يوجد هناك:

lantern-upload-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "WriteUploads",
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::lantern-posters/uploads/*"
    },
    {
      "Sid": "ListUploadsOnly",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::lantern-posters",
      "Condition": {
        "StringLike": { "s3:prefix": "uploads/*" }
      }
    }
  ]
}

اقرأها من الأعلى إلى الأسفل:

  • Version دائمًا "2012-10-17"، وهو الإصدار الحالي للغة السياسات. إنه نص ثابت، لا تاريخ اليوم.
  • Statement قائمة. وكل عبارة تُقيَّم وحدها.
  • Sid تسمية اختيارية. سمِّ الغرض من العبارة؛ وستشكرك نفسك في المستقبل.
  • Effect قيمته Allow أو Deny.
  • Action إجراء واحد أو قائمة، ويُكتب بالشكل service:Operation. الرموز البديلة تعمل (s3:Get*) لكن كل واحد منها يوسّع الباب.
  • Resource ARN واحد أو قائمة. والرموز البديلة تعمل هنا أيضًا.
  • Condition اختياري ويضيّق متى تنطبق العبارة.

تضيف السياسات القائمة على المورد، مثل سياسات الـ buckets، عنصر Principal يسمّي من تخصّه العبارة. أما السياسات القائمة على الهوية فلا تحتوي عليه، لأن الهوية المرفقة بها هي الـ principal.

ARN الـ bucket أم ARN الكائن؟

للسياسة أعلاه موردان مختلفان عن قصد. s3:ListBucket عملية على الـ bucket، لذا موردها هو arn:aws:s3:::lantern-posters. وs3:PutObject عملية على الكائنات، لذا موردها ARN الـ bucket متبوعًا بمسار: lantern-posters/uploads/*. بدّل بينهما فلن تطابق أيٌّ من العبارتين أبدًا، وستحصل على AccessDenied مع سياسة تبدو صحيحة.

التمييز نفسه موجود في أماكن أخرى. فالإجراء dynamodb:Query على index في جدول يحتاج إلى ARN الـ index (table/lantern-rsvps/index/by-event)، لا إلى ARN الجدول وحده. عندما تسمح سياسة “بوضوح” بشيء وترفضه AWS، قارن ARN الطلب بـ ARN السياسة حرفًا حرفًا.

أقل الصلاحيات عمليًا

أقل الصلاحيات (least privilege) يعني ألّا تمنح إلا الإجراءات والموارد التي تحتاجها المهمة. يبدو هذا بطيئًا، لكن طريقة العمل سريعة:

  1. اكتب ما تفعله المهمة بكلمات بسيطة: “تكتب الملصقات في uploads/، وتسرد تلك البادئة”.
  2. ترجم كل فعل إلى إجراء، وكل اسم إلى ARN دقيق.
  3. انشر واختبر. رسالة AccessDenied تسمّي الإجراء والمورد الناقصين؛ أضف ذلك بالضبط.

بالنسبة إلى الـ roles الموجودة، يعرض IAM معلومات آخر وصول (last accessed) لكل خدمة، ويستطيع IAM Access Analyzer توليد سياسة من الإجراءات التي استخدمها الـ role فعلًا وفق AWS CloudTrail. وكلاهما طريقة جيدة لتقليص سياسة اتّسعت أكثر من اللازم.

الشروط: متى ينطبق السماح

كتلة الشرط تربط العوامل (operators) بـ المفاتيح (keys) والقيم (values):

JSON
"Condition": {
  "StringEquals": { "aws:RequestedRegion": ["eu-west-1", "eu-south-2"] },
  "Bool": { "aws:MultiFactorAuthPresent": "true" }
}

قاعدتان تجعلان الشروط قابلة للتوقّع. المفاتيح المنفصلة تُجمع بـ AND: يجب أن يكون الطلب في إحدى تلك الـ Regions وأن يُرسَل باستخدام MFA. والقيم المتعدّدة للمفتاح الواحد تُجمع بـ OR: أيٌّ من الاثنتين تفي بالغرض.

مفاتيح مفيدة لـ Lantern:

المفتاح استخدمه من أجل
aws:SecureTransport رفض طلبات HTTP العادي
aws:MultiFactorAuthPresent اشتراط MFA للإجراءات الخطرة مثل الحذف
aws:SourceIp قصر الإنسان على نطاق عناوين المكتب أو الـ VPN
aws:RequestedRegion إبقاء العمل داخل الـ Regions الخاصة بـ Lantern
s3:prefix قصر ListBucket على مجلّد واحد

والشروط ممتازة أيضًا كحواجز حماية بـ الرفض. ترفض سياسة الـ bucket في Lantern أي طلب دون TLS، من أي أحد:

lantern-posters-bucket-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyInsecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::lantern-posters",
        "arn:aws:s3:::lantern-posters/*"
      ],
      "Condition": { "Bool": { "aws:SecureTransport": "false" } }
    }
  ]
}

ولأن الرفض الصريح ينتصر دائمًا، لا يستطيع أي سماح في أي مكان إلغاءه.

تحقّق قبل أن ترفق

يشغّل محرّر السياسات في console الـ IAM فحوص IAM Access Analyzer أثناء كتابتك: أخطاء الصياغة، والإجراءات غير الصالحة، والتحذيرات الأمنية مثل رمز بديل في pass-role. ومن الطرفية:

Terminal
aws accessanalyzer validate-policy \
  --policy-type IDENTITY_POLICY \
  --policy-document file://lantern-upload-policy.json \
  --query "findings[].[findingType,issueCode]" --output table

النتيجة الفارغة تعني عدم وجود ملاحظات. أصلح كل ERROR وSECURITY_WARNING، واقرأ كل WARNING وSUGGESTION.

أصبحت تستطيع كتابة صلاحيات محكمة. في الدرس التالي: كيف يحصل عليها الأشخاص دون مستخدمي IAM، وكيف يحصل عليها الكود دون مفاتيح وصول.

أهم النقاط

  • العبارة (statement) هي Effect وAction وResource، ويمكن تضييقها اختياريًا بـ Condition؛ وتسمّي السياسات القائمة على المورد Principal أيضًا.
  • الإجراءات على مستوى الـ bucket مثل s3:ListBucket تأخذ ARN الـ bucket، أما الإجراءات على مستوى الكائن مثل s3:GetObject فتحتاج إلى ARN الـ bucket متبوعًا بـ /* أو بمسار أضيق.
  • أقل الصلاحيات (least privilege) يعني أن تسرد الإجراءات والموارد المحدّدة التي تحتاجها المهمة، ثم لا توسّعها إلا حين يخبرك خطأ AccessDenied حقيقي بذلك.
  • مفاتيح الشروط تُجمع بينها بـ AND، والقيم المتعدّدة للمفتاح الواحد تُجمع بـ OR.
  • تحقّق من كل سياسة قبل إرفاقها باستخدام IAM Access Analyzer، في محرّر الـ console أو عبر aws accessanalyzer validate-policy.

قراءات إضافية

تحقّق من فهمك

4 أسئلة

السؤال 1 من 4

دالة لها هذه السياسة تستدعي GetObject على posters/2026/festival.jpg في الـ bucket المسمّى lantern-posters فتحصل على AccessDenied. لماذا؟

JSON
{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::lantern-posters"
}
السؤال 2 من 4

أيّ الطلبات يسمح بها هذا الشرط؟

JSON
"Condition": {
  "StringEquals": { "aws:RequestedRegion": ["eu-west-1", "eu-south-2"] },
  "Bool": { "aws:SecureTransport": "true" }
}
السؤال 3 من 4

تحتاج إلى سياسة لدالة تغيير حجم الملصقات في Lantern، لكنك لست متأكّدًا من إجراءات S3 التي تستدعيها. ما أفضل نقطة بداية؟

السؤال 4 من 4

ماذا تفعل عبارة سياسة الـ bucket هذه؟

JSON
{
  "Effect": "Deny",
  "Principal": "*",
  "Action": "s3:*",
  "Resource": ["arn:aws:s3:::lantern-posters", "arn:aws:s3:::lantern-posters/*"],
  "Condition": { "Bool": { "aws:SecureTransport": "false" } }
}

تدريب

اكتشف الخطأ

راجع سياسة Developers

كتب أحد زملائك هذه السياسة القائمة على الهوية لمجموعة Developers في Lantern. والمقصود، بحسب التذكرة: يستطيع المطوّرون قراءة تأكيدات الحضور وكتابتها (get وput وquery للعناصر) في جدول lantern-rsvps، وقراءة أي ملصق في الـ bucket المسمّى lantern-posters، وحذف الملصقات فقط عند تسجيل الدخول باستخدام MFA. اختر كل سطر يخالف هذا المقصود.

حدّد السطر أو الأسطر التي تظنها خاطئة، ثم تحقّق.