Connection Security
Riptides secures workload connections at the kernel level. Every TCP connection is evaluated against identity-based policies, and TLS is applied transparently without application changes. This document covers TLS modes, transparent mTLS, TLS handling strategies, and access control policies.
TLS Modes
Section titled “TLS Modes”Each connection between a workload and a service operates in one of three TLS modes, configured on the WorkloadIdentity’s ingress or egress rules:
MUTUAL
Section titled “MUTUAL”Both sides of the connection present X.509 SVIDs and verify each other’s identity. This is the strongest mode and the recommended default for internal service-to-service communication.
Riptides supports TLS 1.2 and TLS 1.3. TLS 1.2 is provided for compatibility with external services; for internal communication between Riptides-managed processes using connection.tls.mode: MUTUAL, the mTLS tunnel is always negotiated with TLS 1.3. With TLS 1.3, Riptides also offers PQC mTLS for internal service-to-service communication.
The kernel module performs the full mTLS handshake transparently. The application sends and receives plaintext; the kernel handles certificate exchange, verification, and encryption.
SIMPLE
Section titled “SIMPLE”Only the server side presents a certificate. The client verifies the server’s identity but does not present its own. Use this for connections to external services that require server authentication but do not support client certificates.
PERMISSIVE
Section titled “PERMISSIVE”Accepts both plaintext and TLS connections on the same port. This mode is useful during migration: workloads that have been enrolled in Riptides will connect over mTLS, while workloads that have not yet been enrolled can still connect over plaintext.
Permissive mode is intended as a transitional step, not a permanent configuration. Once all connecting workloads are enrolled, switch to MUTUAL.
Transparent mTLS
Section titled “Transparent mTLS”Riptides provides transparent mTLS: applications make ordinary plaintext TCP connections, and the kernel module automatically upgrades them to mutual TLS.
This works because the kernel module intercepts connections at the socket level. When a workload opens a connection to a destination that matches an egress rule with connection.tls.mode: MUTUAL, the kernel module:
- Intercepts the TCP handshake.
- Performs a TLS handshake with the remote side, presenting the workload’s X509 SVID.
- Verifies the remote side’s SVID against the loaded trust bundle.
- Encrypts all subsequent traffic using the negotiated session keys.
The application sees a normal TCP connection. It does not need TLS libraries, certificate files, or any awareness that encryption is happening.
On the receiving side, the kernel module on the destination node terminates the mTLS connection, verifies the caller’s SVID, evaluates ingress policies, and delivers plaintext to the application.
TLS Handling Strategies
Section titled “TLS Handling Strategies”The kernel module handles connections differently depending on whether the application is already using TLS:
TLS Intercept
Section titled “TLS Intercept”When connection.tls.intercept is enabled, the kernel module terminates the application’s TLS connection locally, inspects and modifies the HTTP payload, then establishes a new TLS connection to the destination. The daemon evaluates the connection context and, if a credential injection is required, sets a reference in the evaluation context. The kernel checks for this reference and injects the credential before forwarding the request.
TLS Pass-Through
Section titled “TLS Pass-Through”When a connection is already encrypted and no credential injection or policy evaluation at the HTTP layer is needed, the kernel module can wrap the existing encrypted connection in an additional Riptides mTLS layer for identity and policy enforcement. The original TLS payload is not re-encrypted; it passes through intact inside the outer mTLS tunnel.
The kernel module can inspect TLS handshake metadata (such as the ClientHello and ALPN extensions) to make routing and policy decisions without decrypting the payload.
Ingress and Egress Policies
Section titled “Ingress and Egress Policies”Connection policies are defined on WorkloadIdentity resources and control both inbound and outbound connections.
Egress
Section titled “Egress”Egress rules specify which services a workload is allowed to connect to and under what conditions:
spec: egress: - selectors: - tier: backend connection: tls: mode: MUTUAL allowedSPIFFEIDs: - "spiffe://example.com/orders-service" - "spiffe://example.com/inventory-service"- egress[].selectors — Matches destination services by label. See Services.
- egress[].connection.tls.mode — The TLS mode for the connection (MUTUAL, SIMPLE, or PERMISSIVE).
- egress[].allowedSPIFFEIDs — Restricts which SPIFFE IDs the remote service must present. If specified, the connection is only established if the remote side’s SVID matches one of the listed identities.
Ingress
Section titled “Ingress”Ingress rules specify which workloads are allowed to connect to this workload:
spec: ingress: - port: 8000 allowedSPIFFEIDs: - "spiffe://example.com/frontend" - "spiffe://example.com/monitoring"- ingress[].port — The port on which this rule applies.
- ingress[].allowedSPIFFEIDs — Only workloads presenting one of the listed SPIFFE IDs are allowed to connect. Connections from any other identity are rejected at the TLS handshake.
If no allowedSPIFFEIDs are specified, any workload within the trust domain that satisfies the TLS mode requirement can connect.
Connection Flow Example
Section titled “Connection Flow Example”Consider a frontend workload connecting to an internal orders service:
- The frontend application opens a plaintext TCP connection to
orders-service.internal.example.com:8080. - The kernel module intercepts the connection and negotiates with the remote side to establish whether the peer is also a Riptides-managed workload.
- The kernel module initiates an mTLS handshake, presenting the frontend’s SVID (
spiffe://example.com/frontend) and verifying the peer’s SPIFFE SAN. - The kernel module on the orders service node terminates the mTLS connection and checks the ingress policy. The frontend’s SPIFFE ID is in the
allowedSPIFFEIDslist. - The connection is established. Both sides exchange plaintext with their local kernel modules, while the network carries encrypted, mutually authenticated traffic.