Istio — API Surface#
API types#
Istio exposes five distinct API surfaces:
- gRPC — the dominant internal API; xDS ADS is the core control-plane/data-plane protocol
- HTTP — internal debug/monitoring endpoints and Kubernetes admission webhooks
- Kubernetes CRD — the primary user-facing configuration API
- CLI (
istioctl) — operator tooling built on Cobra - Extension / Plugin — pluggable xDS generators and EnvoyFilter patching
gRPC API#
Proto files (in-repo)#
The project defines several internal proto schemas in-repo (not in istio.io/api):
| Proto file | Package | Purpose |
|---|---|---|
pkg/dns/proto/nds.proto | istio.networking.nds.v1 | Name Discovery Service — hostname→IP table pushed to agent DNS proxy |
pkg/workloadapi/workload.proto | istio.workload | Ambient-mode xDS: Address, Workload, Service messages |
pkg/workloadapi/security/authorization.proto | istio.workload | Ambient-mode RBAC policy wire format |
pkg/zdsapi/zds.proto | istio.workload.zds | Ztunnel Discovery Service — CNI-to-ztunnel workload sync protocol |
pkg/test/echo/proto/echo.proto | test only | Test echo service |
Istio’s primary API proto (VirtualService, DestinationRule, etc.) lives in the external istio.io/api module (v1.29.0-alpha.0), not in this repo.
gRPC services registered#
Istiod (pilot-discovery) — port 15010 (plaintext) and 15012 (mTLS)
| Service | Registration | Purpose |
|---|---|---|
AggregatedDiscoveryService (Envoy xDS v3) | pilot/pkg/xds/discovery.go:216 | The core ADS bidirectional streaming service; all resource types (LDS, CDS, RDS, EDS, SDS, NDS, ECDS, PCDS, Workload) multiplexed over a single stream |
IstioCertificateService | security/pkg/server/ca/server.go:189 | Workload certificate issuance (Citadel CA); called by the istio-agent for mTLS cert rotation |
SecretDiscoveryService (SDS) | security/pkg/nodeagent/sds/sdsservice.go:159 | Secret delivery from istio-agent to co-located Envoy; runs in the agent sidecar, not in Istiod |
AggregatedDiscoveryService (istio-agent proxy) | pkg/istio-agent/xds_proxy.go:602 | The agent acts as an ADS proxy: it fronts Envoy and tunnels xDS traffic to Istiod |
Sample external extension service (in samples/)
| Service | Purpose |
|---|---|
envoy.service.auth.v2.Authorization | External authorization gRPC service (ext_authz example) |
envoy.service.auth.v3.Authorization | Same, v3 API |
gRPC interceptors (Istiod)#
Both gRPC servers (plaintext port 15010, mTLS port 15012) use a unary interceptor chain:
grpcprom.UnaryServerInterceptor— Prometheus metrics (request count, latency)- Chain assembled via
grpc.ChainUnaryInterceptorinpilot/pkg/bootstrap/server.go:766–822
The mTLS server (15012) enforces mutual TLS at the transport layer via credentials configured in initSecureDiscoveryService().
HTTP API#
Istiod runs three distinct HTTP/HTTPS listeners:
Port 8080 / 15014 — Admin/monitoring (plaintext)#
Handled by pilot/pkg/bootstrap/monitoring.go and extended by DiscoveryServer.AddDebugHandlers():
| Path | Handler | Auth |
|---|---|---|
/metrics | Prometheus exporter | none (internal) |
/version | Version string | none |
/debug | Index of all debug handlers | JWT or localhost |
/debug/adsz | ADS client status dump | JWT or localhost |
/debug/edsz | EDS snapshot dump | JWT or localhost |
/debug/ndsz | NDS snapshot dump | JWT or localhost |
/debug/ecdsz | ECDS snapshot dump | JWT or localhost |
/debug/syncz | Envoy sync status | JWT or localhost |
/debug/registryz | Service registry dump | JWT or localhost |
/debug/endpointShardz | Endpoint shards info | JWT or localhost |
/debug/cachez | XDS cache statistics/clear | JWT or localhost |
/debug/configz | Istio config dump | JWT or localhost |
/debug/sidecarz | Sidecar scope debug | JWT or localhost |
/debug/resourcesz | Watched resources | JWT or localhost |
/debug/instancesz | Service instances | JWT or localhost |
/debug/ambientz | Ambient mode state | JWT or localhost |
/debug/krtz | krt internal state | JWT or localhost |
/debug/authorizationz | Authorization policies | JWT or localhost |
/debug/telemetryz | Telemetry config | JWT or localhost |
/debug/config_dump | Envoy admin config dump for a proxy | JWT or localhost |
/debug/push_status | Last PushContext details | JWT or localhost |
/debug/pushcontext | Current push context | JWT or localhost |
/debug/connections | Connected XDS clients | JWT or localhost |
/debug/inject | Active inject template | JWT or localhost |
/debug/mesh | Active MeshConfig | JWT or localhost |
/debug/clusterz | Remote clusters | JWT or localhost |
/debug/networkz | Cross-network gateways | JWT or localhost |
/debug/mcsz | Kubernetes MCS services | JWT or localhost |
/debug/list | List all debug endpoints (JSON) | JWT or localhost |
/debug/pprof/* | Go pprof (if profiling enabled) | JWT or localhost |
/debug/force_disconnect | Force-disconnect a proxy (unsafe, flag-gated) | JWT or localhost |
Auth model for debug endpoints: allowAuthenticatedOrLocalhost — requests from 127.0.0.1 pass unconditionally; remote requests must present a valid JWT verified by the configured Authenticator chain (Kubernetes JWT, OIDC, client cert, or XFCC header).
Port 15017 — HTTPS webhook server#
Serves Kubernetes admission webhook callbacks. Registered via httpsMux:
| Path | Handler | Purpose |
|---|---|---|
/inject | pkg/kube/inject/webhook.go:237 | MutatingAdmissionWebhook — sidecar injection |
/inject/<template>/<version>/<namespace> | same handler, routed by path segments | Per-revision/namespace injection variants |
/validate | pkg/webhooks/validation/server/server.go:116 | ValidatingAdmissionWebhook — Istio CRD validation |
/ready | pilot/pkg/bootstrap/server.go:613 | Readiness probe (also remotely accessible) |
Port 15020 — Pilot-agent status server#
Each sidecar agent runs its own HTTP server at port 15020 (istio-agent), handling:
| Path | Purpose |
|---|---|
/healthz/ready | Envoy + agent readiness probe |
/metrics / /stats/prometheus | Merged Prometheus metrics (Envoy + agent) |
/quitquitquit | Graceful agent shutdown (POST) |
/drain | Trigger Envoy drain |
/app-health/<name>/<probe-type> | Proxied app health checks |
/app-lifecycle/<name>/<probe-type> | App lifecycle probes |
/debug/ndsz | NDS state from agent |
/debug/pprof/* | Go pprof (if enabled) |
Kubernetes CRD API (user-facing configuration)#
This is the primary user-facing API for mesh configuration. All CRDs are defined in istio.io/api and reconciled via typed informers in pilot/pkg/config/kube/crdclient/.
Istio networking CRDs (networking.istio.io)#
| CRD | API Version | Purpose |
|---|---|---|
VirtualService | v1 | L7 traffic routing rules (retries, timeouts, fault injection, weighted routing) |
DestinationRule | v1 | Circuit breaking, load balancing, TLS settings per destination cluster |
Gateway | v1 | Ingress/egress gateway configuration |
ServiceEntry | v1 | Register external services in the mesh |
WorkloadEntry | v1 | Register non-Kubernetes workloads (VMs) |
Sidecar | v1 | Scope what a sidecar proxy listens to (egress listener namespacing) |
EnvoyFilter | v1alpha3 | Low-level Envoy config patching (patch operations on listeners, clusters, routes, HTTP filters) |
ProxyConfig | v1beta1 | Per-workload proxy configuration overrides |
Istio security CRDs (security.istio.io)#
| CRD | API Version | Purpose |
|---|---|---|
AuthorizationPolicy | v1 | L4/L7 RBAC — allow/deny rules based on source, destination, conditions |
PeerAuthentication | v1 | mTLS mode per namespace/workload (STRICT, PERMISSIVE, DISABLE) |
RequestAuthentication | v1 | JWT validation rules for workloads |
Telemetry CRD (telemetry.istio.io)#
| CRD | API Version | Purpose |
|---|---|---|
Telemetry | v1 | Configure access logging, metrics, tracing on a per-workload/namespace basis |
Kubernetes Gateway API (standard, gateway.networking.k8s.io)#
Istio implements the upstream Kubernetes Gateway API alongside its own CRDs:
| CRD | Purpose |
|---|---|
GatewayClass | Declares Istio as the gateway implementation |
Gateway (k8s) | Standard gateway resource managed by Istio |
HTTPRoute | HTTP routing rules (Gateway API standard) |
GRPCRoute | gRPC-specific routing |
TCPRoute | L4 TCP routing |
TLSRoute | TLS passthrough routing |
BackendTLSPolicy | TLS config for backends |
ReferenceGrant | Cross-namespace reference permissions |
ListenerSet | (experimental) Reusable listener sets |
InferencePool | (experimental) Kubernetes AI gateway inference pools |
CLI (istioctl)#
- Framework: Cobra + Viper (config from
~/.istioctl/config.yamlandISTIOCTL_*env vars) - Context propagation:
cli.CLIContextwraps kubeconfig, namespace, and istio-namespace; passed through all commands - Global persistent flags:
--istioNamespace(defaultistio-system),--namespace,--kubeconfig,--context, logging flags
Top-level commands#
| Command | Package | Purpose |
|---|---|---|
istioctl inject | istioctl/pkg/kubeinject | Manually inject sidecar into a resource manifest (offline) |
istioctl proxy-config | istioctl/pkg/proxyconfig | Inspect Envoy xDS config for a specific pod (clusters, listeners, routes, endpoints, bootstrap) |
istioctl proxy-status | istioctl/pkg/proxystatus | Check xDS sync status of all or a specific proxy |
istioctl admin | istioctl/pkg/admin | Admin operations on Istiod (log level, reconcile, etc.) |
istioctl analyze | istioctl/pkg/analyze | Static analysis of Istio configuration for misconfigurations |
istioctl validate | istioctl/pkg/validate | Validate Istio YAML manifests |
istioctl manifest | operator/cmd/mesh | Generate Kubernetes manifests for Istio installation |
istioctl install | operator/cmd/mesh | Install Istio in a cluster |
istioctl upgrade | operator/cmd/mesh | Upgrade Istio installation |
istioctl uninstall | operator/cmd/mesh | Remove Istio from a cluster |
istioctl tag | istioctl/pkg/tag | Manage revision tags (stable aliases for Istio revisions) |
istioctl version | istioctl/pkg/version | Print istioctl and control-plane version |
istioctl dashboard | istioctl/pkg/dashboard | Open Kiali, Grafana, Jaeger, Zipkin, Envoy admin UIs in browser |
istioctl waypoint | istioctl/pkg/waypoint | Manage ambient-mode waypoint proxies |
istioctl ztunnel-config | istioctl/pkg/ztunnelconfig | Inspect ztunnel configuration (ambient mode) |
istioctl bug-report | tools/bug-report/pkg/bugreport | Collect diagnostics for a bug report |
istioctl create-remote-secret | istioctl/pkg/multicluster | Generate a remote secret for multi-cluster federation |
istioctl clusters | istioctl/pkg/proxyconfig | List remote clusters in a multi-cluster mesh |
istioctl validate | istioctl/pkg/validate | Validate Istio config files against the schema |
Experimental subcommands (istioctl experimental / istioctl x)#
| Command | Purpose |
|---|---|
x authz | Check authorization policy evaluation for a request |
x metrics | Print service-level metrics (p50, p99, success rate) |
x describe | Describe how a pod/service is affected by mesh policy |
x config | Manage istioctl config file |
x workload | Commands for VM/non-Kubernetes workload onboarding |
x internal-debug | Call Istiod internal debug endpoints directly |
x precheck | Pre-flight checks before install/upgrade |
x stats | Envoy stats configuration |
x check-inject | Diagnose why injection is or is not happening for a pod |
x injector | List sidecar injector webhooks |
Flag patterns: Cobra persistent flags at root level for namespace/kubeconfig; individual commands bind additional flags locally. Viper provides env-var overriding via ISTIOCTL_ prefix. Shell completion is registered for namespace flags.
Extension / Plugin system#
XdsResourceGenerator interface#
The core extension point for Istiod’s xDS generation pipeline:
// pilot/pkg/model/context.go:290
type XdsResourceGenerator interface {
Generate(proxy *Proxy, w *WatchedResource, req *PushRequest) (model.Resources, model.XdsLogDetails, error)
}
type XdsDeltaResourceGenerator interface {
XdsResourceGenerator
GenerateDeltas(proxy *Proxy, req *PushRequest, w *WatchedResource) (model.Resources, model.DeletedResources, model.XdsLogDetails, bool, error)
}Registered in DiscoveryServer.Generators as a map[string]model.XdsResourceGenerator keyed by xDS type URL. Adding a new xDS type (e.g., a custom extension) requires only registering a new generator — no changes to the push loop. This is how Ambient mode’s Workload, PCDS, and workload address generators were added alongside the classic LDS/CDS/RDS/EDS generators.
EnvoyFilter CRD — user-level extension#
EnvoyFilter is the primary user-facing extension mechanism. It allows operators to patch Envoy proxy configuration at predefined extension points using patch operations (MERGE, ADD, INSERT_BEFORE, INSERT_AFTER, REMOVE, REPLACE) on:
HTTP_FILTER— add/remove/reorder HTTP filter chain entries (e.g., add Lua, Wasm, ext_authz)NETWORK_FILTER— patch TCP filter chainsCLUSTER— modify cluster properties (circuit breakers, endpoints)LISTENER— modify listener propertiesROUTE_CONFIGURATION/VIRTUAL_HOST/HTTP_ROUTE— modify routing tables
Implemented in pilot/pkg/networking/core/envoyfilter/.
ECDS (Extension Config Discovery Service)#
Istiod serves ECDS resources for dynamic Wasm extension delivery. The ECDS generator allows Wasm plugins to be loaded/unloaded without an Envoy restart. The WasmPlugin resource (in istio.io/api/extensions/v1alpha1) declares Wasm plugin URLs and their configuration; Istiod translates these to ECDS TypedExtensionConfig resources pushed to Envoy.
authn/authz networking plugins#
Internal plugin interfaces in pilot/pkg/networking/plugin/ allow the Istiod config generator to compose authentication and authorization configuration into listener filter chains:
authnplugin (pilot/pkg/networking/plugin/authn/) — generates mTLS/JWT filter chains fromPeerAuthenticationandRequestAuthenticationauthzplugin (pilot/pkg/networking/plugin/authz/) — generates RBAC filter config fromAuthorizationPolicy
These are internal plugins, not a public extension point. Third parties cannot add new networking plugins without modifying Istiod source.
Authenticator interface (control-plane auth extensibility)#
// pkg/security/security.go:389
type Authenticator interface {
Authenticate(ctx AuthContext) (*Caller, error)
AuthenticatorType() string
}Implementations: KubeJWTAuthenticator (Kubernetes JWT), JwtAuthenticator (OIDC), ClientCertAuthenticator (client cert), XfccAuthenticator (XFCC header for gateway-to-istiod). The chain is used to authenticate both xDS clients (proxies connecting to ADS) and requests to debug HTTP endpoints.
ZDS protocol — CNI/ztunnel extension interface#
The zds.proto protocol (pkg/zdsapi/) defines the binary API between the Istio CNI node agent and ztunnel (Rust). This is an internal, versioned protocol that enables CNI to pass workload netns file descriptors to ztunnel, allowing transparent traffic redirection in ambient mode without sidecars.
Library API#
Istio does not publish a stable Go library API for external consumption. The module (istio.io/istio) is a monorepo of binaries and internal packages; go get of internal packages is not supported or versioned for external use. The intended library API surface lives in the separate istio.io/api and istio.io/client-go modules, which expose:
- Proto-generated Go types for all Istio CRDs
- Typed Kubernetes clients for Istio resources
The pkg/kube/krt package (Collection[T], Singleton[T]) is the one sub-library that shows signs of potential external adoption, but it carries no stability promise.
Notable API design observations#
xDS as the universal internal bus: Every communication channel between Istiod and data-plane components (Envoy, ztunnel, istio-agent) uses either the xDS ADS protocol or a specialized variant (SDS, NDS, PCDS, Workload API). This means Istiod’s gRPC API is effectively the entire internal control API; HTTP is only for humans (debug/webhooks).
Dual CRD strategy: Istio supports both its own CRDs (
networking.istio.io,security.istio.io) and the upstream Kubernetes Gateway API simultaneously. The same reconciliation path handles both, with Gateway API resources translated to Istio’s internal model. This is explicitly a migration strategy — Gateway API is the future, Istio CRDs are maintained for backward compatibility.EnvoyFilter as an escape hatch: The
EnvoyFilterCRD is both the most powerful and most dangerous part of the API. It operates at the Envoy config level, below Istio’s abstraction layer. Istio provides no stability guarantees for the generated Envoy config it patches, makingEnvoyFilterupgrade-sensitive.istioctl as the operator’s window into the mesh: Unlike most control planes, Istiod has no management REST API. All operator interactions happen through
istioctl, which talks to Kubernetes (for CRDs), to the Istiod debug endpoints (for state inspection), and directly to Envoy admin APIs (for per-pod proxy introspection). The debug endpoints on port 15014 serve the same role that a management API would in other systems.No external plugin loading: Despite having an internal generator plugin map, Istiod has no mechanism for loading external plugins at runtime (no
go-plugin, no WASM for control-plane code). Extension happens through the Kubernetes CRD API (EnvoyFilter,WasmPlugin) or by forking and recompiling Istiod.