Ingress & Egress Rules — Cross-Perimeter Access Fine-Grained
Tại sao cần ingress/egress rules thay vì access levels?
Access levels giải quyết một use case cụ thể: cho phép human users từ trusted networks (corp IP, trusted device) vào perimeter. Nhưng trong production, có nhiều tình huống phức tạp hơn:
- Service A trong perimeter cần gọi Service B ngoài perimeter: Access level không handle được vì access levels chỉ cho phép vào perimeter, không cho phép ra khỏi perimeter
- Service Account từ project ngoài cần đọc BigQuery trong perimeter: Access level IP-based không đủ granular — cần authorize theo project và identity cụ thể
- Một service bên ngoài (Dataflow job trong project khác) cần đọc Cloud Storage trong perimeter: Cần cho phép cross-project, cross-service access có kiểm soát
Ingress rules và egress rules là cơ chế để xử lý các trường hợp này — chúng cung cấp kiểm soát cross-perimeter API access ở mức độ granular nhất trong VPC SC.
Internal Model: Request Flow và Rule Evaluation
Định nghĩa ingress vs egress
Từ góc nhìn của perimeter:
- Ingress: Request đi vào perimeter — API client bên ngoài truy cập resource bên trong
- Egress: Request đi ra khỏi perimeter — API client bên trong truy cập resource bên ngoài
[CLIENT bên ngoài] ──INGRESS──► [RESOURCE bên trong perimeter]
[CLIENT bên trong perimeter] ──EGRESS──► [RESOURCE bên ngoài]Một điểm tinh tế quan trọng: VPC SC evaluate cả hai chiều của một operation. Ví dụ, gcloud storage cp gs://bucket-in-perimeter/file gs://bucket-outside-perimeter/ là một operation nhưng require cả ingress rule (để read từ bucket trong perimeter) và egress rule (để write vào bucket ngoài perimeter). Cả hai phải được định nghĩa nếu không operation sẽ bị block.
Evaluation Order
Khi VPC SC nhận một cross-perimeter request, nó evaluate theo thứ tự:
Request đến (từ bên ngoài vào bên trong)
│
├── Có match access level nào không? → YES → ALLOWED
│
└── Không match access level nào
│
└── Kiểm tra ingress rules (theo thứ tự)
├── Rule 1 match? → ALLOWED
├── Rule 2 match? → ALLOWED
└── Không rule nào match → DENIEDIngress rules và access levels là hai cơ chế song song độc lập — nếu một trong hai match, request được allowed.
Cấu Trúc Ingress Rule
Mỗi ingress rule gồm hai block bắt buộc: ingressFrom (nguồn) và ingressTo (đích):
# Cấu trúc đầy đủ của một ingress rule
ingressPolicies:
- ingressFrom:
# Xác định NGUỒN của request (bên ngoài perimeter)
identityType: ANY_SERVICE_ACCOUNT # hoặc ANY_IDENTITY, ANY_USER_ACCOUNT
# Hoặc danh sách danh tính cụ thể:
identities:
- serviceAccount:sa@project.iam.gserviceaccount.com
- user:admin@company.com
# Nguồn network/project:
sources:
- accessLevel: accessPolicies/123/accessLevels/corp_network
# Hoặc restrict theo project cụ thể:
- resource: //cloudresourcemanager.googleapis.com/projects/partner-project-id
ingressTo:
# Xác định RESOURCES và OPERATIONS được phép bên trong perimeter
operations:
- serviceName: storage.googleapis.com
methodSelectors:
- method: google.storage.v1.Storage.GetObject
- method: google.storage.v1.Storage.ListObjects
- serviceName: bigquery.googleapis.com
methodSelectors:
- permission: bigquery.tables.getData
# Resources cụ thể bên trong perimeter (optional, mặc định là tất cả):
resources:
- "projects/123456789"ingressFrom: Xác định nguồn request
ingressFrom có hai loại conditions kết hợp với nhau (AND logic):
1. Identity conditions — Ai đang gửi request:
| Field | Giá trị | Ý nghĩa |
|---|---|---|
identityType | ANY_IDENTITY | Bất kỳ danh tính nào |
identityType | ANY_USER_ACCOUNT | Bất kỳ user (không phải service account) |
identityType | ANY_SERVICE_ACCOUNT | Bất kỳ service account |
identities | Danh sách cụ thể | Chỉ các danh tính được liệt kê |
Chỉ dùng một trong identityType hoặc identities, không dùng cả hai.
2. Source conditions — Request đến từ đâu:
| Field | Giá trị | Ý nghĩa |
|---|---|---|
sources.accessLevel | Access level resource name | Request phải match access level này |
sources.resource | //cloudresourcemanager.googleapis.com/projects/PROJECT_ID | Request phải đến từ project này |
Không có sources | N/A | Cho phép từ bất kỳ nguồn nào |
Khi kết hợp identity và sources, cả hai đều phải match (AND): identity phải đúng VÀ nguồn phải đúng.
ingressTo: Xác định operations được phép
ingressTo định nghĩa resources nào trong perimeter được access và với operations gì:
ingressTo:
operations:
# Option 1: Specify service + specific methods
- serviceName: storage.googleapis.com
methodSelectors:
- method: google.storage.v1.Storage.GetObject
# Option 2: Specify service + all methods via wildcard permission
- serviceName: bigquery.googleapis.com
methodSelectors:
- permission: "*"
# Option 3: IAM role-based (thay vì methods)
- serviceName: bigquery.googleapis.com
methodSelectors:
- permission: bigquery.tables.getData
# Restrict đến resources cụ thể (optional)
resources:
- "projects/123456789" # Chỉ project này trong perimeterCấu Trúc Egress Rule
Egress rules có cấu trúc đảo ngược: egressFrom (nguồn bên trong) và egressTo (đích bên ngoài):
egressPolicies:
- egressFrom:
# Xác định NGUỒN bên trong perimeter
identityType: ANY_IDENTITY
# Hoặc:
identities:
- serviceAccount:dataflow-sa@my-project.iam.gserviceaccount.com
# Optional: restrict theo source project:
sources:
- resource: //cloudresourcemanager.googleapis.com/projects/my-project
egressTo:
# Xác định ĐÍCH bên ngoài perimeter
operations:
- serviceName: storage.googleapis.com
methodSelectors:
- permission: "*"
# Resources bên ngoài perimeter được phép:
resources:
- "projects/partner-project-id"
# Hoặc external resources (cho BigQuery Omni):
externalResources:
- "//s3.amazonaws.com/my-bucket"Sự khác biệt quan trọng giữa ingress và egress
Ingress: Protect resources bên trong khỏi unauthorized external access
ingressFrom: Định nghĩa ai (từ ngoài) có thể accessingressTo: Định nghĩa cái gì (bên trong) họ được access
Egress: Ngăn data từ perimeter chảy ra ngoài không kiểm soát
egressFrom: Định nghĩa ai (bên trong) có thể gửi data ra ngoàiegressTo: Định nghĩa đích nào (bên ngoài) họ có thể gửi đến
Không có egress rule, một service account bên trong perimeter có thể tự do copy data ra các bucket bên ngoài — đây là data exfiltration path mà VPC SC được thiết kế để block.
Các Pattern Cross-Perimeter Phổ Biến
Pattern 1: Cho phép external service account đọc data trong perimeter
Tình huống: Dataflow job chạy trong project B (ngoài perimeter) cần đọc BigQuery table trong project A (trong perimeter).
# Ingress rule trên perimeter chứa project A
ingressPolicies:
- ingressFrom:
identities:
- serviceAccount:dataflow-sa@project-b.iam.gserviceaccount.com
sources:
- resource: //cloudresourcemanager.googleapis.com/projects/project-b
ingressTo:
operations:
- serviceName: bigquery.googleapis.com
methodSelectors:
- permission: bigquery.tables.getData
- permission: bigquery.jobs.create
resources:
- "projects/project-a-id"Pattern này cho phép chỉ service account cụ thể từ chỉ project cụ thể đọc BigQuery — không cho phép các service accounts khác hay các project khác.
Pattern 2: Cho phép write kết quả ra project ngoài perimeter
Tình huống: Service trong perimeter xử lý data và cần ghi kết quả vào Cloud Storage bucket của đối tác (ngoài perimeter).
# Egress rule: cho phép service account trong perimeter ghi ra ngoài
egressPolicies:
- egressFrom:
identities:
- serviceAccount:data-processor@project-a.iam.gserviceaccount.com
egressTo:
operations:
- serviceName: storage.googleapis.com
methodSelectors:
- permission: storage.objects.create
resources:
- "projects/partner-project-id"Pattern 3: Shared VPC — Yêu cầu bắt buộc
Tình huống: Host project của Shared VPC ở ngoài perimeter nhưng service projects trong perimeter cần dùng network resources.
Giải pháp đúng: Include host project vào cùng perimeter với service projects. Đây là yêu cầu bắt buộc — nếu chỉ include service projects, VPC SC không thể correctly evaluate network context.
SAII:
Perimeter: [service-project-A] [service-project-B]
Ngoài perimeter: [host-project] ← VPC SC sẽ fail với NETWORK_NOT_IN_SAME_SERVICE_PERIMETER
ĐÚNG:
Perimeter: [host-project] [service-project-A] [service-project-B]Pattern 4: Cho phép Logging/Monitoring từ bên ngoài quan sát vào perimeter
Tình huống: Cloud Monitoring agents và Logging cần export metrics và logs từ resources trong perimeter ra external monitoring systems.
VPC SC tự động allow một số Google-managed services (như Cloud Logging, Cloud Monitoring) để hoạt động với resources trong perimeter mà không cần ingress/egress rules riêng. Tuy nhiên, nếu bạn có custom monitoring infrastructure bên ngoài perimeter, cần explicit egress rule:
egressPolicies:
- egressFrom:
identityType: ANY_SERVICE_ACCOUNT # Các SAs trong perimeter
egressTo:
operations:
- serviceName: monitoring.googleapis.com
methodSelectors:
- permission: "*"
- serviceName: logging.googleapis.com
methodSelectors:
- permission: "*"
resources:
- "projects/monitoring-project-id"Multiple Rules và Evaluation Logic
Khi có nhiều ingress/egress rules, VPC SC evaluate theo OR logic — request chỉ cần match một trong số các rules là được allow:
Request đến
├── Ingress Rule 1: match? → ALLOW (dừng evaluation)
├── Ingress Rule 2: match? → ALLOW (dừng evaluation)
└── Ingress Rule 3: match? → ALLOW (dừng evaluation)
└── Không rule nào match → DENYNhưng bên trong một rule, ingressFrom phải match VÀ ingressTo phải match (AND logic):
Rule match = (ingressFrom conditions ALL match) AND (ingressTo conditions ALL match)IAM Roles trong Ingress/Egress Rules
Thay vì chỉ định specific methods, bạn có thể dùng IAM roles trong methodSelectors. VPC SC sẽ tự map IAM role ra các permissions tương ứng:
ingressTo:
operations:
- serviceName: bigquery.googleapis.com
methodSelectors:
# Dùng IAM role thay vì liệt kê từng method
- role: roles/bigquery.dataViewerĐây là cách tiếp cận scalable hơn — khi Google thêm new methods vào BigQuery, role-based rules tự động bao gồm các methods mới mà không cần cập nhật VPC SC config.
Anti-Pattern: Quá Loose Rules
# Anti-pattern: Quá rộng, vô hiệu hóa VPC SC
ingressPolicies:
- ingressFrom:
identityType: ANY_IDENTITY
ingressTo:
operations:
- serviceName: "*"
methodSelectors:
- permission: "*"
resources:
- "*"Rule này về cơ bản vô hiệu hóa VPC SC. Luôn bắt đầu từ least privilege và mở rộng dần khi có nhu cầu thực tế, dùng dry-run mode để validate trước khi enforce.