---
title: 'GitHub Actions OIDC إلى Google Cloud: عمليات نشر بدون مفاتيح (2026)'
description: 'مصادقة GitHub Actions على Google Cloud باستخدام Workload Identity Federation: pool و provider و attribute conditions ونشر Cloud Run بدون مفاتيح (2026).'
url: https://nerdleveltech.com/ar/github-actions-gcp-workload-identity-federation-tutorial
language: ar
date: '2026-06-05'
category: cloud-devops
tags:
  - github actions
  - workload identity federation
  - google cloud
  - oidc
  - cloud run
  - keyless authentication
  - ci-cd
  - iam
  - gcp
  - security
markdown_url: https://nerdleveltech.com/ar/github-actions-gcp-workload-identity-federation-tutorial.md
attribution: 'Source: NerdLevelTech — https://nerdleveltech.com/ar/github-actions-gcp-workload-identity-federation-tutorial'
terms: https://nerdleveltech.com/llms.txt
---

# GitHub Actions OIDC إلى Google Cloud: عمليات نشر بدون مفاتيح (2026)

للمصادقة على إجراءات GitHub Actions مع Google Cloud بدون مفتاح حساب خدمة، قم بإنشاء Workload Identity Pool ومزود OIDC يثق في `https://token.actions.githubusercontent.com`، وقم بتقييد الدخول بشرط سمة (attribute condition)، وتبادل توكن OIDC الخاص بمسار العمل عبر `google-GitHub-actions/auth@v3`. يربط هذا البرنامج التعليمي العملية من البداية إلى النهاية في نشر Cloud Run.

## ملخص

ستقوم بتهيئة **Workload Identity Federation (WIF)** في Google Cloud بحيث يمكن لمسار عمل GitHub Actions النشر في **Cloud Run** بدون بيانات اعتماد مخزنة على الإطلاق — لا يوجد مفتاح JSON في أسرار المستودع الخاص بك، ولا شيء يتطلب التدوير، ولا شيء للتسريب. الإعداد بالكامل يتكون من عشرة أوامر `gcloud` بالإضافة إلى ملف مسار عمل واحد يستخدم `google-GitHub-actions/auth@v3`[^1] و `google-GitHub-actions/deploy-cloudrun@v3`[^2]، ويستغرق حوالي 20 دقيقة. ستقوم أيضًا بتأمين تكوين الثقة الخاص بك للمستقبل للتعامل مع **مطالبات الموضوع غير القابلة للتغيير (immutable subject claims)** من GitHub، والتي ستصبح الافتراضية للمستودعات الجديدة في **18 يونيو 2026**[^3].

## ما ستتعلمه

- كيف يعمل تبادل توكن OIDC الخاص بـ GitHub Actions مع Google Cloud (وكيف يختلف عن تدفق AWS)
- كيفية إنشاء Workload Identity Pool ومزود مع شروط سمات آمنة
- الفرق بين Workload Identity Federation المباشر وانتحال شخصية حساب الخدمة — وأيهما يحتاجه نشر Cloud Run
- أدوار IAM المحددة التي يحتاجها GitHub Actions للنشر في Cloud Run
- ملف YAML لمسار عمل النشر بدون مفاتيح، خطوة بخطوة
- كيفية التحقق من النشر وتشديد سياسة الثقة لتغيير المطالبة غير القابلة للتغيير في 18 يونيو 2026
- استكشاف أخطاء خمسة أوضاع فشل موثقة وإصلاحها

## كيف يعمل تبادل التوكن

عندما يتم تشغيل وظيفة مسار عمل بإذن `id-token: write`، يقوم GitHub بإصدار توكن OIDC قصير العمر تحدد مطالباته مسار العمل: `repository`، و `repository_owner`، و `ref`، ومطالبة `sub` (الموضوع) مركبة تكون افتراضيًا `repo:OWNER/REPO:ref:refs/heads/BRANCH`[^4]. تتحقق خدمة Security Token Service في Google Cloud من هذا التوكن مقابل جهة إصدار GitHub (`https://token.actions.githubusercontent.com`)، وتتحقق منه مقابل **شرط السمة** الخاص بالمجمع (pool) الخاص بك، وتبادله ببيانات اعتماد Google قصيرة العمر. توكن OIDC الخاص بـ GitHub نفسه قصير العمر — يشير ملف README الخاص بـ `auth` إلى أنه ينتهي في غضون 5 دقائق تقريبًا[^1].

إذا اتبعت البرنامج التعليمي الخاص بنا [AWS OIDC keyless deploy tutorial](https://nerdleveltech.com/GitHub-actions-oidc-aws-terraform-keyless-deploys-tutorial)، فسيكون الشكل مألوفًا — لكن GCP تختلف في طريقتين: تعيش الثقة في زوج موارد مخصص *pool + provider* بدلاً من سياسة ثقة دور IAM، وتقدم GCP وضعين متميزين (Direct WIF وانتحال شخصية حساب الخدمة) بينما تمتلك AWS افتراض الدور فقط.

```mermaid
sequenceDiagram
    participant GH as GitHub Actions job
    participant IdP as token.actions.githubusercontent.com
    participant STS as Google Cloud STS
    participant IAMC as IAM Credentials API
    participant CR as Cloud Run Admin API
    GH->>IdP: Request OIDC token (id-token: write)
    IdP-->>GH: Signed JWT (sub, repository, ref claims)
    GH->>STS: Exchange JWT (pool/provider validates + attribute condition)
    STS-->>GH: Federated token
    GH->>IAMC: Impersonate deployer SA (roles/iam.workloadIdentityUser)
    IAMC-->>GH: OAuth 2.0 access token
    GH->>CR: gcloud run deploy (roles/run.admin)
```

## Direct WIF مقابل انتحال شخصية حساب الخدمة

يدعم إجراء `auth` وضعين لـ WIF، ويصنف ملف README الرسمي Direct WIF كـ "(مفضل)"[^1]:

|                     | Direct WIF                                      | WIF عبر حساب خدمة                                                                          |
| ------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------ |
| مورد وسيط           | لا يوجد — يحصل المجمع (pool) على منح IAM مباشرة | يتم انتحال شخصية حساب خدمة                                                                 |
| كيفية اختياره       | حذف مدخل `service_account`                      | توفير مدخل `service_account`                                                               |
| عمر التوكن          | توكن موحد (Federated)، بحد أقصى 10 دقائق        | توكن وصول OAuth 2.0؛ توكنات الوصول التي يتم إنشاؤها تكون افتراضيًا ساعة واحدة (3600 ثانية) |
| التغطية             | لا تقبل جميع موارد GCP هويات `principalSet`     | يعمل مع أي API يمكن لحساب الخدمة استدعاؤه                                                  |
| إصدار توكن OAuth/ID | غير مدعوم                                       | مدعوم                                                                                      |

يعد Direct WIF هو الخيار الافتراضي الأنظف للموارد التي تدعم الهويات الموحدة (يوضح ملف README استخدام Secret Manager). في هذا البرنامج التعليمي، نستخدم **WIF عبر حساب خدمة**، لأن هذا هو نموذج التفويض الذي يوثقه إجراء `deploy-cloudrun`: حساب خدمة مع `roles/run.admin` بالإضافة إلى Service Account User على حساب خدمة Compute Engine الافتراضي[^2]. ستحصل على مصادقة بدون مفاتيح في كلتا الحالتين — حساب الخدمة هنا **ليس له مفتاح مصدر**؛ لا يمكن انتحال شخصيته إلا من خلال مسارات العمل التي تجتاز شرط السمة الخاص بك.

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

- مشروع Google Cloud مع تمكين الفواتير، وتثبيت [gcloud CLI](https://cloud.google.com/sdk) والمصادقة عليه (`gcloud auth login`) كمالك مشروع أو محرر
- مستودع GitHub (على GitHub.com — يستخدم GitHub Enterprise Server عنوان URL مختلف لجهة الإصدار، راجع استكشاف الأخطاء وإصلاحها)
- إصدارات الإجراءات المثبتة المستخدمة أدناه: `actions/checkout@v6.0.2` (2026-01-09)، `google-GitHub-actions/auth@v3.0.0` (2025-08-28)، `google-GitHub-actions/deploy-cloudrun@v3.0.1` (2025-09-03)[^5]

قم بتعيين متغيرات الصدفة (shell variables) التي تستخدمها كل خطوة:

```bash
export PROJECT_ID="your-project-id"
export GITHUB_ORG="your-GitHub-org-or-username"
export REPO="your-GitHub-org-or-username/your-repo"
```

## الخطوة 1 — تمكين واجهات برمجة التطبيقات المطلوبة

يحتاج Workload Identity Federation إلى واجهات برمجة تطبيقات IAM و Security Token Service و IAM Credentials؛ ويحتاج هدف النشر إلى Cloud Run[^6]:

```bash
gcloud services enable \
  iam.googleapis.com \
  sts.googleapis.com \
  iamcredentials.googleapis.com \
  run.googleapis.com \
  --project="${PROJECT_ID}"
```

المخرجات المتوقعة: `Operation "operations/..." finished successfully.`

## الخطوة 2 — إنشاء Workload Identity Pool

```bash
gcloud iam workload-identity-pools create "GitHub" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --display-name="GitHub Actions Pool"
```

التقط اسم المورد الكامل للمجمع — ستحتاج إليه لربط IAM:

```bash
export WORKLOAD_IDENTITY_POOL_ID=$(gcloud iam workload-identity-pools describe "GitHub" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --format="value(name)")
echo "${WORKLOAD_IDENTITY_POOL_ID}"
```

المخرجات المتوقعة (لاحظ **رقم** المشروع، وليس معرف المشروع):

```text
projects/123456789/locations/global/workloadIdentityPools/GitHub
```

## الخطوة 3 — إنشاء مزود OIDC مع شرط سمة

هذا هو مرساة الثقة. هناك قاعدتان من ملف README الرسمي لـ `auth` غير قابلة للتفاوض: **أضف دائمًا شرط سمة** يقيد الدخول إلى المجمع، و **قم بتعيين كل مطالبة تريد التأكيد عليها** — لا يمكنك الرجوع إلى `assertion.repository` في شرط أو ربط IAM ما لم يتم تعيينه أولاً[^1].

```bash
gcloud iam workload-identity-pools providers create-oidc "GitHub-provider" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --workload-identity-pool="GitHub" \
  --display-name="GitHub repo provider" \
  --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
  --attribute-condition="assertion.repository_owner == '${GITHUB_ORG}'" \
  --issuer-uri="https://token.actions.githubusercontent.com"
```

شرط السمة هو تعبير CEL يتم تقييمه مقابل التوكن الوارد. التقييد على `repository_owner` يمنع أي مستودع خارج مؤسستك من دخول المجمع — ثم تضيق روابط IAM الوصول بشكل أكبر لكل مستودع. هناك مشكلتان: الشروط **حساسة لحالة الأحرف** في جانب Google حتى لو كان GitHub يعامل الأسماء بغض النظر عن حالة الأحرف، ويتم رفض `google.subject` المعين الذي يزيد طوله عن **127 بايت** (أسماء المستودعات + الفروع الطويلة) بواسطة IAM[^7].

استخرج اسم مورد المزود لمسار العمل:

```bash
gcloud iam workload-identity-pools providers describe "GitHub-provider" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --workload-identity-pool="GitHub" \
  --format="value(name)"
```

المخرجات المتوقعة:

```text
projects/123456789/locations/global/workloadIdentityPools/GitHub/providers/GitHub-provider
```

هذا المسار الكامل — مع *رقم* المشروع — هو قيمة `workload_identity_provider` الخاصة بك. تمرير معرف المشروع (ID) بدلاً من الرقم هو وضع فشل يشير إليه دليل استكشاف الأخطاء وإصلاحها الرسمي صراحةً[^7].

## الخطوة 4 — إنشاء حساب خدمة النشر ومنح الأدوار

أنشئ حساب خدمة مخصص للنشر (لن يتم إنشاء مفتاح له أبداً):

```bash
gcloud iam service-accounts create "GitHub-deployer" \
  --project="${PROJECT_ID}" \
  --display-name="GitHub Actions Cloud Run deployer"
```

امنحه ما توثقه أداة `deploy-cloudrun`: دور Cloud Run Admin على المشروع، ودور Service Account User على حساب خدمة Compute Engine الافتراضي (الهوية التي تعمل بها إصدارات Cloud Run الجديدة في وقت التشغيل)[^2]:

```bash
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
  --member="serviceAccount:GitHub-deployer@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/run.admin"

export PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")

gcloud iam service-accounts add-iam-policy-binding \
  "${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
  --project="${PROJECT_ID}" \
  --member="serviceAccount:GitHub-deployer@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/iam.serviceAccountUser"
```

## الخطوة 5 — السماح للمستودع الخاص بك بانتحال شخصية الناشر

اربط الهوية الموحدة للمجمع (pool) لـ **مستودعك فقط** بحساب الخدمة باستخدام `roles/iam.workloadIdentityUser`[^1]:

```bash
gcloud iam service-accounts add-iam-policy-binding \
  "GitHub-deployer@${PROJECT_ID}.iam.gserviceaccount.com" \
  --project="${PROJECT_ID}" \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${REPO}"
```

العضو `principalSet://...attribute.repository/...` يطابق كل تشغيل لسير العمل (workflow) الذي تساوي مطالبة `repository` في رمزه المميز (token) القيمة `your-org/your-repo` — وهذا هو بالضبط السبب في أن الخطوة 3 كان عليها تعيين `attribute.repository=assertion.repository` أولاً.

الدفاع الآن يعتمد على طبقتين: شرط السمة (attribute condition) الذي يحدد أي الرموز المميزة تدخل المجمع (مؤسستك)، وهذا الربط في IAM الذي يحدد أي من تلك الهويات يمكنها انتحال شخصية الناشر (مستودع واحد).

## الخطوة 6 — سير عمل النشر بدون مفتاح

أنشئ `.GitHub/workflows/deploy.yml`. استبدل قيمة `workload_identity_provider` باسم مورد المزود من الخطوة 3:

```yaml
name: deploy-cloud-run

on:
  push:
    branches: ['main']

jobs:
  deploy:
    runs-on: 'ubuntu-latest'

    permissions:
      contents: 'read'
      id-token: 'write'

    steps:
      - uses: 'actions/checkout@v6.0.2'

      - id: 'auth'
        uses: 'google-GitHub-actions/auth@v3.0.0'
        with:
          project_id: 'your-project-id'
          workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/GitHub/providers/GitHub-provider'
          service_account: 'GitHub-deployer@your-project-id.iam.gserviceaccount.com'

      - id: 'deploy'
        uses: 'google-GitHub-actions/deploy-cloudrun@v3.0.1'
        with:
          service: 'hello-keyless'
          region: 'us-central1'
          image: 'us-Docker.pkg.dev/cloudrun/container/hello:latest'

      - name: 'Show service URL'
        run: 'echo "Deployed to ${{ steps.deploy.outputs.url }}"'
```

ثلاثة تفاصيل يؤدي إهمالها إلى فشل عمليات النشر:

1. **`id-token: write` إلزامي.** بدونه، لن يقوم GitHub أبداً بحقن رمز OIDC المميز وستفشل خطوة المصادقة. لاحظ أن إضافة كتلة `permissions` تزيل الإعدادات الافتراضية، لذا يجب إعادة ذكر `contents: read` لخطوة checkout[^1].
2. **يجب أن تأتي `actions/checkout` قبل `auth`.** تقوم الأداة بكتابة ملف بيانات اعتماد في `$GITHUB_WORKSPACE` للخطوات اللاحقة؛ ملف README صريح في أن حذف checkout أو وضعه بعد `auth` يترك الخطوات المستقبلية غير قادرة على المصادقة[^1].
3. **أضف `gha-creds-*.json` إلى `.gitignore` و `.dockerignore`.** يوجد ملف بيانات الاعتماد المصدر في مساحة العمل أثناء الوظيفة (يتم حذفه تلقائياً عند انتهاء الوظيفة)، لذا فإن أي شيء يحزم مساحة العمل — مثل بناء Docker أو أصل إصدار (release artifact) — يمكن أن يدرجه بالخطأ[^1].

صورة العرض `us-Docker.pkg.dev/cloudrun/container/hello:latest` هي حاوية عينة من Google، تمت الإشارة إليها تماماً كما يفعل ملف README الرسمي لـ `deploy-cloudrun`[^2]؛ في خط أنابيب حقيقي، ستستبدلها بوسم الصورة المثبت الخاص بك.

قم بعمل commit، و push إلى `main`، وشاهد التشغيل. ملاحظة تشغيلية واحدة: تغييرات المجمع والمزود و IAM تتسم بالاتساق النهائي (eventually consistent) ويمكن أن تستغرق ما يصل إلى 5 دقائق للانتشار — إذا فشل التشغيل الأول بخطأ في الأذونات، انتظر خمس دقائق وأعد التشغيل قبل تغيير أي شيء[^1].

## التحقق

خدمة Cloud Run الجديدة **خاصة بشكل افتراضي** — عمليات النشر الجديدة تكون خاصة تلقائياً، وتوصية منتج Cloud Run هي ألا تقوم أنظمة CI/CD بضبط أو تغيير إعداد unauthenticated-invocations[^2]. تحقق من ذلك من جهازك الخاص باستخدام رمز هوية مميز (يحتاج حساب gcloud الخاص بك إلى `run.routes.invoke`، والذي يتضمنه دور Cloud Run Admin)[^8]:

```bash
curl -s -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
  "$(gcloud run services describe hello-keyless \
      --project="${PROJECT_ID}" \
      --region='us-central1' \
      --format='value(status.url)')"
```

المتوقع: الصفحة الرئيسية للتطبيق العينة (HTTP 200). والدليل على نجاح التمرين بأكمله — تحقق من Settings ← Secrets في المستودع: **لا توجد بيانات اعتماد Google Cloud مخزنة في أي مكان**.

## التحصين لتاريخ 18 يونيو 2026: مطالبات الموضوع غير القابلة للتغيير

أعلنت GitHub عن مطالبات موضوع (subject claims) غير قابلة للتغيير لرموز OIDC المميزة لـ Actions في 23 أبريل 2026: بدلاً من `repo:octocat/my-repo:ref:refs/heads/main`، تكتسب مطالبة `sub` معرفات رقمية غير قابلة للتغيير، مثل `repo:octocat-123456/my-repo-456789:ref:refs/heads/main`. **المستودعات التي تم إنشاؤها بعد 18 يونيو 2026 تستخدم التنسيق الجديد تلقائياً**، وكذلك المستودعات الحالية بعد إعادة تسميتها أو نقلها؛ كل شيء آخر يحتفظ بالتنسيق القديم ما لم تختر التغيير عبر إعدادات OIDC للمستودع أو المؤسسة[^3].

هذا يغلق ثغرة هجوم حقيقية: إذا تم حذف اسم مؤسسة أو مستودع وإعادة تسجيله، يمكن للمالك الجديد سابقاً إصدار رموز مميزة بنفس الـ `sub` ووراثة ثقتك السحابية.

إعدادنا محمي إلى حد كبير لأن ربط IAM يطابق `attribute.repository` (الذي يظل `owner/repo`) وشرط السمة يطابق `repository_owner` — ولا يدمج أي منهما تنسيق `sub`. ولكن إذا قمت بتشديد الروابط القائمة على `google.subject` (على سبيل المثال، `principal://...subject/repo:org/repo:ref:refs/heads/main` لتثبيت الفرع)، فإن المستودع الذي تم إنشاؤه أو إعادة تسميته بعد 18 يونيو سيحمل المالك/المستودع الملحق بالمعرف في `sub` وسيتوقف عن مطابقة النمط القديم. بالنسبة للقيود على مستوى الفرع، يفضل التعيين والتحقق من `assertion.ref` بالإضافة إلى `assertion.repository` في شرط السمة بدلاً من مطابقة السلسلة النصية لـ `sub` بالكامل.

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

كل هذه حالات فشل موثقة من دليل استكشاف أخطاء `auth` الرسمي[^7]:

1. **`Failed to generate Google Cloud federated token`** — فشل الدخول إلى المجمع. رفض شرط السمة الخاص بك الرمز المميز: تحقق من هجاء المؤسسة/المستودع وتذكر أن الشروط حساسة لحالة الأحرف في جانب Google.
2. **`Failed to generate OAuth 2.0 Access Token`** — فشل انتحال الشخصية. ربط `roles/iam.workloadIdentityUser` مفقود أو أن `principalSet` الخاص به لا يطابق: تحقق من أن معرف المجمع في سلسلة العضو يستخدم رقم المشروع وأن المستودع هو `owner/name`.
3. **Permission denied مع مسار مجمع في `workload_identity_provider`** — لقد مررت اسم *المجمع* بدلاً من اسم *المزود* الكامل، أو استخدمت معرف المشروع حيث يكون رقم المشروع مطلوباً.
4. **`The size of mapped attribute exceeds the 127 bytes limit`** — الـ `google.subject` الخاص بك (المستودع + الفرع) طويل جداً. هذا حد من حدود Google Cloud IAM؛ قم بتقصير اسم الفرع أو المستودع.

أنت تستخدم GitHub Enterprise Server أو رابط توكن فريد لـ GHEC؛ جهة الإصدار ليست `https://token.actions.githubusercontent.com`. استخدم رابط التوكن الخاص بتثبيتك كـ `--issuer-uri`.

لاحظ أيضاً مشكلة محتملة في سياسة المؤسسة: إذا كانت مؤسستك في Google Cloud تقيد مزودي الهوية الخارجيين، فيجب إدراج `https://token.actions.githubusercontent.com` في القائمة المسموح بها في قيد `constraints/iam.workloadIdentityPoolProviders` قبل أن تنجح الخطوة 3[^7]. وإذا كانت خطوة لاحقة تستخدم `gsutil`، فلن تظهر لها بيانات الاعتماد هذه — استخدم `gcloud storage` بدلاً من ذلك[^1].

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

- قم بتضييق نطاق الثقة باستخدام [بيئات GitHub والمواضيع محددة النطاق بالبيئة، كما هو موضح في دليل OIDC لـ AWS الخاص بنا](https://nerdleveltech.com/GitHub-actions-oidc-aws-terraform-keyless-deploys-tutorial) — ينطبق نفس نمط `environment:production` على شروط سمات GCP عبر `assertion.sub`.
- هل تقوم بالنشر في عدة مشاريع (staging/prod)؟ نمط hub-and-spoke من [دليل تسلسل أدوار OIDC لـ AWS متعدد الحسابات](https://nerdleveltech.com/GitHub-actions-multi-account-aws-oidc-role-chaining-tutorial) يُطبق هنا عبر مجمع (pool) واحد لكل مشروع أو مجمع مشترك مع حسابات خدمة لكل مشروع.
- استبدل الصورة العينة ببنائك الخاص: أضف مستودع Artifact Registry، وامنح الناشر دور `roles/artifactregistry.writer`، وقم بالدفع (push) من نفس سير العمل بدون مفاتيح.

[^1]: google-GitHub-actions/auth README and inputs reference — <https://GitHub.com/google-GitHub-actions/auth>

[^2]: google-GitHub-actions/deploy-cloudrun README (usage, inputs, authorization) — <https://GitHub.com/google-GitHub-actions/deploy-cloudrun>

[^3]: GitHub Changelog (2026-04-23): Immutable subject claims for GitHub Actions OIDC tokens — <https://GitHub.blog/changelog/2026-04-23-immutable-subject-claims-for-GitHub-actions-oidc-tokens/>

[^4]: GitHub Docs: OpenID Connect reference — <https://docs.GitHub.com/actions/reference/openid-connect-reference>

[^5]: Release dates from the GitHub Releases API: auth v3.0.0 (2025-08-28), deploy-cloudrun v3.0.1 (2025-09-03), checkout v6.0.2 (2026-01-09).

[^6]: Google Cloud IAM docs: Configure Workload Identity Federation with deployment pipelines — <https://docs.cloud.google.com/iam/docs/workload-identity-federation-with-deployment-pipelines>

[^7]: google-GitHub-actions/auth troubleshooting guide — <https://GitHub.com/google-GitHub-actions/auth/blob/main/docs/TROUBLESHOOTING.md>

[^8]: Google Cloud Run docs: Authenticate developers — <https://docs.cloud.google.com/run/docs/authenticating/developers>
