Istio Guardrails
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 →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 GitHubIstio 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: STRICTNo AuthorizationPolicy defined — mTLS authenticates workloads but does not authorize themGateway istio-system/ingress server on port 80 serves plaintext — set httpsRedirect: true or use TLSNamespace bookinfo runs mesh workloads but sidecar injection is not enabled
Remediation
When this policy fails, resolve it by:
- For
validfailures: Fix the Istio resource flagged byistioctl analyze(bad host, missing subset, malformed selector). - For
mtls-strictfailures: Create aPeerAuthenticationnameddefaultin the Istio root namespace (usuallyistio-system) withspec.mtls.mode: STRICT, and remove any PERMISSIVE/DISABLE overrides. Workloads that must accept plaintext (e.g. during migration) can be scoped out viainclude/excludeinlunar-config.yml. - For
authorization-policies-definedfailures: Add anAuthorizationPolicy— start with a namespace default-deny ({}) plus explicit ALLOW rules for expected callers. - For
no-permissive-authzfailures: Addfrom/to/whenconstraints to the flagged ALLOW rule so it no longer matches every source, or split it into scoped rules. - For
gateway-tlsfailures: Add atlsblock to HTTPS/TLSGatewayservers, and settls.httpsRedirect: trueon plain HTTP servers so ingress never serves plaintext. - For
sidecar-injectionfailures: Label the namespace withistio-injection=enabled(or the revision labelistio.io/rev=<rev>), and removesidecar.istio.io/inject: "false"from workloads that should join the mesh. - For
no-envoy-filter(advisory): Review eachEnvoyFilter; migrate to a supported Istio API where possible, or accept the upgrade risk. Pinenforcement: report-prto 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.
Common Use Cases
Explore how individual guardrails work with specific integrations.
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.