Hamburger Cross Icon
Istio Guardrails - Lunar Policy for Deployment And Infrastructure

Istio Guardrails

Policy Experimental Deployment And Infrastructure

Enforce Istio service-mesh best practices: STRICT mutual TLS, authorization policies in place, no blanket-allow authz rules, TLS on ingress gateways, and sidecar injection on mesh namespaces. Flags brittle EnvoyFilter usage and invalid Istio config.

Add istio to your lunar-config.yml:
uses: github://earthly/lunar-lib/policies/istio@v1.0.5

Included Guardrails

This policy includes 7 guardrails that enforce standards for your deployment and infrastructure.

Guardrail

valid

Validates that all Istio custom resources parse and pass istioctl analyze (run offline). Invalid mesh config can silently drop routing or security rules once applied to the cluster.

istio istioctl analyze validation mesh config yaml
View Guardrail
Guardrail

mtls-strict

Requires mesh-wide mutual TLS to be STRICT. A PeerAuthentication in the Istio root namespace must set mode STRICT, and no namespace or workload PeerAuthentication may downgrade to PERMISSIVE or DISABLE. PERMISSIVE accepts plaintext, so a workload without a sidecar (or an attacker on the pod network) can bypass mesh encryption.

mtls mutual tls peerauthentication strict encryption in transit zero trust
View Guardrail
Guardrail

authorization-policies-defined

Requires at least one AuthorizationPolicy in the mesh. mTLS authenticates workloads but does not authorize them — without an AuthorizationPolicy every authenticated workload can call every other. Establishes a zero-trust authz baseline.

authorizationpolicy authorization zero trust least privilege rbac
View Guardrail
Guardrail

no-permissive-authz

Fails when an AuthorizationPolicy grants blanket access — an ALLOW action with a rule that has no from/to/when constraints (matches every source). Accidental allow-all rules quietly negate the rest of the mesh's authz.

authorizationpolicy allow-all permissive over-permissive least privilege
View Guardrail
Guardrail

gateway-tls

Requires ingress Gateways to terminate or pass through TLS: HTTPS/TLS servers must set a tls config, and plain HTTP servers must set httpsRedirect. Catches ingress that serves plaintext to the internet.

gateway tls https httpsRedirect ingress encryption in transit
View Guardrail
Guardrail

sidecar-injection

Requires namespaces running mesh workloads to have sidecar injection enabled (istio-injection=enabled or an istio.io/rev label) and flags workloads that opt out via sidecar.istio.io/inject: "false". Without the sidecar a workload silently bypasses mesh mTLS, authz, and telemetry.

sidecar injection istio-injection envoy sidecar mesh membership istio.io/rev
View Guardrail
Guardrail

no-envoy-filter

Advisory (info): flags use of EnvoyFilter. EnvoyFilter patches the raw Envoy config and is brittle across Istio upgrades, bypassing the higher-level networking and security APIs. Surfaced so mesh owners can review each use.

envoyfilter envoy technical debt upgrade risk advisory
View Guardrail

How Guardrails Fit into Lunar

Lunar guardrails define your engineering standards as code. They evaluate data collected by integrations and produce pass/fail checks with actionable feedback.

Policies support gradual enforcement—from silent scoring to blocking PRs or deployments—letting you roll out standards at your own pace without disrupting existing workflows.

Learn How Lunar Works
1
Integrations Gather Data
Collectors extract metadata from code, CI pipelines, tool outputs, and scans
2
{ } Centralized as JSON
All data merged into each component's unified metadata document
3
Guardrails Enforce Standards This Policy
Real-time feedback in PRs and AI workflows

Required Integrations

This policy evaluates data gathered by one or more of the following integration(s). Make sure to enable them in your lunar-config.yml.

Configuration

Configure this policy in your lunar-config.yml.

Inputs

Input Required Default Description
required_mtls_mode Optional STRICT Required mesh-wide mTLS mode for the mtls-strict check (STRICT or PERMISSIVE)

Documentation

View on GitHub

Istio Guardrails

Enforces Istio service-mesh security and traffic best practices.

Overview

This policy validates Istio service-mesh configuration against production best practices: STRICT mutual TLS, an authorization baseline, no accidental allow-all rules, TLS on ingress gateways, and sidecar injection on mesh namespaces. It reads the normalized .mesh data produced by the istio collector, so the checks describe mesh posture rather than tool internals. It helps ensure a mesh actually enforces the encryption and access control it was adopted for, instead of quietly running in permissive mode.

Policies

This plugin provides the following policies (use include to select a subset):

Policy Description
valid Validates Istio resources parse and pass istioctl analyze
mtls-strict Requires mesh-wide mTLS in STRICT mode
authorization-policies-defined Requires at least one AuthorizationPolicy
no-permissive-authz Forbids blanket allow-all AuthorizationPolicy rules
gateway-tls Requires ingress Gateways to use TLS / redirect HTTP
sidecar-injection Requires mesh namespaces to enable sidecar injection
no-envoy-filter Advisory: flags brittle EnvoyFilter usage

Required Data

This policy reads from the following Component JSON paths:

Path Type Provided By
.mesh.resources[] array istio collector
.mesh.peer_authentications[] array istio collector
.mesh.authorization_policies[] array istio collector
.mesh.gateways[] array istio collector
.mesh.envoy_filters[] array istio collector
.mesh.injection object istio collector
.mesh.summary object istio collector

Note: Ensure the istio collector is configured before enabling this policy.

Installation

Add to your lunar-config.yml:

policies:
  - uses: github://earthly/lunar-lib/policies/istio@v1.0.0
    on: ["domain:your-domain"]  # Or use tags like [kubernetes, mesh]
    enforcement: report-pr
    # include: [mtls-strict, gateway-tls]  # Only run specific checks
    # with:
    #   required_mtls_mode: "STRICT"

Examples

Passing Example

A component with STRICT mesh mTLS, an authorization policy, and injection enabled:

{
  "mesh": {
    "peer_authentications": [
      {"name": "default", "namespace": "istio-system", "scope": "mesh", "mode": "STRICT"}
    ],
    "authorization_policies": [
      {"name": "require-jwt", "namespace": "bookinfo", "action": "ALLOW", "rule_count": 1, "allows_all": false}
    ],
    "gateways": [
      {"name": "ingress", "namespace": "istio-system", "servers": [{"port": 443, "protocol": "HTTPS", "tls_mode": "SIMPLE"}]}
    ],
    "injection": {
      "namespaces": [{"name": "bookinfo", "enabled": true}],
      "workload_overrides": []
    },
    "summary": {"mtls_strict": true, "has_authorization_policies": true, "all_gateways_tls": true, "injection_enabled": true}
  }
}

Failing Example

A component running permissive mTLS, no authorization, and a plaintext gateway:

{
  "mesh": {
    "peer_authentications": [
      {"name": "default", "namespace": "istio-system", "scope": "mesh", "mode": "PERMISSIVE"}
    ],
    "authorization_policies": [],
    "gateways": [
      {"name": "ingress", "namespace": "istio-system", "servers": [{"port": 80, "protocol": "HTTP", "https_redirect": false}]}
    ],
    "injection": {
      "namespaces": [{"name": "bookinfo", "enabled": false}],
      "workload_overrides": [{"kind": "Deployment", "name": "api", "namespace": "bookinfo", "inject": false}]
    },
    "summary": {"mtls_strict": false, "has_authorization_policies": false, "all_gateways_tls": false, "injection_enabled": false}
  }
}

Failure messages:

  • Mesh mTLS is PERMISSIVE — set a mesh-wide PeerAuthentication with mode: STRICT
  • No AuthorizationPolicy defined — mTLS authenticates workloads but does not authorize them
  • Gateway istio-system/ingress server on port 80 serves plaintext — set httpsRedirect: true or use TLS
  • Namespace bookinfo runs mesh workloads but sidecar injection is not enabled

Remediation

When this policy fails, resolve it by:

  1. For valid failures: Fix the Istio resource flagged by istioctl analyze (bad host, missing subset, malformed selector).
  2. For mtls-strict failures: Create a PeerAuthentication named default in the Istio root namespace (usually istio-system) with spec.mtls.mode: STRICT, and remove any PERMISSIVE/DISABLE overrides. Workloads that must accept plaintext (e.g. during migration) can be scoped out via include/exclude in lunar-config.yml.
  3. For authorization-policies-defined failures: Add an AuthorizationPolicy — start with a namespace default-deny ({}) plus explicit ALLOW rules for expected callers.
  4. For no-permissive-authz failures: Add from/to/when constraints to the flagged ALLOW rule so it no longer matches every source, or split it into scoped rules.
  5. For gateway-tls failures: Add a tls block to HTTPS/TLS Gateway servers, and set tls.httpsRedirect: true on plain HTTP servers so ingress never serves plaintext.
  6. For sidecar-injection failures: Label the namespace with istio-injection=enabled (or the revision label istio.io/rev=<rev>), and remove sidecar.istio.io/inject: "false" from workloads that should join the mesh.
  7. For no-envoy-filter (advisory): Review each EnvoyFilter; migrate to a supported Istio API where possible, or accept the upgrade risk. Pin enforcement: report-pr to keep it non-blocking.

Open Source

This policy is open source and available on GitHub. Contribute improvements, report issues, or fork it for your own use.

View Repository

Ready to Automate Your Standards?

See how Lunar can turn your AGENTS.md, engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 200+ built-in guardrails.

Works with any process
check AI agent rules & prompt files
check Post-mortem action items
check Security & compliance policies
check Testing & quality requirements
Automate Now
Paste your AGENTS.md or manual process doc and get guardrails in minutes
Book a Demo