📚

Cloud WorkflowsからCloud Function・Dataformを呼び出す際の認証エラー解決記録

に公開

はじめに

Google Cloud WorkflowsからCloud FunctionやDataform APIを呼び出す際に遭遇した認証エラーと、その解決方法を記録します。

特に「OAuth2とOIDCの使い分け」が重要なポイントでした。

エラー1: Cloud Function呼び出し時の認証エラー

発生したエラー

WorkflowsからCloud Functionを呼び出すステップで、以下の認証エラーが発生しました。

L0 Load Function failed: {"message":"ValueError: invalid domain for OAuth2","tags":["ValueError"]}

原因の分析

workflow.yamlでCloud Function (.run.appドメイン) を呼び出す際に、認証タイプとしてtype: OAuth2を指定していたことが原因でした。

# 問題のあった設定
call: http.post
args:
    url: "https://your-function-xxxxx.run.app"
    auth:
        type: OAuth2  # ← これが原因

なぜOAuth2ではダメだったのか

  • OAuth2: 汎用的な**認可(Authorization)**の仕組み

    • 「このユーザーには〇〇する権限がある」を証明
    • Google提供の管理API(*.googleapis.com)を呼び出す際に使用
  • OIDC: **認証(Authentication)**の仕組み

    • 「私は〇〇である」という身元を証明
    • Cloud Run/Functionsなど、自作サービスを呼び出す際に使用

Workflowsの認証ライブラリが.run.appドメインに対してOAuth2を適用しようとした結果、invalid domainエラーが発生していました。

解決策

認証タイプをOAuth2からOIDCに変更することで解決しました。

# 修正後の設定
call: http.post
args:
    url: "https://your-function-xxxxx.run.app"
    auth:
        type: OIDC  # ← OIDCに変更

OIDCの仕組み

OIDCを使うと、Workflowsは以下のような動作をします:

  1. Workflowsが自身のサービスアカウントでIDトークンを生成
  2. そのトークンをHTTPリクエストのAuthorizationヘッダーに付与
  3. Cloud Functionがトークンを検証し、呼び出し元を認証

この方法により、Cloud Functionは「確かにこのWorkflowsから呼ばれた」ことを確認できます。


エラー2: Dataform API呼び出し時のサービスアカウントエラー

最初のOIDC修正後、今度はDataformのサブワークフロー呼び出しで新たなエラーが発生しました。

発生したエラー

{
  "error": {
    "code": 400,
    "message": "Service account must be set when strict act as checks are enabled.",
    "status": "INVALID_ARGUMENT"
  }
}

原因の分析

エラーメッセージが示す通り、Dataform API (dataform.googleapis.com) を呼び出す際に、どのサービスアカウントとしてジョブを実行するかの指定が漏れていました。

# 問題のあった設定
invocationConfig:
    includedTags:
        - ${tag_name}
    transitiveDependenciesIncluded: true
    # serviceAccountの指定がない!

なぜサービスアカウントの指定が必要なのか

Dataformは内部的にBigQueryのジョブを実行します。そのため:

  • 誰の権限でBigQueryを操作するのか
  • どのサービスアカウントでデータにアクセスするのか

を明示的に指定する必要があります。これは「なりすまし防止」のセキュリティ要件でもあります。

解決策

workflow-dataform-runner.yamlを修正し、invocationConfigにDataform実行用のサービスアカウントを明記しました。

# 修正後の設定
invocationConfig:
    includedTags:
        - ${tag_name}
    transitiveDependenciesIncluded: true
    # ▼▼▼ この行を追加 ▼▼▼
    serviceAccount: "dataform-runner@your-project.iam.gserviceaccount.com"

サービスアカウントに必要な権限

指定するサービスアカウントには、以下の権限が必要です:

  • roles/bigquery.dataEditor: BigQueryへのデータ書き込み
  • roles/bigquery.jobUser: BigQueryジョブの実行
  • 必要に応じて、読み取り元テーブルへのアクセス権限

補足: OIDCとOAuth2の使い分けまとめ

Workflowsで外部サービスを呼び出す際の認証タイプの選び方:

OIDC を使う場合

対象: 自作のサービス(Cloud Run/Functions)

auth:
    type: OIDC

用途: 「私はこのWorkflowsです」という身元証明(認証)

仕組み: IDトークンを生成し、呼び出し先が検証

OAuth2 を使う場合

対象: Google提供の管理API(*.googleapis.com

auth:
    type: OAuth2

用途: 「私にはこの操作をする権限があります」という証明(認可)

仕組み: アクセストークンを生成し、APIが権限を確認

判断のポイント

呼び出し先 ドメイン例 認証タイプ
Cloud Run/Functions *.run.app OIDC
Cloud Run Jobs *.run.app OIDC
Google APIs *.googleapis.com OAuth2

デバッグのヒント

エラーログの確認方法

Workflowsのエラー詳細は、以下で確認できます:

  1. Cloud Console → Workflows → 実行履歴
  2. エラーステップをクリック → errorフィールドを展開
  3. payload内に元のAPIエラーメッセージが含まれている

よくあるエラーパターン

invalid domain for OAuth2

→ 自作サービスに対してOAuth2を使っている。OIDCに変更。

Service account must be set

→ API呼び出しにserviceAccountフィールドが不足。追加。

Permission denied

→ サービスアカウントに必要な権限(IAMロール)が付与されていない。


まとめ

Workflowsから外部サービスを呼び出す際の認証設定は、以下の2点を意識することが重要です:

  1. 呼び出し先の種類(自作サービス vs Google API)で認証タイプを使い分ける
  2. 実行アカウント(特にDataformなど)を明示的に指定する

この理解があれば、認証周りのエラーに遭遇してもスムーズに解決できます。

特にDataformのように「Workflowsから呼び出し → さらに別のサービス(BigQuery)を操作」という多段構成の場合、「誰が誰として何を実行するのか」を整理することが大切です。

ぜひ参考にしてみてください!

Discussion