Service mesh
Dwara can run as a service mesh sidecar, co-located with each service instance, providing identity, mTLS, and policy for east-west traffic between services in the same way it provides them for north-south traffic at the edge. In sidecar mode the gateway is the network for the services it fronts: every call between meshed services flows through a pair of gateways (outbound from the caller, inbound at the callee), each enforcing policy and presenting a verifiable identity.
Implementation status
Mesh is config-accepted, runtime stubbed (Enterprise only). The config schema (MeshConfig, MeshSidecarConfig, MeshSpiffeConfig) parses and validates, and the SidecarController and SpiffeClient types exist, but the runtime is scaffolded: install_redirects() is a documented no-op (no iptables/TPROXY rules), and the gRPC GrpcWorkloadApi returns WorkloadApiUnreachable (the SPIRE Workload API client is not yet wired). The spiffe crate will be added when the integration is production-ready. Until then, use the edge gateway for north-south traffic and an external mesh (Istio, Linkerd) for east-west.
When to use this
Use sidecar mode when east-west traffic between your services needs the same authn, authz, mTLS, and observability the gateway gives north-south traffic, and you want it without a separate control plane or a different proxy. The same binary, config grammar, and policy chain that run at the edge run beside each service -- one tool to learn, one config to author. For a single-service deployment or a cluster where east-west trust is handled elsewhere, the edge gateway alone is enough; the mesh block is for the multi-service case.
Configuration
Add a mesh block under gateway. It is optional and off by default.
gateway:
mesh:
mode: sidecar
identity:
spiffe:
trust_domain: example.com
workload_id: ns/api/svc/api-server
cert:
spiffe_bundle_endpoint: https://spire.example.com:8443
rotation_interval: 1h
mtls:
required: true
client_verification: spiffe
trusted_ca_file: /etc/dwara/spiffe-bundle.pem
policy:
enforce: true
rules: /etc/dwara/mesh-policy.yamlSPIFFE identity
Each sidecar presents a SPIFFE (a framework for cryptographic workload identity, independent of network location) identity to its peers: a SPIFFE Verifiable Identity Document (SVID) issued by a trust domain, naming the workload it represents. The workload_id is the SPIFFE ID this sidecar presents; the trust_domain is the SPIFFE trust domain it belongs to.
SVIDs are fetched from a SPIFFE Bundle Endpoint (typically a SPIRE server) named by spiffe_bundle_endpoint, and rotated on rotation_interval. The gateway never holds a long-lived key -- it rotates the SVID before it expires, so a compromised sidecar's identity is short-lived and revocable. The trust bundle (trusted_ca_file) is the SPIFFE bundle the gateway uses to verify peer SVIDs; it is refreshed from the same endpoint. For running Dwara against a real SPIRE deployment, see SPIFFE/SPIRE workload identity; for kernel-level traffic steering without sidecars at all, see the eBPF hooks research spike.
mTLS
With mtls.required: true, every outbound connection the sidecar opens and every inbound connection it accepts must complete mTLS using the SVID. A peer that does not present a valid SVID from the configured trust domain is rejected at the TLS handshake -- the request never reaches the service.
client_verification: spiffe tells the gateway to verify the peer's SVID against the SPIFFE bundle and to extract the peer's SPIFFE ID for policy evaluation. This is stronger than cert-chain verification alone: the gateway checks not just that the cert is valid, but that it names the workload it claims to be, under the trust domain.
Policy
The policy block carries the east-west authorization rules, separate from the route-level authorization that governs north-south clients. rules points at a policy file that maps source SPIFFE IDs to destination routes and verdicts -- "workload ns/checkout/svc/checkout may call ns/payment/svc/payment on POST /charge, and nothing else." With enforce: true, a call that does not match an allow rule is denied with 403 at the sidecar; with enforce: false, the decision is logged but the call proceeds -- useful for shadow-rolling out mesh policy.
Sidecar vs edge
The mesh block does not replace the edge gateway; it extends the same gateway binary into the east-west path. A typical deployment runs one edge gateway per cluster entry point (north-south) and one sidecar per service instance (east-west), all reading from the same config pipeline. The edge gateway's config carries the public-facing routes; each sidecar's config carries the routes for its co-located service plus the mesh block. Both share the config convergence pipeline, so a policy change rolls to edge and sidecars in one publish.
Observability
Mesh decisions surface in /metrics as dwara_mesh_mtls_total{sidecar,outcome} with outcomes handshake_ok, handshake_failed, and svid_rotated, and dwara_mesh_policy_total{src,dst,verdict} for east-west authorization. The SPIFFE IDs of caller and callee are added to the access log, so east-west traffic is attributable to workloads, not just IP addresses -- the foundation of zero-trust service-to-service calls.
Runnable demo
The demos/11-enterprise/ directory in the repository documents service mesh mode and verifies the reverse-proxy baseline (test script: test-09-service-mesh.sh). The category README covers prerequisites and teardown.