- Renamed all directories: OpenHarbor.MCP.* → Svrnty.MCP.* - Updated all namespaces in 179 C# files - Renamed 20 .csproj files and 3 .sln files - Updated 193 documentation references - Updated 33 references in main CODEX codebase - Updated Codex.sln with new paths - Build verified: 0 errors Preparing for extraction to standalone repositories. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
14 KiB
HTTPS/TLS Setup Guide - Svrnty.MCP.Gateway
Purpose: Production-grade HTTPS/TLS configuration for MCP gateway/proxy deployment Audience: DevOps engineers, system administrators Last Updated: 2025-10-19 Version: 1.0.0
Table of Contents
- Overview
- Prerequisites
- Gateway HTTPS Configuration
- Backend Server Connections
- Load Balancer Integration
- TLS Termination Strategies
- Security Headers
- Testing
- Troubleshooting
Overview
Svrnty.MCP.Gateway acts as a reverse proxy/load balancer between MCP clients and servers. It supports multiple TLS termination strategies and secure backend connections.
Architecture Options:
- TLS Termination at Gateway (recommended)
- Client → HTTPS → Gateway → HTTP → Backend Servers
- TLS Passthrough
- Client → HTTPS → Gateway (proxy) → HTTPS → Backend Servers
- End-to-End TLS
- Client → HTTPS → Gateway (HTTPS) → HTTPS → Backend Servers
Security Features:
- Centralized certificate management
- Multiple backend server support with connection pooling
- Circuit breakers and health checks
- Rate limiting and authentication
- Security headers (HSTS, CSP, etc.)
Prerequisites
Development
- .NET 8.0 SDK
- Docker + Docker Compose (optional)
- TLS certificates (dev or production)
Production
- Valid TLS certificate (from CA or Let's Encrypt)
- Load balancer (optional): Nginx, HAProxy, AWS ALB
- Backend MCP servers configured
- Monitoring/logging infrastructure
Gateway HTTPS Configuration
Configuration via appsettings.json
appsettings.Production.json:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:8080"
},
"Https": {
"Url": "https://*:8443",
"Certificate": {
"Path": "/app/certs/gateway.pfx",
"Password": "" // From environment variable
},
"Protocols": "Http1AndHttp2"
}
}
},
"Gateway": {
"BackendServers": [
{
"Name": "mcp-server-1",
"Url": "http://mcp-server-1:5050", // HTTP backend (TLS terminated at gateway)
"HealthCheckPath": "/health",
"MaxConnections": 10
},
{
"Name": "mcp-server-2",
"Url": "http://mcp-server-2:5050",
"HealthCheckPath": "/health",
"MaxConnections": 10
}
],
"LoadBalancing": {
"Strategy": "RoundRobin", // RoundRobin, LeastConnections, or ToolBased
"HealthCheckInterval": "00:00:30",
"CircuitBreaker": {
"FailureThreshold": 5,
"SuccessThreshold": 2,
"Timeout": "00:01:00"
}
},
"Security": {
"RequireHttps": true,
"AllowedOrigins": ["https://app.example.com"],
"RateLimiting": {
"RequestsPerMinute": 100,
"BurstSize": 20
}
}
}
}
Environment Variables
# Certificate password
export KESTREL__CERTIFICATES__DEFAULT__PASSWORD="ProductionSecurePassword"
# Backend server URLs (override config)
export GATEWAY__BACKENDSERVERS__0__URL="https://mcp-server-1.internal:5051"
export GATEWAY__BACKENDSERVERS__1__URL="https://mcp-server-2.internal:5051"
# API keys
export GATEWAY__SECURITY__APIKEY="gateway-api-key"
Backend Server Connections
Option 1: HTTP Backends (TLS Termination at Gateway)
Recommended for: Internal networks, simplified certificate management
{
"Gateway": {
"BackendServers": [
{
"Name": "server-1",
"Url": "http://10.0.1.10:5050", // HTTP only
"HealthCheckPath": "/health"
}
]
}
}
Architecture:
Internet → HTTPS (443) → Gateway (TLS termination) → HTTP → Backend Servers
Pros:
- Single certificate to manage
- Lower backend server CPU usage
- Simpler debugging (plain HTTP)
Cons:
- Backend traffic unencrypted (use private network)
Option 2: HTTPS Backends (End-to-End Encryption)
Recommended for: Security-sensitive deployments, zero-trust networks
{
"Gateway": {
"BackendServers": [
{
"Name": "server-1",
"Url": "https://mcp-server-1.internal:5051",
"HealthCheckPath": "/health",
"TlsOptions": {
"ValidateCertificate": true,
"AllowedCertificateThumbprints": [
"A1B2C3D4E5F6..." // Pin backend certificates
]
}
}
]
}
}
Architecture:
Internet → HTTPS (443) → Gateway (TLS re-encryption) → HTTPS → Backend Servers
Pros:
- End-to-end encryption
- Backend servers independently secured
- Compliance with zero-trust architecture
Cons:
- More certificates to manage
- Higher CPU usage (double TLS)
- More complex troubleshooting
Custom Backend Certificate Validation
Program.cs Configuration:
services.AddHttpClient("BackendClient", client =>
{
client.Timeout = TimeSpan.FromSeconds(30);
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
// Custom certificate validation for backends
handler.ServerCertificateCustomValidationCallback = (request, cert, chain, errors) =>
{
if (errors == SslPolicyErrors.None)
return true;
// Accept specific backend certificates (certificate pinning)
var allowedThumbprints = new[]
{
"A1B2C3D4E5F6...", // Backend server 1
"B2C3D4E5F6A1..." // Backend server 2
};
return cert != null && allowedThumbprints.Contains(cert.Thumbprint);
};
return handler;
});
Load Balancer Integration
Option 1: Gateway Behind Load Balancer (TLS at LB)
Architecture:
Internet → ALB/NLB (TLS) → Gateway (HTTP) → Backends (HTTP/HTTPS)
AWS Application Load Balancer Example:
Target Group:
{
"TargetType": "ip",
"Protocol": "HTTP",
"Port": 8080,
"HealthCheck": {
"Protocol": "HTTP",
"Path": "/health",
"Interval": 30,
"Timeout": 5
}
}
Listener:
{
"Protocol": "HTTPS",
"Port": 443,
"Certificates": [
{
"CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/abc123..."
}
],
"DefaultActions": [
{
"Type": "forward",
"TargetGroupArn": "arn:aws:elasticloadbalancing:..."
}
]
}
Gateway Configuration (HTTP only, LB handles TLS):
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:8080"
}
}
},
"Gateway": {
"Security": {
"RequireHttps": false, // LB enforces HTTPS
"TrustForwardedHeaders": true // Trust X-Forwarded-Proto from ALB
}
}
}
Program.cs - Forward Headers:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
Option 2: Gateway as Primary TLS Termination
Architecture:
Internet → Gateway (TLS) → Backends (HTTP/HTTPS)
Use Cases:
- On-premises deployment
- Direct internet exposure
- Custom routing logic
Configuration:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://*:443",
"Certificate": {
"Path": "/app/certs/gateway.pfx",
"Password": ""
}
}
}
}
}
TLS Termination Strategies
Strategy 1: TLS Termination (Recommended for Most Cases)
Diagram:
Client --HTTPS--> Gateway --HTTP--> Backend Servers
[TLS
Termination]
Benefits:
- Single certificate management point
- Lower backend CPU usage
- Easy to inspect/log traffic
- Simpler troubleshooting
Configuration:
{
"Kestrel": {
"Endpoints": {
"Https": { "Url": "https://*:8443" }
}
},
"Gateway": {
"BackendServers": [
{ "Url": "http://backend:5050" } // HTTP to backends
]
}
}
Strategy 2: TLS Passthrough (Transparent Proxy)
Diagram:
Client --HTTPS--> Gateway --HTTPS--> Backend Servers
[Proxy Only,
No TLS
Termination]
Benefits:
- End-to-end encryption
- Gateway never sees decrypted traffic
- Backend servers control TLS config
Limitations:
- Cannot inspect traffic
- Cannot do intelligent routing based on content
- More complex certificate management
Not Recommended for MCP Gateway (requires layer 7 routing)
Strategy 3: TLS Re-encryption (Maximum Security)
Diagram:
Client --HTTPS--> Gateway --HTTPS--> Backend Servers
[TLS Termination
+ Re-encryption]
Benefits:
- Can inspect/route traffic
- End-to-end encryption
- Zero-trust architecture
Configuration:
{
"Kestrel": {
"Endpoints": {
"Https": { "Url": "https://*:8443" }
}
},
"Gateway": {
"BackendServers": [
{ "Url": "https://backend:5051" } // HTTPS to backends
]
}
}
Security Headers
Add to Program.cs:
app.Use(async (context, next) =>
{
// HSTS (HTTP Strict Transport Security)
context.Response.Headers.Add("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");
// Content Security Policy
context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self'");
// X-Frame-Options (prevent clickjacking)
context.Response.Headers.Add("X-Frame-Options", "DENY");
// X-Content-Type-Options (prevent MIME sniffing)
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
// Referrer Policy
context.Response.Headers.Add("Referrer-Policy", "strict-origin-when-cross-origin");
// Permissions Policy
context.Response.Headers.Add("Permissions-Policy", "geolocation=(), microphone=(), camera=()");
await next();
});
// Redirect HTTP to HTTPS
if (!app.Environment.IsDevelopment())
{
app.UseHttpsRedirection();
app.UseHsts();
}
Testing
1. Test Gateway HTTPS Endpoint
# Health check
curl https://gateway.example.com/health
# Expected output
{
"status": "Healthy",
"service": "MCP Gateway",
"backends": [
{
"name": "mcp-server-1",
"healthy": true,
"lastCheck": "2025-10-19T12:00:00Z"
}
]
}
2. Test MCP Tool Invocation Through Gateway
curl -X POST https://gateway.example.com/mcp/invoke \
-H "Content-Type: application/json" \
-H "X-API-Key: gateway-api-key" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "search_documents",
"arguments": {
"query": "test"
}
},
"id": "1"
}'
3. Verify TLS Configuration
# Check TLS version and cipher suites
nmap --script ssl-enum-ciphers -p 8443 gateway.example.com
# Check certificate
echo | openssl s_client -connect gateway.example.com:8443 -servername gateway.example.com 2>/dev/null | openssl x509 -noout -text
4. Test Load Balancing
# Send multiple requests, verify distribution
for i in {1..10}; do
curl -s https://gateway.example.com/health | jq -r '.backend'
done
# Should see round-robin distribution across backends
5. Test Circuit Breaker
# Stop one backend server
docker stop mcp-server-1
# Verify gateway routes to healthy server
curl https://gateway.example.com/health
# Should show mcp-server-2 only
Troubleshooting
Issue: "Unable to configure HTTPS endpoint"
Symptoms:
System.InvalidOperationException: Unable to configure HTTPS endpoint
Solution:
- Verify certificate file exists
- Check password is correct
- Ensure certificate is PFX format
# Verify PFX
openssl pkcs12 -info -in gateway.pfx -noout
Issue: Gateway Cannot Connect to Backend Servers
Symptoms:
All backends unavailable
Circuit breaker: OPEN
Solution:
- Check backend server URLs
- Verify network connectivity
- Check firewall rules
# Test backend connectivity from gateway container
docker exec gateway-container curl http://mcp-server-1:5050/health
Issue: Clients Receive "Certificate Invalid"
Symptoms: Clients reject gateway certificate.
Solution:
- Ensure certificate CN/SAN matches gateway domain
- Verify certificate is from trusted CA
- Check certificate not expired
# Check certificate details
openssl x509 -in gateway.crt -noout -text | grep -A1 "Subject Alternative Name"
Issue: Slow Response Times
Symptoms: High latency through gateway.
Solution:
- Check backend server performance
- Increase connection pool size
- Enable HTTP/2
{
"Gateway": {
"BackendServers": [
{
"MaxConnections": 50 // Increase from 10
}
]
},
"Kestrel": {
"Endpoints": {
"Https": {
"Protocols": "Http1AndHttp2" // Enable HTTP/2
}
}
}
}
Production Deployment Checklist
- Valid TLS certificate from trusted CA
- Certificate includes full chain
- Private key secured (Kubernetes secret, vault, etc.)
- HSTS header enabled
- HTTP → HTTPS redirect configured
- Backend server health checks working
- Circuit breakers configured
- Connection pooling optimized
- Security headers configured
- Rate limiting enabled
- Monitoring/alerting set up
- Certificate expiry monitoring configured
- Load testing completed
- Firewall rules configured
- TLS 1.2+ enforced
References
Svrnty.MCP Documentation:
ASP.NET Core Documentation:
Load Balancers:
Document Version: 1.0.0 Last Updated: 2025-10-19 Maintained By: Svrnty Development Team Related: Server HTTPS Setup, Client HTTPS Setup