Istio — API Surface#

API types#

Istio exposes five distinct API surfaces:

  1. gRPC — the dominant internal API; xDS ADS is the core control-plane/data-plane protocol
  2. HTTP — internal debug/monitoring endpoints and Kubernetes admission webhooks
  3. Kubernetes CRD — the primary user-facing configuration API
  4. CLI (istioctl) — operator tooling built on Cobra
  5. 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 filePackagePurpose
pkg/dns/proto/nds.protoistio.networking.nds.v1Name Discovery Service — hostname→IP table pushed to agent DNS proxy
pkg/workloadapi/workload.protoistio.workloadAmbient-mode xDS: Address, Workload, Service messages
pkg/workloadapi/security/authorization.protoistio.workloadAmbient-mode RBAC policy wire format
pkg/zdsapi/zds.protoistio.workload.zdsZtunnel Discovery Service — CNI-to-ztunnel workload sync protocol
pkg/test/echo/proto/echo.prototest onlyTest 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)

ServiceRegistrationPurpose
AggregatedDiscoveryService (Envoy xDS v3)pilot/pkg/xds/discovery.go:216The core ADS bidirectional streaming service; all resource types (LDS, CDS, RDS, EDS, SDS, NDS, ECDS, PCDS, Workload) multiplexed over a single stream
IstioCertificateServicesecurity/pkg/server/ca/server.go:189Workload certificate issuance (Citadel CA); called by the istio-agent for mTLS cert rotation
SecretDiscoveryService (SDS)security/pkg/nodeagent/sds/sdsservice.go:159Secret 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:602The agent acts as an ADS proxy: it fronts Envoy and tunnels xDS traffic to Istiod

Sample external extension service (in samples/)

ServicePurpose
envoy.service.auth.v2.AuthorizationExternal authorization gRPC service (ext_authz example)
envoy.service.auth.v3.AuthorizationSame, 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.ChainUnaryInterceptor in pilot/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():

PathHandlerAuth
/metricsPrometheus exporternone (internal)
/versionVersion stringnone
/debugIndex of all debug handlersJWT or localhost
/debug/adszADS client status dumpJWT or localhost
/debug/edszEDS snapshot dumpJWT or localhost
/debug/ndszNDS snapshot dumpJWT or localhost
/debug/ecdszECDS snapshot dumpJWT or localhost
/debug/synczEnvoy sync statusJWT or localhost
/debug/registryzService registry dumpJWT or localhost
/debug/endpointShardzEndpoint shards infoJWT or localhost
/debug/cachezXDS cache statistics/clearJWT or localhost
/debug/configzIstio config dumpJWT or localhost
/debug/sidecarzSidecar scope debugJWT or localhost
/debug/resourceszWatched resourcesJWT or localhost
/debug/instanceszService instancesJWT or localhost
/debug/ambientzAmbient mode stateJWT or localhost
/debug/krtzkrt internal stateJWT or localhost
/debug/authorizationzAuthorization policiesJWT or localhost
/debug/telemetryzTelemetry configJWT or localhost
/debug/config_dumpEnvoy admin config dump for a proxyJWT or localhost
/debug/push_statusLast PushContext detailsJWT or localhost
/debug/pushcontextCurrent push contextJWT or localhost
/debug/connectionsConnected XDS clientsJWT or localhost
/debug/injectActive inject templateJWT or localhost
/debug/meshActive MeshConfigJWT or localhost
/debug/clusterzRemote clustersJWT or localhost
/debug/networkzCross-network gatewaysJWT or localhost
/debug/mcszKubernetes MCS servicesJWT or localhost
/debug/listList all debug endpoints (JSON)JWT or localhost
/debug/pprof/*Go pprof (if profiling enabled)JWT or localhost
/debug/force_disconnectForce-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:

PathHandlerPurpose
/injectpkg/kube/inject/webhook.go:237MutatingAdmissionWebhook — sidecar injection
/inject/<template>/<version>/<namespace>same handler, routed by path segmentsPer-revision/namespace injection variants
/validatepkg/webhooks/validation/server/server.go:116ValidatingAdmissionWebhook — Istio CRD validation
/readypilot/pkg/bootstrap/server.go:613Readiness probe (also remotely accessible)

Port 15020 — Pilot-agent status server#

Each sidecar agent runs its own HTTP server at port 15020 (istio-agent), handling:

PathPurpose
/healthz/readyEnvoy + agent readiness probe
/metrics / /stats/prometheusMerged Prometheus metrics (Envoy + agent)
/quitquitquitGraceful agent shutdown (POST)
/drainTrigger Envoy drain
/app-health/<name>/<probe-type>Proxied app health checks
/app-lifecycle/<name>/<probe-type>App lifecycle probes
/debug/ndszNDS 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)#

CRDAPI VersionPurpose
VirtualServicev1L7 traffic routing rules (retries, timeouts, fault injection, weighted routing)
DestinationRulev1Circuit breaking, load balancing, TLS settings per destination cluster
Gatewayv1Ingress/egress gateway configuration
ServiceEntryv1Register external services in the mesh
WorkloadEntryv1Register non-Kubernetes workloads (VMs)
Sidecarv1Scope what a sidecar proxy listens to (egress listener namespacing)
EnvoyFilterv1alpha3Low-level Envoy config patching (patch operations on listeners, clusters, routes, HTTP filters)
ProxyConfigv1beta1Per-workload proxy configuration overrides

Istio security CRDs (security.istio.io)#

CRDAPI VersionPurpose
AuthorizationPolicyv1L4/L7 RBAC — allow/deny rules based on source, destination, conditions
PeerAuthenticationv1mTLS mode per namespace/workload (STRICT, PERMISSIVE, DISABLE)
RequestAuthenticationv1JWT validation rules for workloads

Telemetry CRD (telemetry.istio.io)#

CRDAPI VersionPurpose
Telemetryv1Configure 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:

CRDPurpose
GatewayClassDeclares Istio as the gateway implementation
Gateway (k8s)Standard gateway resource managed by Istio
HTTPRouteHTTP routing rules (Gateway API standard)
GRPCRoutegRPC-specific routing
TCPRouteL4 TCP routing
TLSRouteTLS passthrough routing
BackendTLSPolicyTLS config for backends
ReferenceGrantCross-namespace reference permissions
ListenerSet(experimental) Reusable listener sets
InferencePool(experimental) Kubernetes AI gateway inference pools

CLI (istioctl)#

  • Framework: Cobra + Viper (config from ~/.istioctl/config.yaml and ISTIOCTL_* env vars)
  • Context propagation: cli.CLIContext wraps kubeconfig, namespace, and istio-namespace; passed through all commands
  • Global persistent flags: --istioNamespace (default istio-system), --namespace, --kubeconfig, --context, logging flags

Top-level commands#

CommandPackagePurpose
istioctl injectistioctl/pkg/kubeinjectManually inject sidecar into a resource manifest (offline)
istioctl proxy-configistioctl/pkg/proxyconfigInspect Envoy xDS config for a specific pod (clusters, listeners, routes, endpoints, bootstrap)
istioctl proxy-statusistioctl/pkg/proxystatusCheck xDS sync status of all or a specific proxy
istioctl administioctl/pkg/adminAdmin operations on Istiod (log level, reconcile, etc.)
istioctl analyzeistioctl/pkg/analyzeStatic analysis of Istio configuration for misconfigurations
istioctl validateistioctl/pkg/validateValidate Istio YAML manifests
istioctl manifestoperator/cmd/meshGenerate Kubernetes manifests for Istio installation
istioctl installoperator/cmd/meshInstall Istio in a cluster
istioctl upgradeoperator/cmd/meshUpgrade Istio installation
istioctl uninstalloperator/cmd/meshRemove Istio from a cluster
istioctl tagistioctl/pkg/tagManage revision tags (stable aliases for Istio revisions)
istioctl versionistioctl/pkg/versionPrint istioctl and control-plane version
istioctl dashboardistioctl/pkg/dashboardOpen Kiali, Grafana, Jaeger, Zipkin, Envoy admin UIs in browser
istioctl waypointistioctl/pkg/waypointManage ambient-mode waypoint proxies
istioctl ztunnel-configistioctl/pkg/ztunnelconfigInspect ztunnel configuration (ambient mode)
istioctl bug-reporttools/bug-report/pkg/bugreportCollect diagnostics for a bug report
istioctl create-remote-secretistioctl/pkg/multiclusterGenerate a remote secret for multi-cluster federation
istioctl clustersistioctl/pkg/proxyconfigList remote clusters in a multi-cluster mesh
istioctl validateistioctl/pkg/validateValidate Istio config files against the schema

Experimental subcommands (istioctl experimental / istioctl x)#

CommandPurpose
x authzCheck authorization policy evaluation for a request
x metricsPrint service-level metrics (p50, p99, success rate)
x describeDescribe how a pod/service is affected by mesh policy
x configManage istioctl config file
x workloadCommands for VM/non-Kubernetes workload onboarding
x internal-debugCall Istiod internal debug endpoints directly
x precheckPre-flight checks before install/upgrade
x statsEnvoy stats configuration
x check-injectDiagnose why injection is or is not happening for a pod
x injectorList 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 chains
  • CLUSTER — modify cluster properties (circuit breakers, endpoints)
  • LISTENER — modify listener properties
  • ROUTE_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:

  • authn plugin (pilot/pkg/networking/plugin/authn/) — generates mTLS/JWT filter chains from PeerAuthentication and RequestAuthentication
  • authz plugin (pilot/pkg/networking/plugin/authz/) — generates RBAC filter config from AuthorizationPolicy

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#

  1. 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).

  2. 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.

  3. EnvoyFilter as an escape hatch: The EnvoyFilter CRD 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, making EnvoyFilter upgrade-sensitive.

  4. 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.

  5. 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.