S176 IAM RCA: cursor-ci-builder Missing Permissions Pattern
S176-IAM-RCA: Root Cause Analysis — cursor-ci-builder Missing Secret Manager Access
Ngày điều tra: 2026-04-10 Mission: S176 (Lark Production Infrastructure) Trạng thái: FIXED — IAM binding added, GSM access verified
1. Bối cảnh
Khi bắt đầu S176, phát hiện SA cursor-ci-builder trên VPS không có quyền đọc GSM secrets (LARK_APP_ID, LARK_APP_SECRET). Đây là lần thứ 2 trong 3 phiên gặp pattern "IAM silent missing":
- S174:
cursor-ci-builderthiếustorage.buckets.list→ GCS upload fail (WARN), backup hỏng 28 ngày - S176:
cursor-ci-builderthiếusecretmanager.versions.access→ không đọc được Lark credentials
2. RCA — 5 câu hỏi
Q1: Ai tạo SA cursor-ci-builder, khi nào?
- Display name: "GitHub Actions Build / Push Artifact Registry"
- Email:
cursor-ci-builder@github-chatgpt-ggcloud.iam.gserviceaccount.com - Project:
github-chatgpt-ggcloud - Mục đích ban đầu: CI/CD cho GitHub Actions — build Docker image, push lên Artifact Registry
- Ngày tạo: Không xác định chính xác (GCP
describekhông trả creation date). Xuất hiện trong Gemini chat logs từ 2025-10-26, nên tạo khoảng Q4 2025. - Không có trong Terraform IaC — SA và IAM bindings được tạo thủ công qua
gcloudCLI
Q2: SA có những role gì?
| Role | Mục đích |
|---|---|
roles/artifactregistry.writer |
Push Docker images (mục đích gốc) |
roles/cloudsql.client |
Cloud SQL access |
roles/datastore.user |
Firestore/Datastore |
roles/secretmanager.secretAccessor |
MỚI THÊM hôm nay — đọc GSM secrets |
Nhận xét: SA bắt đầu đời chỉ với artifactregistry.writer (CI/CD), rồi được "mượn" làm SA chính trên VPS khi setup gcloud. Mỗi lần cần tính năng mới (Cloud SQL, Firestore, GSM), phải add role thủ công — và quên thì silent fail.
Q3: SA cần đọc secret nào khác? Còn thiếu quyền gì?
Secrets trong GSM (22 total):
AGENT_DATA_API_KEY,DIRECTUS_ADMIN_TOKEN,DIRECTUS_KEY,DIRECTUS_SECRETGCS_BUCKET_BACKUPLARK_APP_ID,LARK_APP_SECRETMYSQL_ROOT_PASSWORD(legacy)OPENAI_API_KEYPG_DATABASE,PG_HOST,PG_PASSWORD,PG_PORT,PG_USERPOSTGRES_DB,POSTGRES_PASSWORD,POSTGRES_USERQDRANT_LOCAL_API_KEYgh_pat_sync_secretssmtp-password-nmhuyenvps_contabo_id,vps_contabo_secret
Codebase references trên VPS: Chỉ 1 script đọc GSM trực tiếp:
gh_pat_sync_secrets— used by git-push scripts
Hiện tại secretAccessor cho phép đọc TẤT CẢ secrets (project-level binding, không có condition). Đủ cho cả gh_pat_sync_secrets và LARK_APP_*.
Missing permissions đã biết (từ S174):
storage.buckets.list— vẫn thiếu (S174 ghi nhận, chưa fix, coi là out-of-scope)
Q4: Có IaC (Terraform) quản lý IAM không?
KHÔNG. cursor-ci-builder không xuất hiện trong bất kỳ file .tf nào:
agent-data-test/terraform/iam.tfchỉ quản lý compute default SA- Không có
.tffile nào referencecursor-ci-builder
Hệ quả: Mọi IAM change cho SA này đều thủ công (gcloud CLI). Không có drift detection, không có version control, không có review process.
Q5: Liên quan S174 47h silent không?
CÓ — cùng root cause pattern. Đối chiếu:
| S174 | S176 | |
|---|---|---|
| SA | cursor-ci-builder |
cursor-ci-builder |
| Missing role | storage.buckets.list |
secretmanager.secretAccessor |
| Symptom | GCS backup upload silent fail | GSM secret access denied |
| Silent duration | 28 ngày | Phát hiện ngay (nhờ P0 snapshot) |
| Root cause | SA thiếu role, không IaC, không audit | Cùng |
Pattern: SA được repurpose từ CI-only → multi-purpose VPS SA, nhưng permissions chỉ được thêm ad-hoc khi gặp lỗi, không có checklist "SA cần gì cho use case X".
3. Gốc rễ thật (1 câu)
SA
cursor-ci-builderđược tạo cho mục đích hẹp (CI Artifact Registry) rồi được repurpose làm SA chính trên VPS, nhưng IAM bindings quản lý thủ công (không IaC), không có audit/review process, nên mỗi lần thêm use case mới thì thiếu role → silent fail.
4. Fix đã thực hiện
# 2026-04-10, từ Desktop (nmhuyen@gmail.com)
gcloud projects add-iam-policy-binding github-chatgpt-ggcloud \
--member="serviceAccount:cursor-ci-builder@github-chatgpt-ggcloud.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor" \
--condition=None
# Verify trên VPS
ssh root@38.242.240.89 'gcloud secrets versions access latest \
--secret=LARK_APP_ID --project=github-chatgpt-ggcloud | head -c 15'
# Output: cli_a785d634437 (khớp app "For Gem")
5. Đề xuất hệ thống (chờ Desktop duyệt — scope ngoài S176)
| # | Đề xuất | Priority |
|---|---|---|
| 1 | Terraform-ize cursor-ci-builder IAM — Add SA + all bindings vào iam.tf. Drift = terraform plan sẽ phát hiện. |
HIGH |
| 2 | IAM audit cron — Weekly script: dump gcloud projects get-iam-policy, diff với baseline, alert nếu có thay đổi. |
MEDIUM |
| 3 | SA purpose documentation — Ghi rõ mỗi SA dùng cho gì, cần role gì, trong KB. | MEDIUM |
| 4 | Pre-mission IAM checklist — Khi mission cần GSM/GCS/API mới, check SA permissions TRƯỚC, không phải lúc gặp lỗi. | HIGH |
6. Ghi chú kỹ thuật
secretAccessorlà project-level (tất cả secrets). Nếu cần restrict → dùng secret-level IAM binding.gcloud projects add-iam-policy-bindingyêu cầu--condition=Nonekhi policy đã có conditional bindings.- SA
describekhông trảcreateTime— cần Audit Log hoặc Activity Log để xác định.
RCA bởi Claude Code, Mission S176 Phase 0, 2026-04-10