Невозможно получить доступ к ведру облачного хранилища Google из рабочего процесса GitHub Actions

У меня есть тестовый пример Django test_retrieve_bucket для проверки доступа к хранилищу GCP bucket.

from django.test import SimpleTestCase, TestCase
from google.cloud import storage

class DemoTest(TestCase):
def setUp(self):
    self.expense = Expense.objects.create(
        invoice_number = "ABC",
        account_number = "123",
        customer_name = "XYZ",
        invoice_amount = 12.50,
        invoice_date = datetime.now()
    )
def test1(self):
    return self.expense.invoice_number == "ABC"
def test2(self):
    return self.expense.account_number == "123"
def test3(self):
    return self.expense.customer_name == "XYZ"

def test_retrieve_bucket(self):
    bucket = "test_bucket_8866"
    client = storage.Client()
    bucket = client.bucket(bucket)
    return self.assertTrue(bucket.exists())

Однако тест не проходит, и вот какую ошибку я получаю:

google.api_core.exceptions.Forbidden: 403 GET https://storage.googleapis.com/storage/v1/b/test_bucket_8866?fields=name&prettyPrint=false: test-service-account@tbi-finance.iam.gserviceaccount.com не имеет доступа storage.buckets.get к ведру Google Cloud Storage. Разрешение 'storage.buckets.get' запрещено на ресурсе (или он может не существовать).

Я успешно аутентифицировал учетную запись службы с помощью Workload Identity Federation на предыдущем шаге: enter image description here

Учетная запись службы, которую я использовал, также имеет разрешение Storage Object Admin, что должно дать мне доступ к ведру: enter image description here

Вот мой файл рабочего процесса:

name: Django CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      max-parallel: 4
      matrix:
        python-version: [3.12.4]

    steps:
    - uses: actions/checkout@v4
    - name: auth
      uses: google-github-actions/auth@v2.0.0
      with:
        workload_identity_provider: 'projects/334572487877/locations/global/workloadIdentityPools/learn-github-actions-pool/providers/github-cdci'
        service_account: 'test-service-account@tbi-finance.iam.gserviceaccount.com'
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v3
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install Dependencies
      run: |
        pip install pipenv && pipenv install --system
    - name: Run Tests
      run: |
        python manage.py test
permissions:
  contents: 'read'
  id-token: 'write'

Когда я запустил тесты Django локально с указанной выше учетной записью сервиса, все тесты прошли. Может быть, я еще что-то упускаю?

Редактирование: Это была команда, которую я использовал для добавления роли WorkloadIdentityUser в Workload Identity Pool:

gcloud iam service-accounts add-iam-policy-binding "test-service-account@tbi-finance.iam.gserviceaccount.com" \
        --project="tbi-finance" \
        --role="roles/iam.workloadIdentityUser" \
        --member="principalSet://iam.googleapis.com/projects/334572487877/locations/global/workloadIdentityPools/learn-github-actions-pool/attribute.repository/duybtr/django_cdci"

Я смог заставить работать ваше решение, но....Oh boy!

В интересах простоты я собираюсь перечислить различные ресурсы, которые я создал, и надеюсь, что вы сможете найти разницу, которая поможет вам в работе.

После этого комментария я призываю вас добавить:

  1. отладчик GitHub OIDC после checkout и до auth
  2. token_format: access_token (если еще нет)
steps:
- name: checkout
  uses: actions/checkout@v4
- name: oidc-debugger
  uses: github/actions-oidc-debugger@main
  with:
    audience: https://iam.googleapis.com/{PROVIDER}
- name: auth
  uses: google-github-actions/auth@v2
  with:
    workload_identity_provider: {PROVIDER}
    service_account: {EMAIL}
    create_credentials_file: true
    token_format: access_token

Опасайтесь красных колец. Я получил другую ошибку, чем вы, но это результат неправильной конфигурации, а не потому, что IAM проекта Google был неверным:

Ошибка: google-github-actions/auth failed with: failed to generate Google Cloud OAuth 2.0 Access Token for ${EMAIL}:

{
  "error": {
    "code": 403,
    "message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "IAM_PERMISSION_DENIED",
        "domain": "iam.googleapis.com",
        "metadata": {
          "permission": "iam.serviceAccounts.getAccessToken"
        }
      }
    ]
  }
}
Пул
gcloud iam workload-identity-pools describe ${POOL} \
  --project="${PROJECT}" \
  --location="global"
displayName: GitHub Actions Pool
name: projects/{NUMBER}/locations/global/workloadIdentityPools/{POOL}
state: ACTIVE
Provider
gcloud iam workload-identity-pools providers describe ${PROVIDER} \
--project=${PROJECT} \
--location="global" \
--workload-identity-pool=${POOL}
attributeCondition: assertion.repository_owner=="{OWNER}" && assertion.repository=="{OWNER}/{REPO}"
attributeMapping:
  attribute.actor: assertion.actor
  attribute.repository: assertion.repository
  attribute.repository_owner: assertion.repository_owner
  google.subject: assertion.sub
displayName: {PROVIDER}
name: projects/{NUMBER}/locations/global/workloadIdentityPools/{POOL}/providers/{PROVIDER}
oidc:
  issuerUri: https://token.actions.githubusercontent.com
state: ACTIVE
Проект IAM
gcloud projects get-iam-policy ${PROJECT}
bindings:
- members:
  - serviceAccount:{EMAIL}
  role: roles/iam.serviceAccountTokenCreator
- members:
  - user:{ME}
  role: roles/owner
- members:
  - serviceAccount:{EMAIL}
  role: roles/storage.admin
etag: [REDACTED]
version: 1

ПРИМЕЧАНИЕ Согласно моему комментарию, в политике проекта нет roles/iam.workloadIdentityUser; эта роль присутствует в политике учетной записи службы

.
Учетная запись службы IAM
gcloud iam service-accounts get-iam-policy ${EMAIL}
bindings:
- members:
  - principalSet://iam.googleapis.com/projects/{NUMBER}/locations/global/workloadIdentityPools/{POOL}/attribute.repository/{OWNER}/{REPO}
  role: roles/iam.workloadIdentityUser
etag: [REDACTED]
version: 1
Переменные
Name Value
ACCOUNT Service Account
EMAIL Service Account email address: ${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com
ME My Google account
NUMBER Google Cloud Project number
OWNER GitHub User Account or ${ORG}
POOL Workload Identity Pool
PROJECT Google Cloud Project ID
PROVIDER Workload Identity Provider
REPO GitHub repo name
Вернуться на верх