---
title: 'GitHub Actions OIDC إلى AWS: Keyless'
description: نشر Terraform على AWS من GitHub Actions بدون أسرار طويلة الأمد — configure-aws-credentials v6، سياسة الثقة لدور IAM، وتقوية الـ sub-claim (2026).
url: https://nerdleveltech.com/ar/github-actions-oidc-aws-terraform-keyless-deploys-tutorial
language: ar
date: '2026-05-27'
category: cloud-devops
tags:
  - github actions
  - oidc
  - aws
  - terraform
  - iam
  - security
  - ci-cd
  - keyless deployment
markdown_url: https://nerdleveltech.com/ar/github-actions-oidc-aws-terraform-keyless-deploys-tutorial.md
attribution: 'Source: NerdLevelTech — https://nerdleveltech.com/ar/github-actions-oidc-aws-terraform-keyless-deploys-tutorial'
terms: https://nerdleveltech.com/llms.txt
---

# GitHub Actions OIDC إلى AWS: Keyless

## ملخص

يمكن لـ GitHub Actions إصدار رمز JSON Web Token (JWT) قصير العمر عند كل تشغيل لبيئة العمل وتبديله مباشرة مع AWS STS للحصول على بيانات اعتماد مؤقتة — دون الحاجة أبدًا إلى وضع `AWS_ACCESS_KEY_ID` في أسرار المستودع (repository secrets). يشرح هذا البرنامج التعليمي كيفية إعداد نشر Terraform "بدون مفاتيح" (keyless) من البداية إلى النهاية: مزود IAM OpenID Connect، وسياسة ثقة للدور محددة النطاق، وخطوة `aws-actions/configure-aws-credentials@v6`، مع إجراءات تقوية (hardening) تحصر عمليات النشر في فرع وبيئة عمل واحدة فقط. يستغرق الأمر حوالي 25 دقيقة.

**موجز الإجابة:** لنشر Terraform على AWS من GitHub Actions بدون أسرار طويلة الأمد، قم بتسجيل مزود IAM OIDC لـ `token.actions.githubusercontent.com`، وأنشئ دورًا (role) تربط سياسة الثقة الخاصة به مطالبة الـ `sub` بمستودعك وفرعك، وامنح بيئة العمل صلاحية `id-token: write`، واستخدم `aws-actions/configure-aws-credentials@v6` لتبديل رمز GitHub JWT ببيانات اعتماد STS قصيرة العمر.

## ما ستتعلمه

- مزود هوية IAM OpenID Connect يثق في مصدر رموز GitHub
- دور IAM بأقل الامتيازات (least-privilege) لا يمكن انتحاله إلا من خلال مستودعك على فرع `main` أو بيئة `production`
- بيئة عمل GitHub Actions تقوم بتشغيل `terraform plan` و `terraform apply` مقابل AWS بدون أي أسرار طويلة الأمد
- سياسة ثقة محصنة تصمد أمام إطلاق مطالبة الموضوع غير القابلة للتغيير (immutable subject claim) للمستودعات الجديدة في 18 يونيو 2026[^immutable]

## المتطلبات الأساسية

- حساب AWS تتوفر فيه صلاحيات `iam:CreateOpenIDConnectProvider`، و `iam:CreateRole`، و `iam:AttachRolePolicy` (مسؤول أو دور تهيئة بنطاق كافٍ)
- مستودع GitHub (أي خطة — OIDC يعمل على Free و Pro و Team و Enterprise)
- إصدار Terraform 1.15.2 أو أحدث (قفل الحالة الأصلي عبر S3 باستخدام `use_lockfile = true` يتطلب 1.11.0+)[^tf]
- واجهة سطر أوامر AWS (AWS CLI) v2.34+
- حاوية S3 لحالة Terraform عن بُعد (يوضح [البرنامج التعليمي لقفل حالة Terraform S3 الأصلية](https://nerdleveltech.com/terraform-s3-native-state-locking-tutorial) كيفية توفير واحدة مع تمكين القفل وبدون DynamoDB)

## الخطوة 1: إنشاء مزود AWS IAM OpenID Connect

هذه عملية تهيئة تتم مرة واحدة لكل حساب. يخبر مزود OIDC خدمة AWS بالوثوق في رموز JWT الموقعة من قِبل `token.actions.githubusercontent.com`. يمكنك إنشاؤه مرة واحدة باستخدام واجهة سطر الأوامر (CLI) ثم إدارة كل شيء آخر في Terraform.

```bash
aws iam create-open-id-connect-provider \
  --url https://token.actions.githubusercontent.com \
  --client-id-list sts.amazonaws.com
```

هذا هو الأمر بالكامل. هناك ثلاثة أشياء تستحق الملاحظة:

خيار `--thumbprint-list` اختياري. تنص مرجعيات AWS CLI صراحةً على أنه عند حذفه، يقوم IAM باسترداد بصمة CA الوسيطة العليا بنفسه.[^awscli] والأهم من ذلك، منذ يوليو 2023، تتحقق AWS من شهادة TLS لنقطة نهاية JWKS مقابل مكتبتها من مراجع التصديق الجذرية الموثوقة و **تتجاهل أي بصمة تمررها لمزود GitHub**.[^thumbprint] البرامج التعليمية التي لا تزال تثبت البصمة `6938fd4d98bab03faadb97b34396831e3780aea1` تكرر طقوسًا ما قبل عام 2023 لا تفعل شيئًا اليوم.

`sts.amazonaws.com` هو الجمهور (مطالبة `aud`) الذي سيحمله رمز JWT الصادر عن GitHub افتراضيًا. إذا كنت تستهدف قسم AWS China، فستستخدم `sts.amazonaws.com.cn` هنا وتمرر مدخل `audience` مطابقًا للأكشن.[^configure]

يمكنك تسجيل نفس عنوان URL لـ OIDC مرة واحدة فقط لكل حساب AWS، لذا إذا ظهر خطأ `EntityAlreadyExists`، فهذا يعني أن المزود موجود بالفعل — انتقل إلى الخطوة 2.

إذا كنت تفضل التصريح عن المزود في Terraform بجانب الدور، فإن المورد يتكون من سطرين:

```hcl
resource "aws_iam_openid_connect_provider" "GitHub" {
  url            = "https://token.actions.githubusercontent.com"
  client_id_list = ["sts.amazonaws.com"]
}
```

في إصدار AWS provider 6.x أصبح `thumbprint_list` اختياريًا. احذفه تمامًا — عندما لا يتم تمرير السمة، يقوم IAM تلقائيًا باسترداد بصمة CA الوسيطة العليا وقت الإنشاء، ثم تتجاهلها AWS في وقت التشغيل لمزود GitHub. لاحظ وجود خطأ برمجي مفتوح (#40509): بمجرد تعيين البصمات في الحالة (state)، فإن إزالتها من التكوين لا يمسحها من IAM، لذا لا تكتب `thumbprint_list = []` أيضًا (قد ترفض AWS API القائمة الفارغة الصريحة برسالة `Thumbprint list must contain at least one entry`).[^tfthumbprint] إذا ورثت مجموعة موارد (stack) تحتوي بالفعل على بصمات في الحالة، فاتركها كما هي — فهي لا تسبب أي ضرر.

## الخطوة 2: تحديد سياسة الثقة لدور IAM

هذا هو الحد الأمني. تحدد سياسة الثقة **من** يمكنه انتحال الدور؛ بدونها (أو مع شرط فضفاض)، يمكن لأي مستودع على GitHub إصدار JWT وانتحال دورك. سنقوم بربطه بمستودع واحد وفرع واحد.

أنشئ ملف `iam.tf`:

```hcl
data "aws_caller_identity" "current" {}

locals {
  github_org  = "your-org"      # قم بتغييري
  github_repo = "your-repo"     # قم بتغييري
  branch      = "main"
  account_id  = data.aws_caller_identity.current.account_id
}

data "aws_iam_policy_document" "github_trust" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRoleWithWebIdentity"]

    principals {
      type        = "Federated"
      identifiers = [
        "arn:aws:iam::${local.account_id}:oidc-provider/token.actions.githubusercontent.com"
      ]
    }

    condition {
      test     = "StringEquals"
      variable = "token.actions.githubusercontent.com:aud"
      values   = ["sts.amazonaws.com"]
    }

    condition {
      test     = "StringEquals"
      variable = "token.actions.githubusercontent.com:sub"
      values   = [
        "repo:${local.github_org}/${local.github_repo}:ref:refs/heads/${local.branch}"
      ]
    }
  }
}

resource "aws_iam_role" "gha_terraform" {
  name               = "gha-terraform-deploy"
  assume_role_policy = data.aws_iam_policy_document.github_trust.json
  description        = "ينتحله GitHub Actions عبر OIDC لنشر Terraform"
  max_session_duration = 3600
}
```

ثلاثة تفاصيل تكتشفها الفرق لاحقًا:

استخدام `StringEquals` في مطالبة `sub` يقوم بمطابقة تامة. إذا كنت تريد أن يتمكن أي فرع (أو أي وسم، أو أي طلب سحب) من النشر، فقم بالتبديل إلى `StringLike` واستخدم نمط حرف بدل (wildcard) مثل `repo:org/repo:ref:refs/heads/*`. لعمليات النشر في بيئة الإنتاج، ستحتاج دائمًا تقريبًا إلى `StringEquals` لفرع واحد.[^subclaim]

تسمية الدور حرفيًا "GitHubActions" تسببت في تقارير قديمة عن فشل بطرق غير متوقعة (المشكلة رقم 953 في مستودع الأكشن).[^naming] استخدم اسمًا وصفيًا مثل `gha-terraform-deploy`.

القيمة الافتراضية لـ `max_session_duration` هي 3600 ثانية (ساعة واحدة). إذا كان تنفيذ Terraform plan + apply يستغرق وقتًا أطول من ذلك حقًا، فقم بزيادتها حتى 43200 (اثنتي عشرة ساعة)، ولكن ستحتاج أيضًا إلى تمرير `role-duration-seconds` للأكشن لطلب جلسة أطول.[^configure]

## الخطوة 3: إرفاق صلاحيات أقل الامتيازات لحالة Terraform والموارد

يحتاج الدور إلى مجموعتين من الصلاحيات: الوصول إلى الواجهة الخلفية للحالة (state-backend)، وأي شيء يديره Terraform بالفعل. للوصول إلى الواجهة الخلفية فقط، مقابل حاوية حالة S3 تسمى `acme-tf-state` مع تمكين قفل S3 الأصلي:

```hcl
data "aws_iam_policy_document" "tf_state" {
  statement {
    sid     = "StateBucketList"
    effect  = "Allow"
    actions = ["s3:ListBucket"]
    resources = ["arn:aws:s3:::acme-tf-state"]
  }

  statement {
    sid     = "StateObjectRW"
    effect  = "Allow"
    actions = ["s3:GetObject", "s3:PutObject"]
    resources = ["arn:aws:s3:::acme-tf-state/prod/terraform.tfstate"]
  }

  statement {
    sid     = "StateLockfileRW"
    effect  = "Allow"
    actions = ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"]
    resources = ["arn:aws:s3:::acme-tf-state/prod/terraform.tfstate.tflock"]
  }
}

resource "aws_iam_policy" "tf_state" {
  name   = "gha-terraform-deploy-state"
  policy = data.aws_iam_policy_document.tf_state.json
}

resource "aws_iam_role_policy_attachment" "tf_state" {
  role       = aws_iam_role.gha_terraform.name
  policy_arn = aws_iam_policy.tf_state.arn
}
```

ملف الحالة نفسه لا يحتاج إلى `s3:DeleteObject` — يقوم Terraform بالكتابة فوقه في مكانه. يحتاج ملف القفل إلى `DeleteObject` لأن Terraform يحذف كائن `.tflock` لتحرير القفل في نهاية عملية apply.[^s3lock] ثم قم بإرفاق أي سياسات مدارة أو مضمنة تحتاجها مجموعتك لإنشاء الموارد (مثل `AmazonEC2FullAccess`، أو سياسة مخصصة لخدماتك المحددة، إلخ).

## الخطوة 4: ربط بيئة العمل مع configure-aws-credentials v6 و id-token write

الآن سير العمل (workflow). الوسم العائم الحالي `aws-actions/configure-aws-credentials@v6` يشير إلى الإصدار v6.1.1 اعتباراً من 5 مايو 2026؛ قم بتثبيته على الإصدار غير القابل للتغيير `@v6.1.1` إذا كنت تريد قفل سلسلة التوريد بالكامل.[^v6release] أنشئ الملف `.GitHub/workflows/terraform.yml`:

```yaml
name: terraform-deploy

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./infra
    steps:
      - uses: actions/checkout@v6.0.2

      - name: Configure AWS credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v6.1.1
        with:
          role-to-assume: arn:aws:iam::123456789012:role/gha-terraform-deploy
          role-session-name: gha-${{ GitHub.run_id }}
          aws-region: us-east-1

      - name: Verify identity
        run: aws sts get-caller-identity

      - uses: hashicorp/setup-terraform@v4.0.1
        with:
          terraform_version: 1.15.2

      - run: terraform init
      - run: terraform plan -out=tfplan
      - run: terraform apply -auto-approve tfplan
```

هناك إذنان يقومان بعمل محدد: `id-token: write` يسمح للمشغل (runner) بطلب توكن OIDC من موفر الهوية الخاص بـ GitHub (مطلوب لـ OIDC، بدون استثناءات)، و `contents: read` يسمح لـ `actions/checkout` بجلب المستودع عبر التوكن المقدم من GitHub. بمجرد التصريح بكتلة `permissions:`، فإن جميع الأذونات غير المدرجة تصبح "لا شيء" افتراضياً، لذا فإن حذف `contents: read` هو سبب شائع لفشل عمليات الـ checkout الغامضة في المستودعات الخاصة والداخلية.[^perms] إذا أضفت لاحقاً كتلة `permissions:` على مستوى الوظيفة (job-level)، تذكر أن أذونات مستوى الوظيفة تحل محل أذونات مستوى سير العمل بالكامل — ولا يتم دمجهما.

`role-session-name: gha-${{ GitHub.run_id }}` يجعل كل جلسة يتم انتحالها قابلة للتتبع وصولاً إلى تشغيل سير العمل المحدد في CloudTrail. القيمة الافتراضية للإجراء هي مجرد `"GitHubActions"`، وهي صحيحة ولكنها غير مفيدة عندما تلاحق إدخالاً في سجل التدقيق.[^configure]

## الخطوة 5: تقوية مطالبة sub — التثبيت ببيئة، وليس بفرع

سياسة الثقة المحددة بفرع جيدة. لكن المحددة ببيئة (environment) أفضل — وهي تسمح لك بطلب موافقة يدوية قبل أن يتم انتحال الدور. يلزم إجراء تغييرين منسقين.

أولاً، في إعدادات مستودع GitHub، أنشئ بيئة `production` مع مراجعين مطلوبين، ثم أضف مفتاح `environment:` إلى وظيفة النشر في `terraform.yml`:

```yaml
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    # ...rest unchanged
```

ثانياً، قم بتحديث شرط سياسة الثقة لمطابقة `environment:production` بدلاً من `ref:refs/heads/main`. عندما تشير وظيفة إلى بيئة، يقوم GitHub بتجاوز مطالبة الموضوع (subject claim) إلى `repo:org/repo:environment:<name>` بغض النظر عما إذا كان المحفز هو دفع (push) أو `workflow_dispatch`، لذا تقوم بتبديل القيمة المطابقة التي تتوقعها سياسة الثقة:

```hcl
condition {
  test     = "StringEquals"
  variable = "token.actions.githubusercontent.com:sub"
  values   = [
    "repo:${local.github_org}/${local.github_repo}:environment:production"
  ]
}
```

التأثير المشترك: تتوقف الوظيفة مؤقتاً بحالة "Waiting" حتى يوافق المراجع المطلوب عليها، ولا يمكن انتحال الدور إلا من خلال سير العمل الذي يتم تشغيله داخل تلك البيئة المعتمدة — لا إنسان، لا توكن، لا وصول إلى AWS — حتى لو قام شخص ما بالدفع مباشرة إلى `main`.[^envscope]

إذا كنت بحاجة إلى مشاركة دور لكل من عمليات النشر عند الدفع إلى main وإصدار الوسوم (tags)، فانتقل إلى `StringLike` وادرج كلا النمطين:

```hcl
condition {
  test     = "StringLike"
  variable = "token.actions.githubusercontent.com:sub"
  values   = [
    "repo:${local.github_org}/${local.github_repo}:ref:refs/heads/main",
    "repo:${local.github_org}/${local.github_repo}:ref:refs/tags/v*"
  ]
}
```

ما لا يجب عليك فعله أبداً هو ترك سياسة الثقة بشرط `aud` فقط، أو تحديد نطاق `sub` إلى `repo:${org}/*:*`. أي منهما يعني أن أي فرع في أي من مستودعاتك — بما في ذلك فرع ميزة قام مقاول بدفعه بالأمس — يمكنه انتحال الدور.

## الخطوة 6: الاستعداد لمطالبات الموضوع غير القابلة للتغيير (بدءاً من 18 يونيو 2026)

هذه هي المشكلة الخاصة بعام 2026 التي لا تغطيها معظم البرامج التعليمية الحالية. في 23 أبريل 2026، أعلن GitHub أن مطالبات موضوع OIDC ستلحق معرفات المالك والمستودع غير القابلة للتغيير للدفاع ضد هجمات إعادة استخدام الأسماء. المستودعات التي تم إنشاؤها **بعد 18 يونيو 2026** ستصدر تلقائياً توكنات بمواضيع مثل:[^immutable]

```text
repo:octocat-12345/my-repo-67890:ref:refs/heads/main
```

تستمر المستودعات الحالية في إصدار تنسيق الاسم القابل للتغيير فقط ما لم يوافق المالك على التغيير مبكراً. هناك استنتاجان:

إذا كانت سياسة الثقة الخاصة بك تستخدم `StringEquals` على سلسلة الموضوع الكاملة، فيجب أن تتضمن سياسة الثقة الخاصة بك لمستودع جديد تم إنشاؤه بعد 18 يونيو معرف المالك ومعرف المستودع. يمكنك اكتشافهما باستخدام `gh API repos/<owner>/<repo> --jq '{id, owner_id: .owner.id}'` (يرفض واجهة سطر أوامر GitHub وجود شرطة مائلة بادئة في مسار نقطة النهاية). بالنسبة للمستودعات الحالية التي لم تشترك بعد، لا يزال التنسيق القديم يعمل.

إذا لم تتمكن من التنبؤ بالمعرفات مسبقاً، فإن النمط المتوافق مع المستقبل هو `StringLike` مع مصطلحي glob — أحدهما يطابق التنسيق القديم، والآخر يطابق التنسيق غير القابل للتغيير:

```hcl
values = [
  "repo:${local.github_org}/${local.github_repo}:ref:refs/heads/main",
  "repo:${local.github_org}-*/${local.github_repo}-*:ref:refs/heads/main"
]
```

إذا اعتمدت السياسة المحددة بالبيئة من الخطوة 5، فاستبدل `:ref:refs/heads/main` بـ `:environment:production` في كلا مصطلحي glob. هذا هو أنظف مسار للهجرة حتى تشترك في المستودع وتلتقط المعرفات.

## التحقق

قم بدفع التزام (commit) لا يقوم بأي عملية إلى `main` وراقب تشغيل سير العمل. يجب أن تطبع خطوة "Verify identity" شيئاً مثل:

```json
{
    "UserId": "AROAEXAMPLE:gha-1234567890",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/gha-terraform-deploy/gha-1234567890"
}
```

في CloudTrail، ابحث عن حدث `AssumeRoleWithWebIdentity` المطابق. سيكون `requestParameters.roleSessionName` هو `gha-${run_id}` وسيكون `responseElements.subjectFromWebIdentityToken` هو القيمة الدقيقة التي حملها توكن JWT الخاص بـ GitHub في مطالبة `sub` الخاصة به — `repo:<org>/<repo>:ref:refs/heads/main` إذا توقفت عند الخطوة 4، أو `repo:<org>/<repo>:environment:production` إذا قمت بالتقوية إلى البيئة في الخطوة 5. هذا الحقل هو مرساة التدقيق الخاصة بك.

## الأخطاء الشائعة

**`Error: Could not load credentials from any providers`** — غالباً ما يكون بسبب فقدان `permissions: id-token: write` سواء على مستوى سير العمل أو مستوى الوظيفة. إضافته على مستوى الوظيفة هي التي تسود.[^perms]

**`Not authorized to perform sts:AssumeRoleWithWebIdentity`** — شرط `sub` في سياسة الثقة لا يطابق ما يرسله سير العمل فعلياً. ترسل عمليات تشغيل PR القيمة `repo:org/repo:pull_request`، وليس `ref:refs/heads/...`. ترسل عمليات دفع الوسوم (tags) القيمة `ref:refs/tags/<tag>`. أضف `actions-oidc-debugger` لطباعة المطالبة الفعلية، ثم قم بتحديث السياسة.[^configure]

**`InvalidIdentityToken: Provider not found`** — موفر IAM OIDC غير موجود في الحساب، أو قمت بتسجيله بعنوان URL مختلف. يجب أن يكون عنوان URL هو `https://token.actions.githubusercontent.com` تماماً بدون شرطة مائلة في النهاية وبدون مسار.

**`InvalidIdentityToken: Couldn't retrieve verification key`** — عادةً ما يتم تعيين `audience:` مخصص في الإجراء ولكن لم يتم إضافته إلى `client_id_list` الخاص بموفر IAM. يجب أن تطابق مطالبة `aud` في JWT معرف عميل مسجلاً لدى الموفر.

**ينجح الـ Plan، ويتوقف الـ apply عند الحصول على القفل (lock)** — لقد انتقلت من قفل DynamoDB ونسيت حذف وسيط `dynamodb_table` القديم من تكوين الواجهة الخلفية (backend)، أو يفتقر الدور إلى إذن `s3:DeleteObject` على مفتاح `.tflock`. راجع [برنامج تعليمي لقفل حالة Terraform S3](https://nerdleveltech.com/terraform-s3-native-state-locking-tutorial) لمعرفة مسار الهجرة للقفل المزدوج.

## الخطوات التالية

قم بتطبيق نفس نمط سياسة الثقة على أدوار إضافية لبيئات staging مقابل production، مع تحديد نطاقها لبيئاتها الخاصة. أضف `inline-session-policy` في الإجراء لتشديد ما يمكن للدور المنتحل القيام به في وقت التشغيل — وهو أمر مفيد عندما يخدم دور واحد عدة سير عمل. وقم بإلغاء أي مفاتيح `AWS_ACCESS_KEY_ID` طويلة الأمد لا تزال موجودة في أسرار المستودع: فهي الآن خطيرة بشكل نشط، لأن الشيء الوحيد الذي يمنع تسريب البيانات هو طبقة لم تعد بحاجة إليها.

[^immutable]: سجل تغييرات GitHub، "مطالبات الموضوع غير القابلة للتغيير لرموز OIDC الخاصة بـ GitHub Actions"، 23 أبريل 2026 — [GitHub.blog](https://GitHub.blog/changelog/2026-04-23-immutable-subject-claims-for-GitHub-actions-oidc-tokens/)

[^tf]: إصدارات HashiCorp Terraform — [releases.hashicorp.com/terraform/](https://releases.hashicorp.com/terraform/)

[^awscli]: مرجع أوامر AWS CLI، `iam create-open-id-connect-provider` — [docs.aws.amazon.com](https://docs.aws.amazon.com/cli/latest/reference/iam/create-open-id-connect-provider.html)

[^thumbprint]: سجل تغييرات GitHub، "تكامل OIDC مع AWS لم يعد يتطلب تثبيت شهادات TLS الوسيطة"، 13 يوليو 2023 — [GitHub.blog](https://GitHub.blog/changelog/2023-07-13-GitHub-actions-oidc-integration-with-aws-no-longer-requires-pinning-of-intermediate-tls-certificates/)

[^configure]: ملف README الخاص بـ `aws-actions/configure-aws-credentials` (الإصدار v6.1.1، 5 مايو 2026) — [GitHub.com](https://GitHub.com/aws-actions/configure-aws-credentials)

[^tfthumbprint]: مشكلة hashicorp/terraform-provider-aws رقم 40509: "`aws_iam_openid_connect_provider` لا يمكنه مسح `thumbprint_list` بمجرد تعيينه" — [GitHub.com](https://GitHub.com/hashicorp/terraform-provider-aws/issues/40509)

[^subclaim]: وثائق GitHub، "تكوين OpenID Connect في Amazon Web Services" — [docs.GitHub.com](https://docs.GitHub.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)

[^naming]: مشكلة aws-actions/configure-aws-credentials رقم 953، "إذا كان اسم الدور المفترض هو `GitHubActions` فسيفشل الإجراء بخطأ غير محدد"؛ يربطه ملف README تحت عنوان "تم الإبلاغ عن أن تسمية دورك 'GitHubActions' لا تعمل" — [GitHub.com](https://GitHub.com/aws-actions/configure-aws-credentials/issues/953)

[^s3lock]: HashiCorp، "نوع الواجهة الخلفية: s3" (مرجع use\_lockfile) — [developer.hashicorp.com](https://developer.hashicorp.com/terraform/language/backend/s3)

[^v6release]: إصدار aws-actions/configure-aws-credentials v6.1.1، نُشر في 05-05-2026 — [GitHub.com](https://GitHub.com/aws-actions/configure-aws-credentials/releases/tag/v6.1.1)

[^perms]: وثائق GitHub، "OpenID Connect" — [docs.GitHub.com](https://docs.GitHub.com/en/actions/concepts/security/openid-connect)

[^envscope]: مدونة AWS الأمنية، "استخدام أدوار IAM لربط GitHub Actions بالإجراءات في AWS" — [aws.amazon.com](https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-GitHub-actions-to-actions-in-aws/)
