AI Pilot — mTLS Enforcement

Audience: Security architects, platform engineers Time: ~6 min read

AI Pilot can enforce mutual TLS on the AI tier — the bouncer presents a SPIRE-issued SVID to every selected upstream and refuses to connect on any other path.

When to enforce mTLS

Upstream typeRecommended?Notes
Internal LLM endpoints (self-hosted models)strongly recommendedPairs with workload identity
MCP servers (internal)strongly recommendedStops untrusted clients from impersonating MCP traffic
RAG servicesstrongly recommendedEmbeddings/contexts often contain sensitive data
Internal APIs called by AI agentsstrongly recommendedThe classic Zero Trust path
External LLM providers (OpenAI, Anthropic, etc.)not applicableProviders terminate TLS server-side; bouncer uses standard TLS + bearer/api-key

Configure

Open Settings -> AI Pilot -> mTLS and toggle which upstream classes require it:

mtls_enforcement:
  required_for: ["llm-internal", "mcp", "rag", "api"]
  trust_bundle_ref: spire-trust-bundle
  fallback_action: deny      # deny | warn | allow

The bouncer reads SVIDs from the SPIRE Workload API socket (already provisioned when SPIRE is enabled). The compiler emits a BackendSecurityPolicy carrying the trust-bundle reference.

How identity flows end-to-end

Click to enlarge

The bouncer's identity is spiffe://<trust-domain>/bouncer/<bouncer-id>. Upstream services validate the SVID against the issued trust bundle.

Failure modes

ConditionResult with fallback_action=deny
SPIRE Agent socket missingConnection refused; logs MTLS_AGENT_UNAVAILABLE
Trust bundle expiredConnection refused; logs MTLS_BUNDLE_EXPIRED
Upstream rejects SVIDConnection refused; logs MTLS_PEER_REJECTED

With fallback_action=warn, the bouncer emits the same audit events but allows the connection. Use only during onboarding.

Audit and visibility

  • /pilot Overview tab shows an mTLS enforced badge per bouncer when active.
  • Each upstream backend in /pilot -> Routing & models shows a Cert valid until <ts> field when mTLS is on.
  • Audit events: AI_MTLS_HANDSHAKE_OK, AI_MTLS_HANDSHAKE_FAILED, AI_MTLS_BUNDLE_ROTATED.