Open-Source Wikis

/

Istio

/

Systems

/

Security CA (Citadel)

istio/istio

Security CA (Citadel)

Active contributors: hzxuzhonghu, costinm, ramaraochavali, keithmattix

Purpose

The CA is istiod's certificate authority. It accepts CSRs from workloads (via the per-pod pilot-agent), validates the requestor's identity (Kubernetes service-account JWT or in-mesh mTLS), and signs short-lived workload certificates with SPIFFE-formatted identities.

This subsystem was historically a separate component called Citadel; the name still appears in code paths and metrics. It has been part of istiod since the 1.5 merge.

The architecture document is architecture/security/istio-agent.md.

Directory layout

security/
├── pkg/
│   ├── pki/
│   │   ├── ca/                # IstioCA: signing logic, key/cert handling
│   │   ├── ra/                # Registration Authority: cert-manager bridge
│   │   ├── error/             # Typed CA errors
│   │   └── util/              # Cert helpers (parsing, SAN extraction)
│   ├── server/
│   │   └── ca/                # gRPC CSR server: handles `IstioCertificateService`
│   │       └── authenticate/  # Authenticators: kube JWT, mTLS chain, OIDC
│   ├── nodeagent/             # Per-pod CA *client* (covered in pilot-agent page)
│   ├── credentialfetcher/     # JWT acquisition for non-kube environments
│   ├── monitoring/            # Metrics
│   └── cmd/                   # tools/server packaging helpers
└── tools/                     # generate_cert and other helpers used in tests

Key abstractions

Symbol File Role
IstioCA security/pkg/pki/ca/ca.go The signing engine; owns root + intermediate keys
caserver.Server security/pkg/server/ca/server.go gRPC server implementing IstioCertificateService
authenticate.Authenticator security/pkg/server/ca/authenticate/ Pluggable identity verifiers
kubeauth.KubeJWTAuthenticator security/pkg/server/ca/authenticate/kubeauth/ Verifies projected SA tokens
ra.RegistrationAuthority security/pkg/pki/ra/k8s_ra.go Cert-manager-backed CA delegation
KeyCertBundle security/pkg/pki/util/keycertbundle.go The active root + intermediates + signing key

How it works

sequenceDiagram
    participant Agent as pilot-agent (workload)
    participant Server as caserver.Server
    participant Auth as Authenticator(s)
    participant CA as IstioCA
    participant Bundle as KeyCertBundle

    Agent->>Server: CreateCertificate(CSR, JWT bearer)
    Server->>Auth: Authenticate(stream credentials)
    Note right of Auth: mTLS SAN, JWT TokenReview,<br/>or OIDC chain
    Auth-->>Server: identity (SPIFFE URI)
    Server->>CA: Sign(CSR, identity, TTL)
    CA->>Bundle: load signing key + root chain
    Bundle-->>CA: certs
    CA-->>Server: signed cert + chain
    Server-->>Agent: response (full chain)

Root cert lifecycle

bootstrap.istio_ca.go (in pilot/pkg/bootstrap/) decides where the CA's signing material comes from at startup:

  1. Self-signed default — istiod generates an intermediate signed by a self-signed root. Stored in the cacerts Secret (or a similar secret) and the istio-ca-secret. Suitable for clusters without an external CA.
  2. Operator-provided cacerts — the user provides cacerts Secret with ca-cert.pem, ca-key.pem, cert-chain.pem, and root-cert.pem. Istiod uses the provided intermediate.
  3. External CA via RA — istiod proxies signing to an external CA (cert-manager, Vault) through the Registration Authority (security/pkg/pki/ra/). Istiod doesn't see the raw private key.

The bundle is wrapped in pilot/pkg/keycertbundle/ so it can be hot-reloaded; pkg/filewatcher/ watches the cert-mount paths for rotation events.

Signing path

The CSR signing path is in security/pkg/pki/ca/ca.go. Key steps:

  1. Validate the CSR (key length, SAN extension, CN restrictions).
  2. Build the leaf cert with:
    • The SPIFFE URI as the only SAN (URI:spiffe://<trustdomain>/ns/<ns>/sa/<sa>).
    • A short TTL (default 24h, configurable per request up to a cap).
    • Intermediate signing key.
  3. Return the leaf, intermediates, and the root chain.

Authenticators

The authenticate/ directory implements:

  • kubeauth — projected SA token from the workload's pod. Verified via Kubernetes TokenReview API. The standard production path.
  • xfccX-Forwarded-Client-Cert header authentication for clients reaching istiod through an Envoy proxy.
  • oidc — OIDC-issued JWTs for non-kube environments (VMs).
  • mtls — mTLS client cert chain. Used by ztunnel and existing-mesh workloads renewing their certs.

The set of authenticators accepted is configurable per port (mTLS port 15012 vs the legacy plain-text 15010).

Trust bundle

pilot/pkg/trustbundle/ collects every trusted root in the mesh:

  • The local CA's root.
  • Roots configured via MeshConfig.caCertificates.
  • Cert-manager ClusterTrustBundle resources (when enabled).
  • Roots imported from peer trust domains (multi-cluster federation).

The aggregated bundle is published via SDS as ROOTCA and consumed by Envoy/ztunnel.

Integration points

  • Reads from: Kubernetes Secrets (cacerts, istio-ca-secret), file-mounted bundles, MeshConfig for trust domain and TTLs.
  • Writes to: the gRPC response stream. Optionally writes to Kubernetes Secrets when bootstrapping its own root cert.
  • Talks to: Kubernetes TokenReview API for JWT verification, optional cert-manager CertificateRequest API for RA mode.
  • Metrics: citadel_server_* family — cert_chain_expiry_timestamp, csr_count, success_cert_issuance_count, …

Configuration

Set via IstioOperator (or environment variables on istiod):

Setting Default Purpose
MAX_WORKLOAD_CERT_TTL 24h Cap on requested TTL
DEFAULT_WORKLOAD_CERT_TTL 24h Default if request doesn't specify
TRUST_DOMAIN cluster.local Trust domain for SPIFFE URIs
PILOT_CERT_PROVIDER istiod istiod, kubernetes, cert-manager, or none
EXTERNAL_CA unset When set to ISTIOD_RA_KUBERNETES_API, route signing through cert-manager via the RA

Entry points for modification

  • New authenticator → implement authenticate.Authenticator, register in pilot/pkg/bootstrap/server.go where caserver.NewServer is constructed.
  • New cert format / SAN field → security/pkg/pki/ca/ca.go and security/pkg/pki/util/.
  • External CA integration → security/pkg/pki/ra/. The K8s RA is the canonical example; new providers follow the same shape.

Key source files

File Purpose
security/pkg/pki/ca/ca.go The signer
security/pkg/pki/ra/k8s_ra.go cert-manager RA
security/pkg/pki/util/keycertbundle.go Active root/intermediate state
security/pkg/server/ca/server.go gRPC service implementation
security/pkg/server/ca/authenticate/kubeauth/kube_jwt.go JWT TokenReview
pilot/pkg/bootstrap/istio_ca.go CA setup at istiod start
pilot/pkg/keycertbundle/watcher.go Hot-reload watcher
pilot/pkg/trustbundle/trustbundle.go Aggregated trust bundle

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Security CA (Citadel) – Istio wiki | Factory