Python / GCP - GitHub 操作 & Google OAuth 不提交 ID

Python / GCP - GitHub Action & Google OAuth without committing ID

对于使用 YouTube API 的项目,我使用的功能是从 JSON 文件中读取我的 OAuth 2.0 ID,自动创建/刷新凭据,然后生成一个服务来执行各种 API 请求。我已经 运行 本地脚本几天了,没有任何问题。但现在我想使用 GitHub 操作和特定触发器来自动化我的项目。

我的函数大致如下所示:

import ast
import googleapiclient.discovery
import googleapiclient.errors
import json
import os
import sys

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow

def get_authenticated_service():
    # OAUTH 2.0 ID path
    oauth_file = '../tokens/oauth.json'
    scopes = ["https://www.googleapis.com/auth/youtube.force-ssl"]
    cred = None

    if os.path.exists('../tokens/credentials.json'):
        # Retrieve credentials
        cred = Credentials.from_authorized_user_file('../tokens/credentials.json')

    if not cred or not cred.valid:  # Cover outdated credentials
        if cred and cred.expired and cred.refresh_token:
            cred.refresh(Request())

        else:
            # Create a Flow from 'oauth_file'
            flow = InstalledAppFlow.from_client_secrets_file(oauth_file, scopes)
            # Run authentification process
            cred = flow.run_local_server()

        with open('../tokens/credentials.json', 'w') as cred_file:
            # Save credentials as a JSON file
            json.dump(ast.literal_eval(cred.to_json()), cred_file, ensure_ascii=False, indent=4)

    try:
        service = googleapiclient.discovery.build('youtube', 'v3', credentials=cred)
        return service

    except Exception as error:
        sys.exit()

问题是我与 public 存储库共享我的代码,但我不想共享/提交我的 ID(在 token 文件夹中)。我刚刚开始了解 GitHub Action 的工作原理,我不知道如何将我当前的方法转换为可能在工作流程中完成工作的方法。这甚至可能吗?

您应该能够在 GitHub 操作中使用 Workflow Identity Federation。

您的代码应该使用服务帐户而不是安装的应用程序流程进行身份验证,并且在 运行 作为 GitHub 操作时需要使用服务帐户流程(因为没有办法一个人类用户干预 OAuth 审批流程)。

查看 Google 的博客 post Enable keyless auth from GitHub Actions

之后,我找到了一种使用工作流身份联合来使用 Google API Python 客户端的方法。我花了一段时间才弄清楚所有这些是如何工作的,但现在我可以提供一个答案。而且“令人惊讶”的是,它的设置非常简单。

After setting-up your Federation,您可以在所需的工作流程(YAML 文件)中添加这些身份验证行:

steps:
    -   id: checkout
        name: Checkout repository
        uses: actions/checkout@v3
    
    -   id: auth
        name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0
        with:
            token_format: 'access_token'
            access_token_scopes: 'https://www.googleapis.com/auth/youtube.force-ssl'
            workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
            service_account: 'my-service-account@my-project.iam.gserviceaccount.com'
        
# TODO: Install dependencies, program execution...

然后使用 google.auth 的默认方法通过 Python 客户端创建服务:

import google.auth
import googleapiclient.discovery

def create_service_workflow():
    scopes = ["https://www.googleapis.com/auth/youtube.force-ssl"]
    credentials, _ = google.auth.default(scopes=scopes)
    service = googleapiclient.discovery.build('youtube', 'v3', credentials=credentials)
    return service