实验 04 应用与服务账号#
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
目标#
应用读取 input.csv,计算总额,创建一个唯一命名的报表,并读取指定测试 Secret。此处验证 Secret 访问,不实际调用第三方服务,也不返回密钥内容。
管理员创建资源并授予权限。第 03 章的输入 Bucket 和 input.csv 应已存在。
gcloud iam service-accounts create report-app --project="$PROJECT_ID" \
--display-name='Report runtime identity'
gcloud storage buckets create "gs://$OUTPUT_BUCKET" --project="$PROJECT_ID" \
--location="$REGION" --uniform-bucket-level-access
printf 'lab-only-not-a-real-key' > records/dummy-secret.txt
gcloud secrets create "$SECRET_ID" --project="$PROJECT_ID" \
--replication-policy=automatic --data-file=records/dummy-secret.txt
gcloud storage buckets add-iam-policy-binding "gs://$INPUT_BUCKET" \
--member="serviceAccount:$APP_SA" --role=roles/storage.objectViewer
gcloud storage buckets add-iam-policy-binding "gs://$OUTPUT_BUCKET" \
--member="serviceAccount:$APP_SA" --role=roles/storage.objectCreator
gcloud secrets add-iam-policy-binding "$SECRET_ID" --project="$PROJECT_ID" \
--member="serviceAccount:$APP_SA" --role=roles/secretmanager.secretAccessor输入读取权包含列表权限,是本例接受的预定义角色粒度。输出只创建新对象,应用不覆盖或删除旧报表。Secret 授权放在单个 Secret 上。SA 没有获得整个项目的 Editor。
在本机使用 Service Account impersonation#
授予 Token Creator 允许 Bob 以该 SA 身份操作其获授权资源。 本实验只在指定 SA 上授予,不在整个 Project 批量授予:
gcloud iam service-accounts add-iam-policy-binding "$APP_SA" --project="$PROJECT_ID" \
--member="user:$DEV_EMAIL" --role=roles/iam.serviceAccountTokenCreatorBob 执行以下正反验证。这里显式指定impersonation 身份,不依赖当前 CLI 的默认模拟设置:
gcloud storage cat "gs://$INPUT_BUCKET/input.csv" --impersonate-service-account="$APP_SA"
printf 'demo report' > records/probe.txt
gcloud storage cp records/probe.txt "gs://$OUTPUT_BUCKET/probe-$(date +%s).txt" \
--impersonate-service-account="$APP_SA"
# 预期拒绝:运行身份不能删除输入。
gcloud storage rm "gs://$INPUT_BUCKET/input.csv" --impersonate-service-account="$APP_SA"
# 预期拒绝:创建输出不代表能列出输出。
gcloud storage ls "gs://$OUTPUT_BUCKET" --impersonate-service-account="$APP_SA"若删除居然成功,由管理员从 records/input.csv 恢复输入,并先排查超额授权,不继续把该环境当作最小权限成立。
本地应用与 ADC#
Bob 在独立实验开发机或独立操作系统用户中建立 ADC;ADC 与 gcloud 配置不是同一套身份设置:
gcloud auth application-default login --impersonate-service-account="$APP_SA"
python3 -m venv app/.venv
app/.venv/bin/pip install -r app/requirements.txt
export SECRET_VERSION="projects/$PROJECT_ID/secrets/$SECRET_ID/versions/latest"
app/.venv/bin/python app/main.py另一个终端调用 curl -X POST http://127.0.0.1:8080/report。预期返回报表对象路径、行数和合计 30。使用 Python 客户端库读取 ADC。若错误涉及 quota project 的 Service Usage 权限,按错误核对消费项目与impersonation 身份所需权限,不改用 Owner 绕过。
本地端点仅用于实验;本地启动默认监听回环地址。Cloud Run 的访问认证由平台负责,应用源码不实现客户登录和多租户隔离。
回滚与验收#
停止本地进程,执行 gcloud auth application-default revoke 清理本实验 ADC;仅适用于这里建立的独立实验环境。管理员移除 Bob 对运行 SA 的 Token Creator 绑定。后续 Cloud Run 仍可使用绑定的 SA,不依赖 Bob 的本地凭据。
回答:给 SA 授予 Bucket 角色,与在 SA 上给 Bob 授予 Token Creator,有何区别?为什么本地登录成功不能证明线上应用权限正确?