你在本地或 CI 上跑 firebase deploy,报:
Error: HTTP Error: 403, The caller does not have permission
Error: Request to https://firebase.googleapis.com/... had HTTP Error: 403
或者更直白:
Error: Failed to authenticate, have you run firebase login?
排查的关键不在 firebase deploy 命令本身,而在背后这串身份链:你的本地 Google 账号 → 当前项目映射 → 那个账号在 GCP IAM 里的角色。任一环节断了,就 permission denied。
常见原因
按命中率从高到低:
1. 登的是个人 Google 账号,但项目在公司账号下
最高频。你 firebase login 时随手用了 personal@gmail.com,但要 deploy 的项目在 you@company.com 的 GCP organization 下,personal 账号根本没访问权限。
如何判断:firebase login:list 看当前账号 email,对照 GCP console 里项目在哪个 org / account。
2. 账号在项目里没 Firebase Hosting Admin 角色
账号能”看见”项目但没 deploy 权限。常见于公司新人——SRE 加了 Viewer 但忘了加 Deploy。
如何判断:GCP IAM → 选项目 → 找你的 email → 看 roles 列表。
3. .firebaserc 项目 ID 写错
{
"projects": {
"default": "my-project-prod" // 真实 ID 是 my-project-prod-x9q
}
}
CLI 试图 deploy 一个不存在或你没权限的项目。
如何判断:firebase projects:list 看你能访问哪些项目,对照 .firebaserc 里的 ID。
4. CI 用了过期 / 错的 service account key
CI 用 GOOGLE_APPLICATION_CREDENTIALS 或 FIREBASE_TOKEN 认证。Key 文件被删 / rotate / 权限被撤掉都会失败。
如何判断:CI 日志报 401/403,本地 deploy 同一个项目正常。
5. 需要 enable 的 API 没启用
Cloud Build API / Cloud Functions API / Cloud Run API 没开。Firebase CLI 首次会提示,但 CI 上没人点确认。
如何判断:错误含 “API has not been used” 或 “is disabled”。
6. Org policy 阻止个人账号 deploy
某些 GCP org 设了 “External members not allowed”,gmail.com 账号即使被 invite 也不能 deploy。
如何判断:错误含 “principalType is not allowed by the organization policy”。
最短修复路径
Step 1:自检身份链
# 1. 当前账号
firebase login:list
# 2. 当前能访问的项目
firebase projects:list
# 3. 当前 .firebaserc 的 default 项目
cat .firebaserc
# 4. 当前部署的目标项目
firebase use # 显示 active project
四个输出对照:账号 → 项目列表里能看到 → .firebaserc 里的 ID 在列表里 → use 选的是正确的。
Step 2:登对账号
firebase logout
firebase login # 浏览器选公司账号
firebase login:list # 确认 email 是公司的
如果你需要在多账号间切换,可以用 --account flag:
firebase deploy --account=you@company.com --project=my-prod
Step 3:让 admin 加 IAM 角色
要 deploy Firebase Hosting + Functions 至少需要:
- Firebase Hosting Admin (roles/firebasehosting.admin)
- Cloud Functions Admin (roles/cloudfunctions.admin)
- Service Account User (roles/iam.serviceAccountUser)
- Firebase Admin (roles/firebase.admin) # 简单粗暴
让 admin 在 IAM → 选项目 → Grant Access → 加你的 email + 上述角色。
Step 4:修 .firebaserc
firebase use --add # 交互式选项目
# 或手动改:
{
"projects": {
"default": "my-project-prod-x9q",
"staging": "my-project-staging-a3p"
}
}
firebase use staging # 切到 staging
firebase deploy --only hosting
Step 5:CI 用 service account
不要在 CI 用 firebase login 个人账号。生成 service account:
# 1. 在 GCP IAM → Service Accounts → Create
# 2. 给 SA 加上述 IAM 角色
# 3. 下载 JSON key
# CI(GitHub Actions 示例)
env:
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GCP_SA_KEY }}
steps:
- run: |
echo "${GOOGLE_APPLICATION_CREDENTIALS}" > /tmp/sa.json
export GOOGLE_APPLICATION_CREDENTIALS=/tmp/sa.json
firebase deploy --project my-project-prod --non-interactive
或用 FIREBASE_TOKEN(旧方式):
firebase login:ci # 生成 token,存进 CI secret
firebase deploy --token "$FIREBASE_TOKEN"
Step 6:启用必要的 API
gcloud services enable \
firebase.googleapis.com \
cloudfunctions.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
--project=my-project-prod
或一次去 API Library 全部 enable。
预防建议
- 新成员入职就在 wiki 写明”deploy Firebase 需要这些 IAM 角色”
- 个人项目用个人 Google 账号,工作项目用工作账号——别混用,浏览器 profile 隔离
.firebaserc提交到 git,每个项目 ID 加注释(哪个环境)- CI 一律用 service account,永远不要用个人账号 token
- service account key 每 90 天 rotate 一次,写进运维 calendar
- 用
firebase use staging --reload而不是手动改.firebaserc,命令式更可重现 - deploy 前 dry-run:
firebase deploy --only hosting --dry-run看会改什么