Firebase Admin v12でcreateSessionCookie時にpermission denied
現象
firebase authenticationでログインした後にCookieに保存するセッションIDを作成しようとするとpermission deniedが発生。
Cloud Functionsのログ
{
"error": {
"code": 403,
"message": "Caller does not have required permission to use project [PROJECT_ID]. Grant the caller the roles/serviceusage.serviceUsageConsumer role, or a custom role with the serviceusage.services.use permission, by visiting https://console.developers.google.com/iam-admin/iam/project?project=[PROJECT_ID] and then retry. Propagation of the new permission may take a few minutes.",
"errors": [
{
"message": "Caller does not have required permission to use project [PROJECT_ID]. Grant the caller the roles/serviceusage.serviceUsageConsumer role, or a custom role with the serviceusage.services.use permission, by visiting https://console.developers.google.com/iam-admin/iam/project?project=[PROJECT_ID] and then retry. Propagation of the new permission may take a few minutes.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "USER_PROJECT_DENIED",
"domain": "googleapis.com",
"metadata": {
"service": "identitytoolkit.googleapis.com",
"consumer": "projects/[PROJECT_ID]",
"containerInfo": "[PROJECT_ID]"
}
},
{
"@type": "type.googleapis.com/google.rpc.LocalizedMessage",
"locale": "en-US",
"message": "Caller does not have required permission to use project [PROJECT_ID]. Grant the caller the roles/serviceusage.serviceUsageConsumer role, or a custom role with the serviceusage.services.use permission, by visiting https://console.developers.google.com/iam-admin/iam/project?project=[PROJECT_ID] and then retry. Propagation of the new permission may take a few minutes."
},
{
"@type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google developer console IAM admin",
"url": "https://console.developers.google.com/iam-admin/iam/project?project=[PROJECT_ID]"
}
]
}
]
}
}
原因
ログ上では、roles/serviceusage.serviceUsageConsumer
ロールかserviceusage.services.use
権限を含むカスタムロールを作成しろ
呼び出し元にプロジェクト [PROJECT_ID] を使用するために必要な権限がないのでGoogle Identity Toolkit API
にリクエストを拒否されているようでした。
ログによると、次のいずれかの権限を付与して許可しなさいとのことです。
-
roles/serviceusage.serviceUsageConsumer
ロール
または -
serviceusage.services.use
権限を含むカスタムロール
なお、firebase deployで自動でfunctionsやhostingなどデプロイしてくれているので、裏側でGoogle Identity Toolkit APIが使われていたのは知らなかったです😅
また、同じアプリケーションなのに以前の組織で発生しなかったのは、2024 年 5 月 3 日以降作成された組織では、自動的なロール付与が無効になったからですね。
解決策
- エラーが出ているfirebase functionsで使用されているサービスアカウントを以下コマンドで確認
gcloud functions describe {関数名} --region={リージョン名}
ちなみに、自分は関数名やリージョンはfirebaseコンソールから確認しました。
gcloud functions describe {関数名} --region={リージョン名}
結果例
...
serviceConfig:
...
serviceAccountEmail: xxxxxxxxxxxx-compute@developer.gserviceaccount.com
...
ここで、xxxxxxxxxxxx-compute@developer.gserviceaccount.com
のサービスアカウントで権限エラーが起きていたということがわかります。
- 問題のあるアカウントのロールを確認
gcloud projects get-iam-policy [PROJECT_ID] \
--flatten="bindings[].members" \
--filter="bindings.members:xxxxxxxxxxxx-compute@developer.gserviceaccount.com" \
--format="table(bindings.role)"
例えば、以下のような感じで、roles/serviceusage.serviceUsageConsumer
はついていない状態のはずです。
結果例
ROLE
roles/cloudbuild.builds.builder
roles/cloudbuild.workerPoolUser
roles/iam.serviceAccountUser
-
roles/serviceusage.serviceUsageConsumer
ロールの追加
gcloud projects add-iam-policy-binding [PROJECT_ID] \
--member="serviceAccount:xxxxxxxxxxxx-compute@developer.gserviceaccount.com" \
--role="roles/serviceusage.serviceUsageConsumer"
追加したら、ロールが正しく付与されたか確認。
gcloud projects get-iam-policy [PROJECT_ID] \
--flatten="bindings[].members" \
--filter="bindings.members:xxxxxxxxxxxx-compute@developer.gserviceaccount.com" \
--format="table(bindings.role)"
結果例
ROLE
...
roles/serviceusage.serviceUsageConsumer
以上で、serviceUsageConsumer
が不足していた件は解決なのですが、自分はエラーが別の内容に変わりました。
Permission 'iam.serviceAccounts.signBlob' denied on resource (or it may not exist).;
Please refer to https://firebase.google.com/docs/auth/admin/create-custom-tokens for more details on how to use and troubleshoot this feature.
iam.serviceAccounts.signBlob
の権限がないために、Firebase Admin SDK を使用してカスタムトークンを作成する操作が拒否されているそうです。なので、追加の対応が必要です。
-
roles/iam.serviceAccountTokenCreator
ロールの追加
iam.serviceAccounts.signBlob 権限はroles/iam.serviceAccountTokenCreator
のロールに含まれているので、このロールを付与してあげれば解決です。
gcloud projects add-iam-policy-binding [PROJECT_ID] \
--member="serviceAccount:xxxxxxxxxxxx-compute@developer.gserviceaccount.com" \
--role="roles/iam.serviceAccountTokenCreator"
追加したら、ロールが正しく付与されたか確認。
gcloud projects get-iam-policy [PROJECT_ID] \
--flatten="bindings[].members" \
--filter="bindings.members:xxxxxxxxxxxx-compute@developer.gserviceaccount.com" \
--format="table(bindings.role)"
結果例
ROLE
...
roles/iam.serviceAccountTokenCreator
以上で解決です。
権限を付与した後、createSessionCookie を再度実行してみてください。正常に動作するはずです。
備考
山ほどネットの記事調べ上げましたが、このエラー解決は、本当に苦労しました。今までロール自動付与で問題起きていなかったので、自動的なロール付与が無効になってからというもの、権限周りのエラーでよく頭悩まされる。
ログイン処理でcreateSessionCookieがこけている際は、ぜひ参考にしてみてください。
Discussion