Skip to content

Firewall: TLS & Networking

Configure TLS encryption, reverse proxies, and networking modes for the TruthVouch Governance Gateway.

Mutual TLS (mTLS)

Generate Certificates

1. Create CA certificate:

Terminal window
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt \
-subj "/CN=TruthVouch CA"

2. Create server certificate:

Terminal window
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr \
-subj "/CN=gateway.yourcompany.local"
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt

3. Create client certificate:

Terminal window
openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr \
-subj "/CN=client.yourcompany.local"
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt

Enable mTLS in Gateway

Update config.yaml:

security:
mtls_enabled: true
server_cert_path: /app/certs/server.crt
server_key_path: /app/certs/server.key
ca_cert_path: /app/certs/ca.crt
client_auth: require # require, optional, none

Client Configuration

Python:

import grpc
import ssl
# Load certificates
with open('client.crt', 'rb') as f:
client_cert = f.read()
with open('client.key', 'rb') as f:
client_key = f.read()
with open('ca.crt', 'rb') as f:
ca_cert = f.read()
# Create credentials
creds = grpc.ssl_channel_credentials(
root_certificates=ca_cert,
private_key=client_key,
certificate_chain=client_cert
)
# Connect
channel = grpc.secure_channel('gateway.local:50052', creds)

Node.js:

const fs = require('fs');
const grpc = require('@grpc/grpc-js');
const clientCert = fs.readFileSync('client.crt');
const clientKey = fs.readFileSync('client.key');
const caCert = fs.readFileSync('ca.crt');
const credentials = grpc.credentials.createSsl(
caCert,
clientKey,
clientCert
);
const client = new gateway.Gateway(
'gateway.local:50052',
credentials
);

.NET:

var clientCert = new X509Certificate2("client.crt");
var caChain = new X509Chain();
caChain.ChainPolicy.ExtraStore.Add(
new X509Certificate2("ca.crt")
);
var channel = new Channel(
"gateway.local:50052",
new SslCredentials(clientCert, caChain)
);

Reverse Proxy

Nginx Configuration

upstream gateway_backend {
server gateway:50052;
}
server {
listen 443 ssl http2;
server_name gateway.yourcompany.local;
# SSL certificates (obtained from Let's Encrypt or your CA)
ssl_certificate /etc/nginx/certs/gateway.crt;
ssl_certificate_key /etc/nginx/certs/gateway.key;
# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# gRPC settings
location / {
grpc_pass grpcs://gateway_backend;
# Forward headers
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# gRPC timeout settings
grpc_read_timeout 60s;
grpc_send_timeout 60s;
# Client certificate (if using mTLS)
proxy_ssl_certificate /etc/nginx/certs/client.crt;
proxy_ssl_certificate_key /etc/nginx/certs/client.key;
proxy_ssl_trusted_certificate /etc/nginx/certs/ca.crt;
}
# Health check endpoint
location /health {
proxy_pass http://gateway_backend;
proxy_set_header Content-Type application/json;
}
}
server {
listen 80;
server_name gateway.yourcompany.local;
return 301 https://$server_name$request_uri;
}

HAProxy Configuration

global
log stdout local0
log stdout local1 notice
ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384
ssl-default-bind-options ssl-min-ver TLSv1.2
maxconn 4096
defaults
mode tcp
timeout connect 10s
timeout client 60s
timeout server 60s
log global
option tcplog
frontend gateway_frontend
bind 0.0.0.0:50052 ssl crt /etc/haproxy/certs/server.pem
default_backend gateway_backend
backend gateway_backend
balance roundrobin
server gateway1 gateway1:50052 check
server gateway2 gateway2:50052 check
server gateway3 gateway3:50052 check

Service Mesh Integration

Istio Configuration

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: gateway-gateway
namespace: truthvouch
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: gateway-tls
hosts:
- "gateway.yourcompany.local"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: gateway-virtual-service
namespace: truthvouch
spec:
hosts:
- gateway.yourcompany.local
gateways:
- gateway-gateway
http:
- match:
- port: 50052
route:
- destination:
host: gateway.truthvouch.svc.cluster.local
port:
number: 50052
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: gateway-mtls
namespace: truthvouch
spec:
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: gateway-authz
namespace: truthvouch
spec:
selector:
matchLabels:
app: gateway
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/client"]
to:
- operation:
methods: ["POST"]
paths: ["/truthvouch.gateway/*"]

Linkerd Configuration

apiVersion: policy.linkerd.io/v1beta1
kind: Server
metadata:
name: gateway
namespace: truthvouch
spec:
port: 50052
protocol: gRPC
---
apiVersion: policy.linkerd.io/v1beta1
kind: ServerAuthorization
metadata:
name: gateway-authz
namespace: truthvouch
spec:
server:
name: gateway
client:
meshTLS:
identities:
- name: client
namespace: default

Networking Modes

1. Reverse Proxy (Edge)

┌─ Your Network ──────────────────┐
│ │
│ Application ──┐ │
│ │ │
│ Application ──┤──▶ Nginx/LB │
│ │ (443) │
│ Application ──┘ ───────────┬┘
└───────────────────────┬─────────┘
│ :50052 gRPC
Gateway

2. Sidecar Proxy

┌─ Pod ────────────────────┐
│ ┌──────────────────┐ │
│ │ Application │ │
│ │ (localhost:5000)│ │
│ └────────┬─────────┘ │
│ │ │
│ │ localhost:50052
│ ▼ │
│ ┌──────────────────┐ │
│ │ Gateway │ │
│ │ (sidecar) │ │
│ └────────┬─────────┘ │
│ │ :50052 │
└───────────┼──────────────┘
│ Outbound
External LLMs

3. Service Mesh

┌─ Cluster ────────────────────┐
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ App 1 │ │ App 2 │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ ┌────▼─────────────▼─────┐ │
│ │ Service Mesh Control │ │
│ │ (Istio/Linkerd) │ │
│ └────┬─────────────┬─────┘ │
│ │ │ │
│ ▼ ▼ │
│ Gateway-1 Gateway-2 │
│ │
└─────────────────────────────┘
LLM APIs

Load Balancing

Round-robin

# Kubernetes Service
apiVersion: v1
kind: Service
metadata:
name: gateway
spec:
selector:
app: gateway
ports:
- port: 50052
targetPort: 50052
sessionAffinity: None # Round-robin

Session Affinity

sessionAffinity: ClientIP
sessionAffinityConfig:
clientIPConfig:
timeoutSeconds: 10800

Endpoint Monitoring

# Check available endpoints
kubectl get endpoints gateway -n truthvouch

Connection Pooling

gRPC Channel Pooling

Python:

# Reuse channel for multiple calls
channel = grpc.aio.secure_channel(
'gateway.local:50052',
creds,
options=[
('grpc.max_connection_idle_ms', 300000),
('grpc.max_connection_age_ms', 600000),
('grpc.http2.min_time_between_pings_ms', 10000),
('grpc.keepalive_time_ms', 30000),
]
)

Node.js:

const client = new gateway.Gateway(
'gateway.local:50052',
credentials,
{
'grpc.max_connection_idle_ms': 300000,
'grpc.max_connection_age_ms': 600000,
}
);

Monitoring Network Health

Prometheus Metrics

# Connection count
gateway_active_connections
# Request latency percentiles
histogram_quantile(0.95, rate(gateway_request_duration_seconds_bucket[5m]))
# Network errors
rate(gateway_network_errors_total[5m])

Network Diagnostics

Terminal window
# Test connectivity
grpcurl -plaintext localhost:50052 list
# Test with mTLS
grpcurl -cert client.crt -key client.key -cacert ca.crt \
localhost:50052 list
# Check certificate expiration
openssl x509 -in server.crt -noout -dates

See Configuration and Network Requirements for related settings.