This document describes the internal architecture of Istio agent.
At a high level, the Istio agent acts as an intermediate proxy between Istiod and Envoy. This is done at two levels. For distributing workload certificates, Envoy will send SDS requests to the agent, causing the agent to submit a CSR to the configured CA (generally Istiod). For other configuration, Envoy will send ADS requests to the agent, which will be forwarded to the configured discovery server (general Istiod).
istio-agent checks the presence of a socket file on the defined socket path /var/run/secrets/workload-spiffe-uds/socket
.
/var/run/secrets/workload-spiffe-credentials
. If certificate files are found, istio-agent will start its own SDS Server, listening and serving these certificates on the defined socket path /var/run/secrets/workload-spiffe-uds/socket
, while also keeping file watchers on them. Envoy proxy then connects to istio-agent's SDS Server through the defined socket path and gets the cryptographic materials of the certificate files served by the SDS API.caClient
to connect to istiod or an external CA, to fetch cryptographic materials (See Default CA Flow).A single SDS request from Envoy goes through a few different layers in istio-agent.
SecretManager
to Envoy, without much business logic. For each resource requested by Envoy, the SDS server will call SecretManager.GenerateSecret(resourceName)
GenerateSecret
is called, the SecretManager
is expected to return a new certificate. This can occur in a few ways.SecretManager
also can return a cache response. In practice, this would only happen in cases where Envoy were to re-request a resource, which is fairly rare.SecretManager
can also read certificates from files. When this is configured, no CA client is used.caClient
will be configured to use either JWT or mTLS authentication. For JWT authentication, gRPC's PerRPCCredentials
is configured with a TokenProvider
which handles the logic of adding the proper JWT to each request. mTLS is configured by a tls.Config that points to files on disk.It should be noted there is a circular dependency with mTLS authentication; in order to fetch a certificate we need a certificate. This can be handled in various ways:
GenerateSecret
may additionally write any signed certificates to disk, with OUTPUT_CERTS
configured.Note that OUTPUT_CERTS
can be used to refresh certificates using previously provisioned certificates, by configuring the ca client to use certificates written to the same directory we have configured them to be written to.
The agent supports two forms of authentication with the CA/discovery servers: mTLS and JWT. Varying deployment topologies mix and match these two.
For a standard Kubernetes deployment, both CA and discovery will use JWT authentication, with a token automatically generated and rotated by Kubernetes.
For discovery, the JWT token will be read directly from a file and sent as is. For CA, this logic is a bit more complex, as the support for external CAs is more mature than external discovery servers. This supports some additional configuration, a CredentialFetcher
which allows fetching a token from places other than a file (for example, a local metadata server), and a TokenExchanger
which allows exchanging a token for another form to match the CA server requirements.
For VMs, the standard flow is for the user to provision a short-lived JWT token onto the VM. After the initial CSR, certificates are written to disk and mTLS is used for future requests. If the VM restarted, it would continue to use the certificates written to disk, assuming the downtime is less than certificate expiration. This is why the certificates are persisted to disk, rather than kept in memory like in the standard Kubernetes deployment.
The agent also handles rotating certificates near expiration. It does so by triggering a callback from the SecretManager
to the SDS server when a certificate is near expiration (configurable by SECRET_GRACE_PERIOD_RATIO
, defaulting to half of the expiration). If the SDS server is still interested in this certificate (ie, Envoy is still connected and requesting the certificate), the SDS server will send another request to generate a new secret and push the updated certificate to Envoy. This ensures that we do not permanently watch certificates even after Envoy has stopped requested them; if there are no subscriptions they update will be ignored. If Envoy later watches these certificates again, a new one will be generated on demand.
Variable | Description |
---|---|
CA_ADDR | Address of CA, defaults to discoveryAddress |
CA_PROVIDER | Type of CA; supported values are GoogleCA or Citadel (although anything but GoogleCA will use Citadel); defaults to Citadel |
PROV_CERT | certificates to be used for mTLS communication with control plane only; NOT for workload mTLS |
OUTPUT_CERT | write all fetched certificates to some directory. Used to support applications that need certificates (Prometheus) as well as rotating mTLS control plane authentication. |
FILE_MOUNTED_CERTS | completely disable CA path, exclusively use certs mounted into the pod with set certificate file locations |
CREDENTIAL_FETCHER_TYPE | allows using custom credential fetcher, for VMs with existing identity |
CREDENTIAL_IDENTITY_PROVIDER | just used to control the audience for VMs with existing identity |
PROXY_XDS_VIA_AGENT | use istio-agent to proxy XDS. True for all use cases now, likely can be always-on now or soon |
PROXY_XDS_DEBUG_VIA_AGENT | Offer XDS istio.io/debug API on agent's 15004 HTTP endpoint. (Requires PROXY_XDS_VIA_AGENT) |
{XDS,CA}_ROOT_CA | explicitly configure root certificate path |
PILOT_CERT_PROVIDER | just used to determine XDS/CA root certificate; redundant with {XDS,CA}_ROOT_CA. |