Skip to content

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) 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 → DENIED

Ingress 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):

yaml
# 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:

FieldGiá trịÝ nghĩa
identityTypeANY_IDENTITYBất kỳ danh tính nào
identityTypeANY_USER_ACCOUNTBất kỳ user (không phải service account)
identityTypeANY_SERVICE_ACCOUNTBất kỳ service account
identitiesDanh 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:

FieldGiá trịÝ nghĩa
sources.accessLevelAccess level resource nameRequest phải match access level này
sources.resource//cloudresourcemanager.googleapis.com/projects/PROJECT_IDRequest phải đến từ project này
Không có sourcesN/ACho 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 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ì:

yaml
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 perimeter

Cấ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):

yaml
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ể access
  • ingressTo: Đị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ài
  • egressTo: Đị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).

yaml
# 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).

yaml
# 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:

yaml
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 → DENY

Nhưng bên trong một rule, ingressFrom phải match 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:

yaml
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

yaml
# 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.

References