IAM Recommender — Cơ Chế Nội Tại và Least-Privilege Automation
Vấn đề IAM Recommender giải quyết
Trong thực tế, IAM permission thường được grant theo mô hình "theo nhu cầu nhưng không thu hồi": khi developer cần access một resource, họ được grant role — rộng hơn cần thiết vì tiện, và không ai nhớ revoke khi không cần nữa. Sau 2-3 năm, một project production có thể có hàng chục service accounts và users với roles quá rộng so với những gì họ thực sự dùng.
IAM Recommender giải quyết bài toán này bằng cách tự động phân tích usage patterns và đề xuất thu hẹp permissions đến mức tối thiểu cần thiết. Đây là công cụ chính trong "IAM hygiene" — process dọn dẹp permissions định kỳ để đảm bảo least-privilege.
Cơ chế nội tại: Dữ liệu gì được dùng
90-day observation window
Recommender track permission usage trong 90 ngày — với principal đã tồn tại ít nhất 90 ngày. Đây là điểm quan trọng:
Theo GCP documentation: Recommender compares "a principal's total number of permissions with the permissions that the principal used in the last 90 days."
Nếu một role binding được grant chưa đến 90 ngày, Recommender không có đủ data để generate recommendation — đây là cơ chế bảo vệ tránh recommend revoke roles mới được grant nhưng chưa có cơ hội dùng.
Minimum observation period có thể adjust ở project level (30, 60, hoặc 90 ngày), nhưng 90 ngày là default và recommended vì các workloads seasonal (ví dụ: monthly report jobs, quarterly audits) cần đủ thời gian để usage patterns được capture.
Nguồn data
Recommender collect dữ liệu từ:
- Cloud Audit Logs: Admin Activity và Data Access logs ghi lại actual API calls
- GCP API metadata: Google biết permissions nào được require cho từng API call
- Co-occurrence patterns: ML model train trên co-occurrence của permissions thường được dùng cùng nhau
Data privacy: Theo documentation, "All data used in the IAM recommender machine learning pipeline has k-anonymity" — tức là data được anonymized, không có PII trước khi đưa vào ML training.
ML pipeline: Không chỉ "đo usage"
IAM Recommender không chỉ đơn giản là "nếu permission không được dùng trong 90 ngày → recommend remove". Machine learning pipeline phức tạp hơn:
Co-occurrence clustering: Permissions thường được dùng cùng nhau (vì cùng thuộc một workflow) được group lại. Nếu
storage.objects.getvàstorage.objects.listthường đi cùng, Recommender sẽ không recommend tách chúng ra.Semantic similarity: Word embeddings identify permissions conceptually related. Permissions
bigquery.tables.getvàbigquery.tables.getDatacó semantic relationship — Recommender aware điều này khi generate replacement roles.Predefined role matching: Recommender ưu tiên suggest predefined roles thay vì luôn suggest custom roles, vì predefined roles ổn định và được Google maintain.
Bốn loại recommendation
1. REMOVE_ROLE
Đơn giản nhất: Principal có một role nhưng không dùng bất kỳ permission nào trong 90 ngày. Recommendation: remove role hoàn toàn.
Principal: alice@example.com
Current: roles/bigquery.admin
Usage (90 ngày): 0 permissions used
Recommendation: REMOVE_ROLEĐây thường xảy ra khi: người dùng chuyển team, project không còn active, test access không được revoke.
2. REPLACE_ROLE
Principal đang dùng một subset của permissions trong role, và có predefined role hẹp hơn bao gồm chỉ những permissions đã dùng.
Principal: backend-sa@project.iam.gserviceaccount.com
Current: roles/bigquery.admin (150+ permissions)
Used: bigquery.jobs.create, bigquery.tables.getData (2 permissions)
Recommendation: REPLACE_ROLE với roles/bigquery.jobUser + roles/bigquery.dataViewer3. REPLACE_ROLE_CUSTOMIZABLE
Không có predefined role nào phù hợp chính xác với permissions đã dùng. Recommender suggest tạo custom role chứa chỉ những permissions đã được sử dụng.
Principal: etl-sa@project.iam.gserviceaccount.com
Current: roles/storage.admin (30 permissions)
Used: storage.objects.get, storage.buckets.list, storage.objects.create
Recommendation: REPLACE_ROLE_CUSTOMIZABLE
→ Tạo custom role với 3 permissions đã dùngCustom role được suggest ở project level (không phải org level) vì: org-level limit là 100 custom roles.
4. SERVICE_AGENT_WITH_DEFAULT_ROLE
Phát hiện cases khi Google-managed service agents (như Compute Engine service agent) đang có roles bị thay đổi khỏi default. Recommend restore về default roles của service agent.
Lateral movement insights: Beyond permission usage
Bên cạnh permission usage recommendations, Recommender còn generate lateral movement insights — một loại insight khác tập trung vào security risks.
Lateral movement insight phát hiện service accounts có permissions để impersonate SAs trong projects khác (cross-project impersonation). Đây là pattern nguy hiểm: nếu SA A trong project B bị compromise, attacker có thể pivot sang project C thông qua impersonation chain.
Insight example:
SA: pipeline-sa@project-a.iam.gserviceaccount.com
Has: roles/iam.serviceAccountTokenCreator trên
worker-sa@project-b.iam.gserviceaccount.com
Risk: Cross-project lateral movement path
Recommendation: Review nếu impersonation này thật sự cần thiếtGiới hạn quan trọng của IAM Recommender
1. Không áp dụng cho conditional bindings
Bindings với IAM Conditions không được phân tích bởi Recommender. Nếu organization dùng nhiều conditional bindings (time-based access, resource-tag-based), Recommender sẽ không có data về bindings đó.
2. Chỉ cho specific principal types
Recommender chỉ analyze:
- User accounts (Google Accounts)
- Service accounts
- Google Groups
- Workload Identity Federation principals
Không analyze:
allUsershayallAuthenticatedUsersbindings (nhưng đây là anti-pattern cần manually review)- Service agents (Google-managed)
3. Không apply tự động
"The IAM recommender does not apply recommendations automatically."
Recommender chỉ suggest — không modify IAM policies. Team phải review và apply hoặc dismiss recommendations. Điều này là thiết kế có chủ đích: không muốn automated system revoke permissions mà không có human review, vì có thể break production workloads.
4. Inactive projects không có recommendations
Nếu project không có API activity (không có audit log events), Recommender không có data để analyze.
5. 90-day window có thể miss seasonal access patterns
Nếu một role được dùng cho quarterly reports, trong 90 ngày không overlap với quarterly cycle, Recommender có thể recommend remove role đó. Team cần aware điều này và dismiss recommendations cho seasonal workloads.
Integrate Recommender vào IAM hygiene workflow
Pull recommendations bằng CLI
# List tất cả IAM recommendations cho một project
gcloud recommender recommendations list \
--project=PROJECT_ID \
--recommender=google.iam.policy.Recommender \
--location=global \
--format=json
# Filter chỉ recommendations có high confidence
gcloud recommender recommendations list \
--project=PROJECT_ID \
--recommender=google.iam.policy.Recommender \
--location=global \
--filter="stateInfo.state=ACTIVE" \
--format="table(name, recommenderSubtype, primaryImpact.securityProjection.details)"Apply một recommendation
# Apply recommendation (sau khi review)
gcloud recommender recommendations mark-applied RECOMMENDATION_ID \
--project=PROJECT_ID \
--location=global \
--recommender=google.iam.policy.Recommender \
--etag=RECOMMENDATION_ETAG
# Dismiss recommendation (nếu không muốn apply)
gcloud recommender recommendations mark-dismissed RECOMMENDATION_ID \
--project=PROJECT_ID \
--location=global \
--recommender=google.iam.policy.Recommender \
--etag=RECOMMENDATION_ETAGAutomation workflow cho IAM hygiene
Không nên auto-apply recommendations, nhưng có thể automate việc review và triage:
from google.cloud import recommender_v1
from google.cloud import iam_admin_v1
def weekly_iam_hygiene_report():
client = recommender_v1.RecommenderClient()
parent = client.recommender_path(
project="my-project",
location="global",
recommender="google.iam.policy.Recommender"
)
recommendations = client.list_recommendations(parent=parent)
high_impact = []
for rec in recommendations:
if rec.state_info.state == recommender_v1.RecommendationStateInfo.State.ACTIVE:
impact = rec.primary_impact
# Filter: Chỉ lấy recommendations liên quan đến service accounts
# (higher risk than user accounts)
if "serviceAccount" in rec.content.operation_groups[0].operations[0].path:
high_impact.append({
"id": rec.name,
"type": rec.recommender_subtype,
"priority": rec.priority.name,
"description": rec.description
})
# Send report via email/Slack cho security team review
send_report(high_impact)Đọc Recommendations đúng cách: Không phải lúc nào cũng apply
IAM Recommender suggestions không phải luôn luôn đúng để apply ngay. Trước khi apply, cần review:
1. Seasonal/infrequent workloads: Batch jobs chạy hàng quý, backup scripts chạy hàng tháng sẽ có 0 usage trong 90 ngày nếu không overlap với cycle. Dismiss và annotate với lý do.
2. Disaster recovery roles: Roles dành cho DR scenarios (break-glass access, emergency procedures) deliberately không được dùng trong normal operations. Cần protect khỏi being recommended out.
3. New services: SA được tạo cho service sắp ra mắt nhưng chưa deploy production sẽ có 0 usage. Dismiss với comment "pending deployment".
4. Review custom role suggestion carefully: Khi Recommender suggest REPLACE_ROLE_CUSTOMIZABLE, review kỹ danh sách permissions trong custom role được suggest. Recommender dựa vào historical usage — nếu service có code path nào chưa được invoke trong 90 ngày, permission cần thiết cho code path đó sẽ không có trong custom role suggestion.
IAM Recommender trong context IAM hygiene program
Recommender là một tool, không phải một program. Least-privilege implementation cần một program xung quanh nó:
IAM Hygiene Program:
├── Weekly: Pull và triage Recommender recommendations
├── Monthly: Apply approved recommendations sau review
├── Quarterly: Audit role assignments theo team/service
├── Semi-annually: Review custom roles cho permission drift
│ (Google có thể add permissions vào predefined roles
│ mà custom role không tự update)
└── On-demand: Review khi offboard user/service, khi change team,
khi deprecate serviceRecommender phủ được "permissions granted nhưng không dùng" — nhưng không phủ được "permissions cần thiết nhưng không được grant" (false negatives) và không phủ được organizational context (ai là oncall, ai đang thực hiện incident response).