Skip to content

Conversation

@chance-coleman
Copy link
Contributor

@chance-coleman chance-coleman commented Dec 4, 2025

Description

  • Centralizes Ambient egress control per host. For each external host:
    • Creates a shared ServiceEntry in istio-egress-ambient.
    • Creates a centralized AuthorizationPolicy in istio-egress-ambient targeting that ServiceEntry with from-only rules.
  • Identity resolution: Unions owners (host-specific) and participants (remoteGenerated: Anywhere) with SA-first principals and namespace fallback.
  • Safety: Skips SE/AP creation when no identities are resolved to avoid transient allow; uses generation-based purge to remove prior resources (Gateway, ServiceEntry, AuthorizationPolicy).
  • Quality: Deterministic resource names via sanitizeWithLimit(). Ambient constants centralized in istio-resources.ts.

New AP flow (Ambient)

  1. Build per-host desired state from in-memory package map (union of ports/protocols + contributing packages).
  2. Resolve identities (owners + Anywhere participants). If non-empty:
    • Apply shared per-host ServiceEntry (bound to egress waypoint).
    • Apply centralized AuthorizationPolicy with from-only rules and targetRef to the host’s ServiceEntry.
  3. Increment generation and purge prior-gen ambient resources.

Related Issue

Fixes #2064

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Other (security config, docs update, etc)

Steps to Validate

  • uds run test:uds-core-e2e
  • npm run test:unit
  • npm run test-uds-core-upgrade

Manual steps

  • apply these manifests
  • verify central resources
    • kubectl -n istio-egress-ambient get se,ap | grep httpbin # expect ambient-se-httpbin-org, ambient-ap-httpbin-org
  • get pods
    • R=$(kubectl -n ambient-egress-restricted get pod -l app=restricted-curl -o name)
    • A=$(kubectl -n ambient-egress-anywhere get pod -l app=anywhere-curl -o name)
  • curl checks
    • Restricted: kubectl -n ambient-egress-restricted exec -it $R -- sh -c 'curl -s -w " HTTP_CODE:%{http_code}\n" https://httpbin.org' # ALLOW (retry if 503)
    • Restricted: kubectl -n ambient-egress-restricted exec -it $R -- sh -c "curl -s -w ' HTTP_CODE:%{http_code}\n' http://httpbin.org" # DENY
    • Restricted: kubectl -n ambient-egress-restricted exec -it $R -- sh -c 'curl -s -w " HTTP_CODE:%{http_code}\n" https://api.github.com' # DENY
    • Anywhere: kubectl -n ambient-egress-anywhere exec -it $A -- sh -c 'curl -s -w " HTTP_CODE:%{http_code}\n" https://httpbin.org' # ALLOW
    • Anywhere: kubectl -n ambient-egress-anywhere exec -it $A -- sh -c "curl -s -w ' HTTP_CODE:%{http_code}\n' http://httpbin.org" # DENY
    • Anywhere: kubectl -n ambient-egress-anywhere exec -it $A -- sh -c 'curl -s -w " HTTP_CODE:%{http_code}\n" https://api.github.com' # ALLOW (L4 Anywhere)

Checklist before merging

@chance-coleman chance-coleman self-assigned this Dec 4, 2025
@chance-coleman chance-coleman changed the title feat: Centralized Ambient Egress feat: centralized ambient egress Dec 4, 2025
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file came out of a refactor to avoid circular import dependency between egress.ts and istio-resources.ts due to ingress and egress orchestration having been intertwined. Previously resulted in unit-test failures due to the dependency issues.

@chance-coleman chance-coleman marked this pull request as ready for review December 8, 2025 14:44
@chance-coleman chance-coleman requested a review from a team as a code owner December 8, 2025 14:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR centralizes Ambient egress control by creating shared, per-host resources in the istio-egress-ambient namespace. Previously, each package created its own egress resources; now a single ServiceEntry and AuthorizationPolicy per external host is created across all Ambient packages. Identity resolution uses a SA-first principals approach with namespace fallback, combining host owners and "Anywhere" participants. Safety checks prevent transient allow windows by skipping resource creation when no identities are resolved, and generation-based purging removes stale resources.

Key Changes:

  • Centralized per-host ServiceEntry and AuthorizationPolicy in istio-egress-ambient namespace with unified identity resolution (owners + Anywhere participants)
  • New egress-orchestrator.ts separates egress reconciliation logic; remapAmbientEgressResources() merges package maps into per-host resources
  • sanitizeWithLimit() utility ensures deterministic resource naming within Kubernetes limits

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.

Show a summary per file
File Description
test/vitest/network.spec.ts Adds tests for per-host egress isolation in Ambient mode
src/pepr/operator/reconcilers/package-reconciler.ts Calls istioEgressResources() separately; counts unique hosts for AP status
src/pepr/operator/crd/validators/package-validator.ts Allows serviceAccount with remoteGenerated: Anywhere on Egress in Ambient
src/pepr/operator/controllers/utils.ts Adds sanitizeWithLimit() for deterministic name truncation with hash suffix
src/pepr/operator/controllers/network/generators/egress.ts Updates import for ambientEgressNamespace from centralized location
src/pepr/operator/controllers/istio/service-entry.ts Implements generateSharedAmbientServiceEntry() for centralized per-host SE
src/pepr/operator/controllers/istio/service-entry.spec.ts Tests shared Ambient SE generation with waypoint binding and annotations
src/pepr/operator/controllers/istio/istio-resources.ts Centralizes Ambient egress constants; removes legacy istioEgressResources()
src/pepr/operator/controllers/istio/istio-resources.spec.ts Updates mocks and expectations for orchestrator-based egress flow
src/pepr/operator/controllers/istio/egress.ts Adds remapAmbientEgressResources() to merge package maps; defensive null checks
src/pepr/operator/controllers/istio/egress.spec.ts Tests remapping logic for merging ports/protocols and collecting packages
src/pepr/operator/controllers/istio/egress-orchestrator.ts New orchestrator for egress reconciliation; replaces removed function
src/pepr/operator/controllers/istio/egress-ambient.ts Rewrites to create centralized SE/AP with pre-indexed identity resolution
src/pepr/operator/controllers/istio/egress-ambient.spec.ts Comprehensive tests for identity resolution, merging, and fallback scenarios
src/pepr/operator/controllers/istio/defaultTestMocks.ts Adds getPkgListMock for UDSPackage.Get() in tests
src/pepr/operator/controllers/istio/auth-policy.ts Implements generateCentralAmbientEgressAuthorizationPolicy() with targetRef
src/pepr/operator/controllers/istio/auth-policy.spec.ts Tests central AP generation with from-only rules targeting ServiceEntry
src/pepr/operator/controllers/istio/ambient-waypoint.ts Updates import path for centralized ambient constants
docs/reference/configuration/service-mesh/egress.md Updates documentation to reflect centralized per-host SE/AP architecture

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Package spec.network.allow L7 (hostname) rule in one namespace breaks L4 (Anywhere) egress for pods in a different namespace

2 participants