الوحدة 2 · الهوية والأمان
قراءة سياسات IAM وكتابتها
20 دقراءة 4 داكتشف الخطأ
الدرس في لمحة
اقرأ أي سياسة IAM عبارةً عبارة، واكتب سياسات بمبدأ أقل الصلاحيات مع ARNs دقيقة، وأضف شروطًا مثل MFA وTLS تضيّق متى ينطبق السماح.
- 1تشريح العبارة
- 2ARN الـ bucket أم ARN الكائن؟
- 3أقل الصلاحيات عمليًا
- 4الشروط: متى ينطبق السماح
- 5تحقّق قبل أن ترفق
لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.
في الدرس السابق تعلّمت كيف يقرّر IAM. والآن تكتب ما يقرّر بناءً عليه. يحتاج Lantern إلى سياسة للدالة التي تستقبل الملصقات المرفوعة، وسياسة للمطوّرين، وسياسة bucket تحمي الملصقات. والثلاث مكتوبة بلغة JSON الصغيرة نفسها.
تشريح العبارة
إليك سياسة دالة الرفع في Lantern، التي تحفظ الملصقات تحت uploads/ وتسرد أحيانًا ما يوجد هناك:
{
"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*) لكن كل واحد منها يوسّع الباب.ResourceARN واحد أو قائمة. والرموز البديلة تعمل هنا أيضًا.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) يعني ألّا تمنح إلا الإجراءات والموارد التي تحتاجها المهمة. يبدو هذا بطيئًا، لكن طريقة العمل سريعة:
- اكتب ما تفعله المهمة بكلمات بسيطة: “تكتب الملصقات في
uploads/، وتسرد تلك البادئة”. - ترجم كل فعل إلى إجراء، وكل اسم إلى ARN دقيق.
- انشر واختبر. رسالة AccessDenied تسمّي الإجراء والمورد الناقصين؛ أضف ذلك بالضبط.
بالنسبة إلى الـ roles الموجودة، يعرض IAM معلومات آخر وصول (last accessed) لكل خدمة، ويستطيع IAM Access Analyzer توليد سياسة من الإجراءات التي استخدمها الـ role فعلًا وفق AWS CloudTrail. وكلاهما طريقة جيدة لتقليص سياسة اتّسعت أكثر من اللازم.
الشروط: متى ينطبق السماح
كتلة الشرط تربط العوامل (operators) بـ المفاتيح (keys) والقيم (values):
"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، من أي أحد:
{
"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. ومن الطرفية:
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.