Skip to content

Fix Envoy container failing to start with digest-pinned image - #5973

Closed
ChrisJBurns wants to merge 6 commits into
mainfrom
cburns/transparent-interception
Closed

ChrisJBurns wants to merge 6 commits into
mainfrom
cburns/transparent-interception

Conversation

@ChrisJBurns

Copy link
Copy Markdown
Collaborator

Summary

After #5949 pinned defaultEnvoyImage to tag@digest, the Envoy proxy container failed to start on every fresh run:

Error response from daemon: No such image: envoyproxy/envoy-distroless:v1.32.3@sha256:375aab...

Docker's container create API looks up images by exact reference string. PullImage stores the image under its tag via daemon.Write, so the daemon has no index entry for the full tag@digest string. getEnvoyImageForCreate() strips the @sha256:... suffix before the create call — digest verification already happened at pull time.

Type of change

  • Bug fix

Test plan

  • task build passes
  • Manually verified: all three containers (fetch, fetch-egress, fetch-dns) start successfully and the fetch tool reaches the allowed host through Envoy

Generated with Claude Code

ChrisJBurns and others added 6 commits July 23, 2026 17:50
Splits createContainer into two steps — create-only and start — to enable
transparent interception to install iptables rules in the workload's network
namespace between container creation and startup, eliminating the race where
the workload could make connections before interception is configured.

No behaviour change: all existing callers use createContainer which now
delegates to createContainerStopped + startContainer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extends the networkProxy interface with SetupTransparent(ctx, spec,
workloadContainerID) which installs iptables DNAT rules into the workload's
network namespace before it starts. squidProxy returns a no-op; envoyProxy
delegates to runTransparentInitContainer (stub for Stage 2).

Also adds EnvoyInternalIP and TransparentPort to proxySpec, and updates
fakeNetworkProxy in deploy tests to record SetupTransparent calls.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements the L3/L4 transparent proxy config for the Envoy backend:
- envoyNetworkRBAC types for TCP-layer policy (distinct from HTTP RBAC)
- buildTransparentListener: transparent:true listener on :15001 with
  gateway DENY (destination_ip CIDR — now correct via SO_ORIGINAL_DST)
  and AllowPort ALLOW (destination_port) + TCP proxy to original_dst
- buildOriginalDstCluster: ORIGINAL_DST + CLUSTER_PROVIDED routes
  connections to their real upstream address
- Wired into SetupIngress so all Envoy workloads get the transparent
  listener automatically alongside egress/ingress

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
For isolated workloads, the MCP container is now created-without-start,
transparent interception is installed (iptables DNAT via init container),
and then the workload is started — eliminating the race where the workload
could make connections before interception was in place.

Sequence for isolated path:
  SetupEgress → createMcpContainerStopped → SetupIngress
  → SetupTransparent → startContainer

Also adds E2E tests in network_isolation_envoy_test.go that prove port-
based enforcement: an HTTP server on ports 15432 (postgres-like) and 16379
(redis-like) is blocked when those ports are not in AllowPort, and allowed
when they are. Uses the gateway IP path (Linux Docker Engine only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Envoy's envoy.filters.network.rbac requires stat_prefix to be at least 1
character. The gateway-deny and allow filters were missing this field.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@ChrisJBurns

Copy link
Copy Markdown
Collaborator Author

Closing because CC is for some reason raising the same PR multiple times.

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.

1 participant