Istio Quick Reference

Istio Quick ReferenceChapter 03 of 10

Istio security

As of Istio 1.31 · Edition 2026.11 · Release data checked on 30 October 2026

PeerAuthentication

mTLS mode between sidecars. STRICT, PERMISSIVE, DISABLE. Scope: mesh (in istio-system), namespace, or workload via selector. Migrating to STRICT: first mesh-wide PERMISSIVE, then switch namespace by namespace.

apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata: {name: default, namespace: prod}
spec:
  mtls: {mode: STRICT}
---
# Port exception (spec only, own name): NLB check
spec:
  selector: {matchLabels: {app: legacy}}
  mtls: {mode: STRICT}
  portLevelMtls:
    8080: {mode: PERMISSIVE}

AuthorizationPolicy

L7 access control. Order: CUSTOM (ext authz) → DENY → ALLOW (default action); AUDIT only marks requests for an audit plugin. No ALLOW policy on a workload = allow all. spec: {} (ALLOW, no rules) denies everything; rules: [{}] matches every request. Rules OR, fields in a rule AND. 1.31+: source.trustDomains.

Ambient: without targetRefs (selector or namespace-wide), ztunnel enforces it, L4 only; L7 rules need a waypoint and targetRefs. ztunnel skips L7 attributes: ALLOW with them denies, DENY with only them blocks nothing. Behind a waypoint, the destination ztunnel sees the waypoint’s identity.

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata: {name: reviews-allow, namespace: prod}
spec:
  selector: {matchLabels: {app: reviews}}
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/prod/sa/productpage
    to:
    - operation:
        methods: [GET]
        paths: ["/reviews/*"]
    when:
    - key: request.auth.claims[groups]
      values: ["reader", "admin"]

RequestAuthentication (JWT)

Validates the JWT and fills request.auth.* for the AuthorizationPolicy. Important: without an additional DENY policy with notRequestPrincipals=["*"], unauthenticated requests can still get through. Ambient: attach both to a waypoint via targetRefs; ztunnel ignores this L7-only DENY, so without a waypoint it blocks nothing.

apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata: {name: jwt, namespace: prod}
spec:
  selector: {matchLabels: {app: api}}
  jwtRules:
  - issuer: "https://auth.example.com"
    jwksUri: "https://auth.example.com/jwks"
    audiences: ["api.example.com"]
    forwardOriginalToken: true

Identity

SPIFFE URI spiffe://<trust>/ns/<ns>/sa/<sa>. Trust domain defaults to cluster.local; all clusters of one mesh share it (or list each other in trustDomainAliases), only the cluster name is unique. Workload certs: 24 h TTL (SECRET_TTL), istio-agent renews at half-life (SECRET_GRACE_PERIOD_RATIO=0.5), issued by the istiod CA.