{"id":"l-aws-2-3","courseId":"aws-cloud-foundations","lang":"ar","kind":"lesson","summary":"امنح الأشخاص الوصول عبر IAM Identity Center، وامنح الكود الوصول عبر الـ roles في IAM، كي يعمل Lantern دون أي مفاتيح وصول طويلة الأمد على الحواسيب أو الخوادم أو في Git.","html":"<p>انتهى القسم الأول بمستخدم مدير واحد لشخص واحد في حساب واحد. أما Lantern الآن فلديه ستة متطوّعين، وحساب للتطوير وآخر للإنتاج، ودالة Lambda، ومهمة ليلية على EC2. إذا احتاج كل واحد من هؤلاء إلى مستخدم IAM بمفاتيح وصول، فستنتهي بنحو اثني عشر سرًّا طويل الأمد مبعثرة على الحواسيب والخوادم. هذا الدرس يزيلها كلها إلا القليل.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">الأشخاص: IAM Identity Center</h2>\n<p><strong>AWS IAM Identity Center</strong> هو المكان الذي يسجّل فيه فريق عملك الدخول. يحصل كل شخص على هوية <strong>واحدة</strong>، إما في الدليل المدمج في Identity Center أو مُزامَنة من مزوّد هوية مثل Microsoft Entra ID أو Okta أو Google Workspace. يسجّل الشخص الدخول مرة واحدة، مع MFA، عبر رابط <strong>بوابة وصول AWS (AWS access portal)</strong>، فيرى كل حساب مسموح له بدخوله.</p>\n<p>ما يستطيع فعله في كل حساب يأتي من <strong>حزم الصلاحيات (permission sets)</strong>: حزمة مسمّاة من السياسات، مثل <code dir=\"ltr\">DeveloperAccess</code> أو <code dir=\"ltr\">ReadOnly</code>. عندما تُسند “المتطوّعة Rita، حزمة الصلاحيات <code dir=\"ltr\">DeveloperAccess</code>، الحساب <code dir=\"ltr\">lantern-dev</code>”، ينشئ Identity Center role مطابقًا في ذلك الحساب، وتتقمّصه جلسة Rita. لا أحد لديه مستخدم IAM؛ ولا أحد لديه مفتاح طويل الأمد.</p>\n<p>صُمِّم Identity Center ليعمل مع <strong>AWS Organizations</strong>، الذي يجمع حسابات Lantern تحت حساب إدارة واحد. انتبه إلى عقبة عملية واحدة: في خطة الحساب المجانية، يؤدّي الانضمام إلى مؤسسة (organisation) إلى ترقية الحساب إلى الخطة المدفوعة، لذا فهذه خطوة لوقت انتقال Lantern إلى الإنتاج.</p>\n<p>في الـ CLI، يكتب <code dir=\"ltr\">aws configure sso</code> الـ profile، ويفتح <code dir=\"ltr\">aws sso login</code> المتصفّح لتسجيل الدخول:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"ini\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">~/.aws/config</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">[sso-session lantern]</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">sso_start_url</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> = https://lantern.awsapps.com/start</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">sso_region</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> = eu-west-1</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">sso_registration_scopes</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> = sso:account:access</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">[profile lantern-dev]</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">sso_session</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> = lantern</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">sso_account_id</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> = 444455556666</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">sso_role_name</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> = DeveloperAccess</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">region</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> = eu-west-1</span></span></code></pre></div>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">aws</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> sso</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> login</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --sso-session</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> lantern</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">aws</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> sts</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> get-caller-identity</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --profile</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> lantern-dev</span></span></code></pre></div>\n<p>الـ <code dir=\"ltr\">Arn</code> الذي يعود الآن يُقرأ <code dir=\"ltr\">assumed-role/AWSReservedSSO_DeveloperAccess_…/rita</code>: جلسة role، لا مستخدم.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">أحمال العمل: roles لا مفاتيح</h2>\n<p>يحتاج الكود إلى بيانات اعتماد أيضًا، والجواب دائمًا <strong>role</strong> تتقمّصه المنصّة نيابة عنك:</p>\n<ul>\n<li><strong>Lambda</strong>: لكل دالة <strong>execution role</strong> (role التنفيذ).</li>\n<li><strong>EC2</strong>: يوصل <strong>الـ instance profile</strong> بيانات اعتماد الـ role عبر خدمة البيانات الوصفية للـ instance (instance metadata service).</li>\n<li><strong>Amazon ECS</strong>: <strong>task role</strong> لكل task definition.</li>\n<li><strong>الـ CI/CD خارج AWS</strong>، مثل GitHub Actions: مزوّد هوية OpenID Connect في IAM، فيستبدل الـ pipeline الـ token الخاص به بجلسة role.</li>\n</ul>\n<p>للـ role سياستان دائمًا. <strong>سياسة الثقة (trust policy)</strong> تحدّد من يحق له تقمّصه:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"json\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">trust-policy.json</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"Version\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"2012-10-17\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"Statement\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"Effect\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Allow\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"Principal\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"Service\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"lambda.amazonaws.com\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"Action\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"sts:AssumeRole\"</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  ]</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n<p>و<strong>سياسة الصلاحيات (permissions policy)</strong> تحدّد ما يحق للـ role فعله بعد تقمّصه، وتُكتب تمامًا مثل سياسات الدرس السابق.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 230\" role=\"img\" aria-labelledby=\"l-aws-2-3-t1\"><defs><marker id=\"arrow-l-aws-2-3-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-aws-2-3-t1\">تطلب خدمة Lambda من STS تقمّص الـ role المسمّى lantern-rsvp. يفحص STS سياسة الثقة ويعيد بيانات اعتماد مؤقتة. يستخدمها كود الدالة لاستدعاء DynamoDB، حيث يفحص IAM سياسة صلاحيات الـ role.</title>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"80\" width=\"150\" height=\"64\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"95\" y=\"108\" text-anchor=\"middle\">Lambda</text>\n  <text class=\"d-label-muted\" x=\"95\" y=\"128\" text-anchor=\"middle\">دالة rsvp</text>\n  <rect class=\"d-box-accent\" x=\"265\" y=\"20\" width=\"150\" height=\"64\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"340\" y=\"48\" text-anchor=\"middle\">AWS STS</text>\n  <text class=\"d-label-muted\" x=\"340\" y=\"68\" text-anchor=\"middle\">يفحص سياسة الثقة</text>\n  <rect class=\"d-box-success\" x=\"510\" y=\"140\" width=\"150\" height=\"64\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"585\" y=\"168\" text-anchor=\"middle\">DynamoDB</text>\n  <text class=\"d-label-muted\" x=\"585\" y=\"188\" text-anchor=\"middle\">يفحص الصلاحيات</text>\n  <path class=\"d-arrow\" d=\"M170 96 L262 56\" marker-end=\"url(#arrow-l-aws-2-3-1)\"/>\n  <text class=\"d-label\" x=\"160\" y=\"58\">1 AssumeRole</text>\n  <path class=\"d-arrow d-dashed\" d=\"M265 72 L174 112\" marker-end=\"url(#arrow-l-aws-2-3-1)\"/>\n  <text class=\"d-label\" x=\"232\" y=\"120\">2 بيانات اعتماد مؤقتة</text>\n  <path class=\"d-arrow\" d=\"M170 134 L506 170\" marker-end=\"url(#arrow-l-aws-2-3-1)\"/>\n  <text class=\"d-label\" x=\"300\" y=\"176\">3 PutItem موقَّع</text>\n</svg><figcaption>تتقمّص Lambda الـ execution role الخاص بها، ثم تستدعي DynamoDB ببيانات اعتماد مؤقتة</figcaption></figure>\n<p>عندئذٍ لا يحتوي الكود الخاص بك على <strong>أي بيانات اعتماد على الإطلاق</strong>. تستخدم حزم AWS SDK سلسلة بيانات اعتماد افتراضية (default credential chain) تعثر على بيانات اعتماد الـ role المؤقتة تلقائيًا:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">rsvp/index.mjs</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { DynamoDBClient } </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"@aws-sdk/client-dynamodb\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// No keys here: the SDK finds the execution role's temporary credentials.</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> client</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> DynamoDBClient</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">({});</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// …handler code that calls client.send(…)</span></span></code></pre></div>\n<h2 id=\"sec-3\" tabindex=\"-1\">الخطأ الذي ينتهي بفاتورة ضخمة</h2>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>مفاتيح وصول في الكود أو الإعدادات أو Git</span></p>\n<p>سطر مثل <code dir=\"ltr\">accessKeyId: &quot;AKIA…&quot;</code> في الكود المصدري، أو ملف <code dir=\"ltr\">.env</code> مرفوع في commit، أو مفتاح لُصق في متغيّر CI “مؤقتًا”، من أكثر الطرق التي تُخترق بها حسابات AWS شيوعًا. تمسح البوتات المستودعات العامة باستمرار، وقد يكون مفتاح مسرّب يشغّل instances باهظة خلال دقائق. قد ترفق AWS سياسة حجر (quarantine policy) بمفتاح تجده مكشوفًا، لكن ذلك يحدّ من الضرر بعد وقوعه. الإصلاح بنيوي: roles لأحمال العمل، وIdentity Center أو <code dir=\"ltr\">aws login</code> للأشخاص، وأداة لفحص الأسرار في المستودع.</p>\n</aside>\n<p>أحيانًا يكون مفتاح الوصول أمرًا لا مفرّ منه فعلًا، كأداة خارجية لا تقبل إلا المفاتيح. عندئذٍ: مستخدم IAM واحد لكل أداة، وسياسة بأقل الصلاحيات، وشرط <code dir=\"ltr\">aws:SourceIp</code> إذا كانت للأداة عناوين ثابتة، وتدوير للمفتاح وفق جدول زمني.</p>\n<p>التخلّص من مفتاح موجود تسلسل دقيق، لأن حذف مفتاح ما زال شيء ما يستخدمه يعطّل الإنتاج. تحقّق من آخر مرة استُخدم فيها:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">aws</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> iam</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> get-access-key-last-used</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --access-key-id</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> AKIAIOSFODNN7EXAMPLE</span></span></code></pre></div>\n<p>بمجرد أن يثبت أن لا شيء استخدمه منذ تشغيل البديل، <strong>عطّله</strong> أولًا (وهذا قابل للتراجع)، وانتظر، ولا <strong>تحذفه</strong> إلا حين لا يشكو شيء. أما المفتاح الذي تشكّ في تسرّبه فأمره مختلف: عطّله فورًا، ثم حقّق في الأمر بعد ذلك.</p>\n<aside class=\"callout callout-why\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><circle cx=\"12\" cy=\"12\" r=\"6\"/><circle cx=\"12\" cy=\"12\" r=\"2\"/></svg><span><span class=\"callout-kind\">لماذا يهمّ هذا</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>التكلفة والأمان حديث واحد</span></p>\n<p>المفتاح المسرّب يكلّف مالًا أولًا وسمعةً ثانيًا. كل مفتاح تستبدله بـ role هو سطر يُحذف من فاتورتك في أسوأ الاحتمالات.</p>\n</aside>\n<p>بهذا تكتمل الهوية. يضعها القسم الثالث موضع التطبيق وأنت تختار قطع الحوسبة والتخزين وقاعدة البيانات والشبكة لـ Lantern.</p>\n","toc":[{"id":"sec-1","text":"الأشخاص: IAM Identity Center","level":2},{"id":"sec-2","text":"أحمال العمل: roles لا مفاتيح","level":2},{"id":"sec-3","text":"الخطأ الذي ينتهي بفاتورة ضخمة","level":2}],"takeaways":["يمنح IAM Identity Center كل شخص تسجيل دخول واحدًا، مع MFA، إلى كل حساب يحتاجه، ويوزّع بيانات اعتماد قصيرة الأمد عبر حزم الصلاحيات (permission sets).","تحصل أحمال العمل على صلاحياتها من الـ roles، مثل الـ execution role في Lambda أو الـ instance profile في EC2، وتعثر حزم AWS SDK على بيانات الاعتماد المؤقتة هذه دون أي كود.","للـ role سياستان؛ سياسة الثقة تحدّد من يحق له تقمّصه، وسياسة الصلاحيات تحدّد ما يحق له فعله بعد ذلك.","مفاتيح الوصول طويلة الأمد في الكود أو ملفات الإعداد أو متغيّرات البيئة من أكثر الطرق شيوعًا لاختراق حسابات AWS.","عند التخلّص من مفتاح وصول قديم، تأكّد من أنه غير مستخدم عبر تاريخ آخر استخدام له، ثم عطّله، ولا تحذفه إلا بعد ذلك."],"further":[{"title":"What is IAM Identity Center?","url":"https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html"},{"title":"Configuring IAM Identity Center authentication with the AWS CLI","url":"https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html"},{"title":"Defining Lambda function permissions with an execution role","url":"https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html"},{"title":"Manage access keys for IAM users","url":"https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html"}],"quiz":[{"q":"<p>يجب أن تكتب دالة تأكيد الحضور في Lantern إلى DynamoDB. كيف يجب أن تحصل على بيانات الاعتماد؟</p>","options":[{"text":"خزّن مفتاح وصول لمستخدم IAM في متغيّرات البيئة الخاصة بالدالة.","why":"كل من يستطيع قراءة إعدادات الدالة يستطيع قراءة المفتاح، وهو لا تنتهي صلاحيته أبدًا. متغيّرات البيئة ليست مخزنًا للأسرار."},{"text":"امنح الدالة execution role بسياسة صلاحيات للجدول؛ وتلتقط الـ SDK بيانات اعتماده المؤقتة.","why":"صحيح. تتقمّص Lambda الـ role نيابة عنك وتسلّم كل بيئة تنفيذ بيانات اعتماد قصيرة الأمد، فلا يوجد ما يتسرّب أو يحتاج إلى تدوير."},{"text":"استخدم بيانات اعتماد مستخدم الجذر، لأن الدالة تحتاج إلى وصول موثوق.","why":"بيانات اعتماد الجذر غير مقيّدة ولا يجب أن توجد كمفاتيح وصول أصلًا، فضلًا عن وجودها داخل الكود."}],"answer":1},{"q":"<p>سياسة الصلاحيات الخاصة بـ role تسمح بـ <code dir=\"ltr\">dynamodb:PutItem</code> على جدول تأكيدات الحضور، لكن الـ instances في EC2 تفشل في تقمّص الـ role. أيّ سياسة هي الخاطئة على الأرجح؟</p>","options":[{"text":"سياسة الثقة، التي يجب أن تسمّي <code dir=\"ltr\">ec2.amazonaws.com</code> كـ principal مسموح له باستدعاء <code dir=\"ltr\">sts:AssumeRole</code>.","why":"صحيح. من يحق له تقمّص الـ role تقرّره سياسة الثقة وحدها. أما سياسة الصلاحيات فلا تهمّ إلا بعد تقمّص الـ role."},{"text":"سياسة الصلاحيات، التي يجب أن تسمح أيضًا بـ <code dir=\"ltr\">sts:AssumeRole</code>.","why":"لا يحتاج الـ role إلى صلاحية لتقمّص نفسه. هذه مهمة سياسة الثقة."},{"text":"سياسة جدول DynamoDB، التي يجب أن تسرد معرّف الـ instance في EC2.","why":"الـ instance ليست أبدًا الـ principal في استدعاءات DynamoDB؛ بل جلسة الـ role المتقمَّص. ثم إن التقمّص يفشل قبل أن تدخل DynamoDB في الصورة."}],"answer":0},{"q":"<p>لدى Lantern الآن حسابان منفصلان للتطوير والإنتاج وستة متطوّعين. ما أفضل طريقة لمنح المتطوّعين وصولًا إلى الـ console والـ CLI؟</p>","options":[{"text":"مستخدم IAM لكل متطوّع في كل حساب، لكلٍّ منهم كلمة مرور وMFA خاصان به.","why":"هذه اثنتا عشرة مجموعة من بيانات الاعتماد عليك إدارتها وإلغاؤها. الطريقة تعمل، لكنها لا تتوسّع جيدًا وتخلّف وراءها بيانات اعتماد طويلة الأمد."},{"text":"مستخدم IAM واحد مشترك لكل حساب بكلمة مرور قوية محفوظة في مدير كلمات مرور.","why":"المستخدمون المشتركون يقضون على المساءلة، ويجعلون إزالة شخص واحد مستحيلة دون تغيير وصول الجميع."},{"text":"مستخدمون في IAM Identity Center، مع حزم صلاحيات مسندة لكل حساب، يسجّلون الدخول عبر بوابة الوصول و<code dir=\"ltr\">aws sso login</code>.","why":"صحيح. لكل شخص هوية واحدة وMFA، والوصول قصير الأمد، وإزالة أي شخص تغيير واحد."}],"answer":2}],"exercise":{"kind":"order","items":["write-policy","create-role","attach-profile","remove-keys","verify-identity","check-last-used","deactivate","delete"],"title":"تخلّص من مفتاح وصول المهمة الليلية","prompt":"<p>تعمل مهمة التصدير الليلية في Lantern على instance في EC2 وتقرأ مفتاح وصول من <code dir=\"ltr\">/etc/lantern/.env</code>. المفتاح <strong>لم</strong> يتسرّب؛ وأنت تستبدله بـ role خلال أسبوع هادئ، دون تعطيل المهمة. رتّب الخطوات ترتيبًا آمنًا.</p>\n","hints":["يجب أن يوجد الـ role، بالصلاحيات الصحيحة، قبل أن يستطيع أي شيء استخدامه.","أثبت أن المهمة تعمل بالـ role قبل أن تلمس المفتاح القديم.","إزالة الوصول تتم على مرحلتين: واحدة قابلة للتراجع، وأخرى نهائية."],"explanation":"<p>تبني البديل أولًا: سياسة صلاحيات بأقل الصلاحيات، وrole تسمح سياسة الثقة الخاصة به بـ <code dir=\"ltr\">ec2.amazonaws.com</code>، وinstance profile يضع الـ role على الـ instance. ثم تزيل المفتاح من الـ instance كي تنتقل الـ SDK إلى بيانات اعتماد الـ role، وتثبت ذلك بتشغيل <code dir=\"ltr\">aws sts get-caller-identity</code> على الـ instance، ويجب أن يُظهر ARN من نوع <code dir=\"ltr\">assumed-role</code>. عندها فقط تنظر في المفتاح القديم: يؤكّد <code dir=\"ltr\">get-access-key-last-used</code> أن لا شيء استخدمه منذ التبديل. التعطيل قابل للتراجع إذا تعطّل شيء نسيته؛ أما الحذف فنهائي، لذا يأتي أخيرًا. لو كان المفتاح قد تسرّب، لعطّلته أولًا، فورًا، وتقبّلت التعطّل.</p>\n","checkLabels":{},"itemText":{"write-policy":"اكتب سياسة صلاحيات بأقل الصلاحيات لما تفعله مهمة التصدير بالضبط.","create-role":"أنشئ role بسياسة ثقة لـ <code dir=\"ltr\">ec2.amazonaws.com</code> وأرفق به سياسة الصلاحيات.","attach-profile":"أرفق الـ role بالـ instance في EC2 عبر instance profile.","remove-keys":"أزل مفتاح الوصول من <code dir=\"ltr\">/etc/lantern/.env</code> وأعد تشغيل المهمة.","verify-identity":"على الـ instance، شغّل <code dir=\"ltr\">aws sts get-caller-identity</code> وتأكّد من أن الـ ARN جلسة من نوع <code dir=\"ltr\">assumed-role</code>.","check-last-used":"شغّل <code dir=\"ltr\">aws iam get-access-key-last-used</code> بعد التشغيل الليلي التالي لتتأكّد من أن المفتاح القديم خامل.","deactivate":"عطّل مفتاح الوصول القديم وراقب التشغيلات القليلة التالية.","delete":"احذف مفتاح الوصول القديم."}},"words":631,"readMinutes":4}