February 9, 2021·6 min read·engineeringistiovirtual-machinesauthorization

Istio 1.9 brings VM integration to beta and adds external authorization

Istio 1.9 advances VM integration while introducing experimental delegation to external authorization services. The release separates established mesh operations from new integration APIs with narrower guarantees.

A service mesh becomes more useful across a mixed estate when it can apply policy to VM workloads as well as containers. That integration also creates more operational dependencies. Istio 1.9 promotes VM integration to beta after work on stability, tests, and documentation, while introducing a separate experimental mechanism for external authorization.

The 9 February release announcement makes ongoing production operation its stated focus. It emphasizes stability and upgrades, and it distinguishes feature status instead of presenting every capability as equally mature. VM integration is beta, Kubernetes Gateway API support is alpha, and the new external authorization action is experimental.

I find workload identity a sound foundation for mesh policy, but operating the control plane and its proxies has a real cost. Broader integration is useful when it reduces inconsistent policy across workloads. The maturity labels matter because they describe how much API change an operator may still need to absorb.

VM integration addresses consistency across workload types

The release describes VM integration as a way to apply consistent policy and collect telemetry across containers and VMs. Promoting it to beta follows work on its tests, documentation, and stability. That is a specific status change, unlike a patch that merely improves one registration path.

The 1.9 change notes also identify a multicluster registration capability. WorkloadEntry resources can be read from all clusters, avoiding duplication and making VM auto-registration compatible with multi-primary multicluster installations.

That capability is disabled by default. The notes identify PILOT_ENABLE_CROSS_CLUSTER_WORKLOAD_ENTRY as the istiod environment variable used to enable it. The distinction matters because the beta status of VM integration does not imply that every related multicluster option is automatically active.

The notes also separate DNS capture from automatic ServiceEntry address allocation. The new experimental DNS_AUTO_ALLOCATE proxy option controls address allocation independently of DNS_CAPTURE. An operator can enable DNS capture without automatically allocating ServiceEntry addresses.

These are different concerns within one integration. Registration describes the workload to the mesh, and DNS behavior determines how a workload resolves service names. Treating VM integration as a single switch would conceal those configuration choices.

External authorization handles policy that Istio cannot express locally

Istio's built-in authorization rules cannot represent every organization's access-control system. The external authorization design explanation published with 1.9 describes users with existing in-house systems and users integrating products such as OPA or an OAuth2 proxy.

Previously, those integrations could require lower-level Envoy configuration. Istio 1.9 introduces CUSTOM as an AuthorizationPolicy action. The policy selects requests for delegation to an external service, while a named provider in mesh configuration defines how the proxy reaches that service.

At runtime, the proxy sends a check request to the external authorizer. If it denies the request, the proxy rejects it. If it allows the request, local ALLOW and DENY policies still apply. External approval is therefore one stage of the access decision.

That ordering is consequential. An external service can approve a request without overriding a local restriction. The integration does not give the external authorizer a universal bypass around every other authorization policy attached to the workload.

A policy can also make delegation conditional. The example in the design explanation selects requests under an administrative path, avoiding a check for traffic outside that match. This connects request selection to the same rule structure already used by authorization policy.

Provider configuration and request selection are separate

The following example selects an ingress gateway and delegates requests beneath /admin/. It follows the 1.9 API and assumes the selected gateway uses the indicated label.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: administrative-authorization
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: CUSTOM
  provider:
    name: administrative-authorizer
  rules:
    - to:
        - operation:
            paths: ["/admin/*"]

The provider name must refer to a mesh-config entry. A corresponding fragment can use Envoy's gRPC external authorization protocol:

extensionProviders:
  - name: administrative-authorizer
    envoyExtAuthzGrpc:
      service: ext-authz.istio-system.svc.cluster.local
      port: 9000

This is a mesh-configuration fragment, not a standalone Kubernetes resource. It assumes an external authorization service already exists at that destination and implements the expected protocol. Declaring the provider does not deploy its server or supply its decision logic.

The separation lets a policy refer to an administratively defined service by name. Request selection lives with AuthorizationPolicy, while connection details live in mesh configuration. Both are required for the intended delegation.

The design also supports an HTTP authorization interface. Its deployment options include a service in the mesh, a service outside the mesh, or a separate container beside the workload. The selected arrangement determines how the authorization service itself is operated and reached.

Experimental means the constraints are part of the design

The external authorization post explicitly warns that the API can change incompatibly. Its 1.9 rules do not support authentication fields such as source principal or JWT claims when used with the CUSTOM action. Only one external provider is permitted for a given workload.

Different workloads can use different providers. That flexibility does not remove the per-workload limit. A design requiring multiple external decisions on the same workload needs to account for this constraint instead of assuming that several provider names can be combined freely.

The external service also becomes part of request processing. The proxy must send it a check when a policy match requires delegation. Availability and connection configuration for that service therefore affect the system beyond merely installing a new policy object.

The design explanation says administrators should verify the authorizer is running. It also describes using PeerAuthentication to enable mTLS where the authorizer has a proxy. That protects the connection using mesh mechanisms, while the authorization service remains responsible for its own decision.

My preference is to keep these responsibilities explicit. Istio selects and enforces the external check, but it does not make an arbitrary authorization server correct by placing it behind a provider name. The application of local policy after external approval is a useful, concrete boundary.

Gateway API support has a different purpose

Kubernetes Gateway API support enters alpha in 1.9. The release describes it as a way to configure service exposure using APIs shared with other implementations. Its value is in common configuration concepts across products, not in replacing every Istio-specific capability at once.

The announcement identifies ongoing cooperation with Kubernetes SIG Network. That makes the API an integration under active development. It should not be interpreted as a complete compatibility promise for every gateway configuration a cluster already uses.

This is another reason the release's status distinctions matter. A beta VM integration, an alpha gateway interface, and an experimental authorization action represent different levels of readiness. Their inclusion in one release does not merge those statuses.

Distribution and telemetry receive operational changes

The project now mirrors its images on gcr.io/istio-release in response to Docker Hub rate limits. Docker Hub remains the default, so using the mirror requires selecting the alternative hub during installation. The mirror supplies another distribution route without changing the meaning of the installed mesh configuration.

The change notes also add source_cluster and destination_cluster labels to Prometheus metrics by default for all scenarios. Previously, those labels were enabled only for multicluster scenarios. This makes cluster identity available in the reported metric dimensions without depending on that earlier scenario distinction.

Default access logs for proxies at version 1.9 or newer include response-code details and connection-termination details. Those fields can distinguish outcomes that a status code alone leaves ambiguous. They are diagnostic inputs, so they complement installation checks without establishing that the underlying application request was correct.

These changes address separate operating tasks. Image retrieval affects getting the mesh installed, while metric and log fields affect interpreting its traffic after installation.

Operational tooling supports the integrations

The release adds installation verification improvements and annotation analysis. The change notes describe control-plane health verification through --verify with installation or upgrade, and analysis for deprecated or alpha annotations.

It also adds an injector-listing command that shows namespaces with injection and, for control-plane canaries, the injectors and namespaces they control. That information is relevant to upgrades because installed control planes and the workloads selected for their proxies need to be understood separately.

The release announcement lists Kubernetes 1.17 through 1.20 as its supported versions. That boundary provides the platform context for the new integrations. A feature description alone does not establish support on an arbitrary Kubernetes version.

Istio 1.9 consequently advances two kinds of work at different speeds. VM integration gains beta status based on stabilization effort, while external authorization gains an explicit policy API with experimental limits. Operators can evaluate each contract directly instead of treating every integration as equally established.