apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-mcp-ingress
namespace: secure-mcp
labels:
app.kubernetes.io/name: secure-mcp
app.kubernetes.io/component: ingress
annotations:
# NGINX Ingress Controller annotations
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/use-regex: "true"
# Security headers
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Frame-Options: DENY";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "X-XSS-Protection: 1; mode=block";
more_set_headers "Referrer-Policy: strict-origin-when-cross-origin";
more_set_headers "Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';";
more_set_headers "Permissions-Policy: geolocation=(), microphone=(), camera=()";
more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload";
# Rate limiting
nginx.ingress.kubernetes.io/limit-rps: "100"
nginx.ingress.kubernetes.io/limit-burst-multiplier: "2"
nginx.ingress.kubernetes.io/limit-connections: "50"
# Timeouts
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
# WebSocket support
nginx.ingress.kubernetes.io/websocket-services: "secure-mcp-service"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
# CORS configuration
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://app.example.com,https://admin.example.com"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-max-age: "86400"
# ModSecurity WAF
nginx.ingress.kubernetes.io/enable-modsecurity: "true"
nginx.ingress.kubernetes.io/enable-owasp-modsecurity-crs: "true"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecAuditLog /var/log/modsecurity/audit.log
SecAuditLogType Serial
SecAuditEngine RelevantOnly
# Certificate management
cert-manager.io/cluster-issuer: "letsencrypt-prod"
cert-manager.io/acme-challenge-type: "http01"
# Monitoring
nginx.ingress.kubernetes.io/enable-opentracing: "true"
nginx.ingress.kubernetes.io/opentracing-trust-incoming-span: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
- api-staging.example.com
secretName: secure-mcp-tls-cert
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-mcp-service
port:
number: 80
- path: /health
pathType: Exact
backend:
service:
name: secure-mcp-service
port:
number: 80
- path: /metrics
pathType: Exact
backend:
service:
name: secure-mcp-service
port:
number: 9090
- path: /ws
pathType: Prefix
backend:
service:
name: secure-mcp-service
port:
number: 80
- host: api-staging.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-mcp-service
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-mcp-grpc-ingress
namespace: secure-mcp
labels:
app.kubernetes.io/name: secure-mcp
app.kubernetes.io/component: grpc-ingress
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/grpc-backend: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- grpc.example.com
secretName: secure-mcp-grpc-tls-cert
rules:
- host: grpc.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-mcp-service
port:
number: 80