Phase 4 - Infrastructure & Kubernetes Hardening
Security Headers
All public-facing services now have security headers applied via Traefik middleware.
Grade Improvement
| Date | Site | Grade | Notes |
|---|---|---|---|
| 04/05/2026 | dev.aliquest.me | F | No headers |
| 04/05/2026 | dev.aliquest.me | D | CSP middleware only |
| 05/05/2026 | dev.aliquest.me | A | All headers live |
Headers Applied
| Header | Value | Purpose |
|---|---|---|
Strict-Transport-Security |
max-age=31536000; includeSubDomains; preload |
Force HTTPS for 1 year |
X-Frame-Options |
DENY |
Prevent clickjacking |
X-Content-Type-Options |
nosniff |
Prevent MIME sniffing |
Referrer-Policy |
strict-origin-when-cross-origin |
Control referrer info |
Permissions-Policy |
camera=(), microphone=(), geolocation=(), payment=(), usb=() |
Restrict browser features |
X-Permitted-Cross-Domain-Policies |
none |
Block cross-domain policies |
Content-Security-Policy |
Per-ingress (app-specific) | Prevent XSS |
Architecture
Global headers (HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) are applied at the Traefik entrypoint level via a global middleware in the traefik namespace.
CSP is managed per-ingress since each application has different resource requirements.
Services Covered
| Service | Middleware Applied |
|---|---|
| dev.aliquest.me | Global + CSP |
| sonar.aliquest.me | Global |
| argo.aliquest.me | Global |
| grafana.aliquest.me | Global |
Remaining Warning
The CSP on dev.aliquest.me contains unsafe-inline in script-src. This is a current limitation of the React frontend. Future improvement: replace unsafe-inline with nonce-based CSP.
Pod Security Context
The frontend deployment now runs with a hardened security context.
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
Container-level restrictions:
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Writable volumes are provided via emptyDir for /tmp and /app/.cache.
Network Policies
Three Network Policies are applied in the aliquest-dev namespace:
| Policy | Effect |
|---|---|
default-deny-all |
Deny all ingress and egress by default |
allow-traefik-to-frontend |
Allow ingress from Traefik namespace only |
allow-frontend-egress-dns |
Allow DNS egress to kube-system only |
This ensures the frontend pod cannot communicate with any other pod in the cluster except via the Traefik ingress controller.
Service Account
A dedicated service account aliquest-frontend is used instead of the default service account.
apiVersion: v1
kind: ServiceAccount
metadata:
name: aliquest-frontend
namespace: aliquest-dev
automountServiceAccountToken: false
automountServiceAccountToken: false ensures the pod has no access to the Kubernetes API.
TLS Certificates
All services use letsencrypt-prod for valid, publicly trusted TLS certificates.
| Service | Issuer |
|---|---|
| dev.aliquest.me | letsencrypt-prod |
| sonar.aliquest.me | letsencrypt-prod |
| argo.aliquest.me | letsencrypt-prod |
| grafana.aliquest.me | letsencrypt-prod |
Dry-Run Validation
All Kubernetes manifest changes are validated with kubectl apply --dry-run=client before pushing to the devgitops repo. This prevents breaking cluster deployments.