Skip to content

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.

kubectl apply -k aliquest/frontend/base --dry-run=client
kubectl apply -k aliquest/frontend/overlays/dev --dry-run=client