شبكات AWS والهوية

الوصول عبر الحسابات وخدمة STS

18 دقيقة الدرس 8 من 28

الوصول عبر الحسابات وخدمة STS

على نطاق الشركات الكبرى، يُعدّ الاعتماد على حساب AWS واحد نمطًا مضادًا للجودة. تعيش بيئات الإنتاج والاختبار والأمان والتسجيل والخدمات المشتركة في حسابات منفصلة داخل AWS Organization. يحتاج المهندسون وخطوط CI/CD والخدمات إلى العبور المستمر بين هذه الحسابات — والآلية التي تجعل ذلك ممكنًا دون مشاركة بيانات اعتماد طويلة الأمد هي خدمة AWS Security Token Service (STS) مع AssumeRole في IAM.

لماذا نفصل الحسابات؟

العزل على مستوى الحساب هو أقوى آلية للتحكم في نطاق الضرر التي تقدمها AWS. بيانات الاعتماد المخترقة في بيئة الاختبار لا تستطيع لمس بيانات الإنتاج. تفرض سياسات التحكم في الخدمات (SCPs) على مستوى المؤسسة قيودًا لا يستطيع حتى المستخدم الجذر تجاوزها. تعمل تخصيصات التكلفة وـ CloudTrail وـ AWS Config لكل حساب على حدة، مما يوفر سجلات تدقيق نظيفة. النمط المعياري هو: حساب إدارة للمؤسسة فقط، وحساب أمان/تدقيق، وحساب خدمات مشتركة (DNS وـ ECR وأدوات CI/CD)، وحسابات أعباء عمل منفصلة لكل فريق أو بيئة.

تدفق AssumeRole

الآلية الأساسية هي سلسلة من أربع خطوات: مستدعٍ (مستخدم IAM أو دور أو خدمة AWS) في الحساب A يستدعي sts:AssumeRole مستهدفًا ARN دور في الحساب B. تتحقق STS من أن سياسة الثقة على الدور المستهدف تسمح للمستدعي، ثم تُصدر بيانات اعتماد قصيرة الأمد (معرّف مفتاح الوصول، المفتاح السري، رمز الجلسة) صالحة من 15 دقيقة حتى 12 ساعة وتُعيدها. يضمّن المستدعي تلك البيانات في استدعاءات API اللاحقة — وتقيّمها AWS مقابل سياسات الأذونات للدور المستهدف في الحساب B.

Cross-Account AssumeRole Flow Account A (Dev / CI) Caller Identity IAM Role / User / EC2 Instance 1. sts:AssumeRole(RoleArn, ExternalId) AWS STS Validates trust policy 2. Temp credentials (AK + SK + Token) 3. API call with temp creds Account B (Prod) Target IAM Role arn:aws:iam::PROD:role/DeployRole Trust Policy Principal: Account A role ARN Permission Policy s3:GetObject, ecr:BatchGetImage… 4. AWS evaluates temp creds against the Permission Policy in Account B
تدفق AssumeRole عبر الحسابات من أربع خطوات: يطلب المستدعي في الحساب A بيانات اعتماد مؤقتة من STS، ثم يستخدمها لاستدعاء APIs في الحساب B تحت أذونات الدور المستهدف.

سياسات الثقة — الباب

سياسة الثقة هي السياسة القائمة على الموارد المُرفقة بالدور نفسه، وتجيب على: "من يُسمح له بافتراض هذا الدور؟" تستخدم الإجراء sts:AssumeRole مع عنصر Principal يُسمي الكيان الموثوق — معرّف حساب، أو ARN دور محدد، أو خدمة AWS.

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowDevCICDRole", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/CICDDeployRole" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "prod-deploy-external-id-abc123" } } } ] }
سياستان، مهمتان: سياسة الثقة تتحكم في من يستطيع افتراض الدور (الباب)؛ سياسة الأذونات تتحكم في ما يمكنه فعله بمجرد الدخول (الغرفة). يجب أن تكون كلتاهما صحيحتين حتى ينجح الوصول.

المعرّف الخارجي — الدفاع ضد هجوم النائب المرتبك

تخيّل أنك تبني أداة SaaS تفترض دورًا في حساب AWS الخاص بعميلك لقراءة مقاييس CloudWatch. تُهيئ سياسة الثقة لتثق في حساب AWS الخاص بـ SaaS. الآن فكّر: يمكن لعميل آخر أن يخدع أداة SaaS الخاصة بك لاستخدام بيانات اعتمادها الشرعية الخاصة لافتراض دور عميلك الأول عبر توفير ذلك ARN. هذا هو هجوم النائب المرتبك.

الحل هو معرّف خارجي (External ID): قيمة سرية مشتركة يتفق عليها الطرفان (أنت كمزوّد SaaS، والعميل الذي يكتب سياسة الثقة)، فريدة لكل عميل. عندما تستدعي خدمتك AssumeRole يجب أن توفر ExternalId الصحيح لذلك العميل، وتفرضه سياسة الثقة بشرط StringEquals. المستدعي الخبيث الذي لا يعرف المعرّف الخارجي لا يمكنه إتمام الافتراض.

أفضل ممارسة للمعرّف الخارجي: أنشئ UUID عشوائيًا لكل عميل واحتفظ به على طرفك. استخدمه في كتلة Condition لسياسة الثقة. تعامل معه كسر — لا تكشفه في السجلات أو رسائل الخطأ. أعد توليده إذا أنهى عميل تعاملاته ثم عاد.

افتراض دور من سطر الأوامر

استخدم aws sts assume-role للحصول على بيانات اعتماد مؤقتة، ثم صدّرها كمتغيرات بيئة لاستدعاءات CLI اللاحقة.

# افتراض الدور والتقاط بيانات الاعتماد CREDS=$(aws sts assume-role \ --role-arn "arn:aws:iam::444455556666:role/ProdReadOnly" \ --role-session-name "developer-audit-$(date +%s)" \ --external-id "prod-deploy-external-id-abc123" \ --duration-seconds 3600 \ --query "Credentials" \ --output json) # تصدير إلى الـ shell export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r .AccessKeyId) export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r .SecretAccessKey) export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r .SessionToken) # التحقق — يجب أن يُظهر ARN الدور المفترض aws sts get-caller-identity # إلغاء التصدير عند الانتهاء unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN

في أنظمة CI/CD (GitHub Actions، Jenkins، GitLab CI) لا تفعل هذا يدويًا أبدًا. بدلًا من ذلك تُهيئ المشغّل لاستخدام aws-actions/configure-aws-credentials (GitHub Actions) أو دور نموذج EC2، ويتولى SDK تجديد الرمز تلقائيًا.

سياسات الجلسة — تضييق النطاق عند الافتراض

عند استدعاء AssumeRole يمكنك تمرير سياسة جلسة اختيارية: سياسة JSON مضمّنة تُضيّق الأذونات الفعّالة لهذه الجلسة. لا يمكنها منح أذونات تتجاوز ما يسمح به الدور — مجموعة الأذونات الفعّالة هي دائمًا تقاطع سياسات الدور وسياسة الجلسة. هذا قوي لتطبيق مبدأ أقل الامتيازات: دور متعدد الاستخدامات بأذونات قراءة واسعة يمكن تقييده على bucket S3 واحد لمهمة آلية محددة.

# افتراض دور لكن تضييق النطاق على bucket واحد لهذه الجلسة aws sts assume-role \ --role-arn "arn:aws:iam::444455556666:role/S3ReadAll" \ --role-session-name "etl-job-nightly" \ --policy '{ "Version":"2012-10-17", "Statement":[{ "Effect":"Allow", "Action":["s3:GetObject","s3:ListBucket"], "Resource":[ "arn:aws:s3:::my-prod-data-bucket", "arn:aws:s3:::my-prod-data-bucket/*" ] }] }' \ --duration-seconds 900
فشل إنتاجي شائع: حدود تسلسل الأدوار. عندما تفترض الدور A ثم تفترض من تلك الجلسة الدور B (تسلسل الأدوار)، تُحدَّد مدة الجلسة القصوى بـ ساعة واحدة بغض النظر عمّا يسمح به الدور. هذا يعطّل مهام CodeBuild أو تشغيلات Terraform الطويلة التي تحاول تسلسل الأدوار. الحل هو جعل المستدعي الجذري يفترض الدور النهائي مباشرة، متجاوزًا الحلقات الوسيطة.

أنماط الأدوار عبر الحسابات في الإنتاج

نمط المحور والأذرع (hub-and-spoke) هو المعيار: دور CI/CD مركزي في حساب الخدمات المشتركة يثق به DeployRole في كل حساب من حسابات أعباء العمل. يفترض خط الأنابيب دور الحساب المستهدف مباشرةً — دون تسلسل. للوصول القراءة فقط لأغراض التدقيق، يكون دور حساب الأمان المخصص موثوقًا من جميع حسابات أعباء العمل، مما يمنح فريق الأمان مكانًا واحدًا لبدء عمليات القراءة عبر الحسابات دون أي وصول دائم.

في AWS Organizations، تُضيف SCPs طبقة ثالثة: حتى لو سمحت كل من سياسة الثقة وسياسة الأذونات بإجراء ما، فإن SCP التي تحظره على مستوى OU ستمنعه. تحقق دائمًا من الوصول عبر الحسابات باستخدام aws iam simulate-principal-policy بعد تغييرات SCP.

لا تستخدم مفاتيح طويلة الأمد للعمل عبر الحسابات أبدًا. أرفق دور IAM بنموذج EC2 أو دالة Lambda أو مهمة ECS أو مشروع CodeBuild. يجلب SDK بيانات الاعتماد المؤقتة من خدمة بيانات تعريف النموذج تلقائيًا. مفاتيح الوصول طويلة الأمد التي تتسرب إلى مستودع git أو سطر سجل هي المصدر الأكبر الوحيد لحوادث أمان AWS.