diff --git a/deploy/README.md b/deploy/README.md
new file mode 100644
index 0000000..7dc2b79
--- /dev/null
+++ b/deploy/README.md
@@ -0,0 +1,83 @@
+# Math Exercises Application - Kubernetes Deployment
+
+This directory contains the Kubernetes deployment configuration for the Math Exercises application, with security best practices applied.
+
+## Directory Structure
+
+```
+deploy/
+├── base/ # Base kustomize configuration
+│ ├── deployment.yaml # Application deployment
+│ ├── service.yaml # Internal service
+│ ├── ingress.yaml # External access configuration
+│ ├── network-policy.yaml # Network security policies
+│ ├── configmap.yaml # Application configuration
+│ ├── pod-disruption-budget.yaml # High availability
+│ └── kustomization.yaml # Base kustomize file
+├── overlays/ # Environment-specific configurations
+│ ├── development/ # Development environment
+│ │ ├── deployment-patch.yaml # Dev-specific deployment settings
+│ │ └── kustomization.yaml # Dev kustomize file
+│ └── production/ # Production environment
+│ ├── deployment-patch.yaml # Prod-specific deployment settings
+│ ├── security-patch.yaml # Additional security settings
+│ └── kustomization.yaml # Prod kustomize file
+└── SECURITY_CHECKLIST.md # Security implementation checklist
+```
+
+## Security Features Implemented
+
+The deployment implements the following security best practices:
+
+1. **Pod Security**:
+ - Non-root user execution
+ - ReadOnly root filesystem
+ - Disabled privilege escalation
+ - Minimal container capabilities
+ - Seccomp profiles
+
+2. **Network Security**:
+ - Network policies restricting traffic
+ - TLS-enforced ingress with security headers
+ - Internal service exposure only
+
+3. **Configuration Security**:
+ - ConfigMaps for configuration separation
+ - Resource limits and requests
+ - Health checks with appropriate timeouts
+
+4. **Operational Security**:
+ - PodDisruptionBudget for high availability
+ - Environment-specific configurations
+ - Versioned image tags
+
+## Deployment Instructions
+
+### Development Environment
+
+```bash
+kubectl apply -k deploy/overlays/development
+```
+
+### Production Environment
+
+```bash
+kubectl apply -k deploy/overlays/production
+```
+
+## Security Verification
+
+To verify security settings are properly applied:
+
+```bash
+# Check security context
+kubectl get deployment math-exercises-app -o jsonpath='{.spec.template.spec.containers[0].securityContext}'
+
+# Check network policies
+kubectl get networkpolicy
+
+# Check resource limits
+kubectl get deployment math-exercises-app -o jsonpath='{.spec.template.spec.containers[0].resources}'
+```
+
+See `SECURITY_CHECKLIST.md` for a comprehensive list of implemented security measures.
\ No newline at end of file
diff --git a/deploy/SECURITY_CHECKLIST.md b/deploy/SECURITY_CHECKLIST.md
new file mode 100644
index 0000000..09688fa
--- /dev/null
+++ b/deploy/SECURITY_CHECKLIST.md
@@ -0,0 +1,93 @@
+# Kubernetes Security Checklist for Math Exercises Application
+
+This document outlines the security measures implemented in the Kubernetes deployment for the Math Exercises application.
+
+## 1. Pod Security
+
+### Container Security Context
+- ✅ Non-root user execution (`runAsNonRoot: true`, `runAsUser: 1000`)
+- ✅ Disabled privilege escalation (`allowPrivilegeEscalation: false`)
+- ✅ Read-only root filesystem (`readOnlyRootFilesystem: true`)
+- ✅ Minimal capabilities (dropped all, added only necessary ones)
+- ✅ Seccomp profile set to RuntimeDefault
+
+### Pod Security Context
+- ✅ Non-root user execution
+- ✅ Proper fsGroup setting
+- ✅ Seccomp profile enforcement
+
+## 2. Network Security
+
+### Network Policies
+- ✅ Restricted ingress traffic (only from ingress controller)
+- ✅ Limited egress traffic (DNS and HTTPS only)
+- ✅ Port-specific rules
+
+### Service Configuration
+- ✅ Internal traffic policy set to Local
+- ✅ ClusterIP service type (no external exposure)
+
+## 3. Application Security
+
+### Ingress Security
+- ✅ TLS enforced with redirect
+- ✅ HSTS enabled with preload
+- ✅ Security headers configured:
+ - X-Frame-Options: DENY
+ - X-Content-Type-Options: nosniff
+ - X-XSS-Protection: 1; mode=block
+ - Referrer-Policy: strict-origin-when-cross-origin
+ - Permissions-Policy: Restricted APIs
+
+### Resource Management
+- ✅ CPU and memory limits set
+- ✅ CPU and memory requests defined
+- ✅ Quality of Service class guaranteed
+
+## 4. Configuration Security
+
+### ConfigMap Usage
+- ✅ Separation of configuration from code
+- ✅ Centralized configuration management
+
+### Environment Variables
+- ✅ No hardcoded secrets
+- ✅ Secure configuration values
+
+## 5. Operational Security
+
+### High Availability
+- ✅ PodDisruptionBudget configured
+- ✅ Multiple replicas in production
+
+### Image Management
+- ✅ Versioned images in production
+- ✅ Separate tags for dev/prod environments
+
+## 6. Monitoring & Observability
+
+### Health Checks
+- ✅ Liveness probes configured
+- ✅ Readiness probes configured
+- ✅ Appropriate timeouts and thresholds
+
+## 7. Additional Recommendations
+
+### Future Enhancements
+- [ ] Implement Kubernetes Secrets for sensitive data
+- [ ] Add RBAC policies for least privilege access
+- [ ] Enable audit logging
+- [ ] Implement runtime security monitoring
+- [ ] Add image vulnerability scanning
+- [ ] Consider Kyverno policies for admission control
+
+## 8. Environment-Specific Security
+
+### Development
+- ✅ Reduced resource consumption
+- ✅ Standard security posture
+
+### Production
+- ✅ Enhanced security settings
+- ✅ High availability configuration
+- ✅ Dedicated security patches
\ No newline at end of file
diff --git a/deploy/base/configmap.yaml b/deploy/base/configmap.yaml
new file mode 100644
index 0000000..b5070c1
--- /dev/null
+++ b/deploy/base/configmap.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: math-exercises-config
+data:
+ # Application configuration
+ PORT: "8000"
+ LOG_LEVEL: "INFO"
+ MAX_REQUEST_SIZE: "10mb"
+
+ # Security configuration
+ SECURE_COOKIES: "true"
+ CORS_ORIGINS: "math-exercises.local"
+ REQUEST_TIMEOUT: "30s"
\ No newline at end of file
diff --git a/deploy/base/deployment.yaml b/deploy/base/deployment.yaml
new file mode 100644
index 0000000..1a0386e
--- /dev/null
+++ b/deploy/base/deployment.yaml
@@ -0,0 +1,75 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: math-exercises-app
+ labels:
+ app: math-exercises
+spec:
+ replicas: 2
+ selector:
+ matchLabels:
+ app: math-exercises
+ template:
+ metadata:
+ labels:
+ app: math-exercises
+ spec:
+ # Security context for the pod
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ fsGroup: 2000
+ seccompProfile:
+ type: RuntimeDefault
+ containers:
+ - name: math-exercises
+ image: math-exercises:latest
+ ports:
+ - containerPort: 8000
+ # Security context for the container
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsUser: 1000
+ capabilities:
+ drop:
+ - ALL
+ # Resource limits and requests
+ resources:
+ requests:
+ memory: "64Mi"
+ cpu: "250m"
+ limits:
+ memory: "128Mi"
+ cpu: "500m"
+ # Liveness probe
+ livenessProbe:
+ httpGet:
+ path: /
+ port: 8000
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 3
+ # Readiness probe
+ readinessProbe:
+ httpGet:
+ path: /
+ port: 8000
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ timeoutSeconds: 3
+ failureThreshold: 3
+ # Environment variables from ConfigMap
+ envFrom:
+ - configMapRef:
+ name: math-exercises-config
+ # Volume mounts for writable directories
+ volumeMounts:
+ - name: static-volume
+ mountPath: /app/app/static
+ # Volumes
+ volumes:
+ - name: static-volume
+ emptyDir: {}
\ No newline at end of file
diff --git a/deploy/base/ingress.yaml b/deploy/base/ingress.yaml
new file mode 100644
index 0000000..3554607
--- /dev/null
+++ b/deploy/base/ingress.yaml
@@ -0,0 +1,29 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: math-exercises-ingress
+ annotations:
+ # Security 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/hsts: "true"
+ nginx.ingress.kubernetes.io/hsts-max-age: "31536000"
+ nginx.ingress.kubernetes.io/hsts-include-subdomains: "true"
+ nginx.ingress.kubernetes.io/hsts-preload: "true"
+spec:
+ tls:
+ - hosts:
+ - math-exercises.local
+ secretName: math-exercises-tls
+ rules:
+ - host: math-exercises.local
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: math-exercises-service
+ port:
+ number: 80
\ No newline at end of file
diff --git a/deploy/base/kustomization.yaml b/deploy/base/kustomization.yaml
new file mode 100644
index 0000000..936ad4b
--- /dev/null
+++ b/deploy/base/kustomization.yaml
@@ -0,0 +1,19 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+- deployment.yaml
+- service.yaml
+- ingress.yaml
+- network-policy.yaml
+- pod-disruption-budget.yaml
+- configmap.yaml
+
+# Common labels to apply to all resources
+commonLabels:
+ app.kubernetes.io/name: math-exercises
+ app.kubernetes.io/instance: math-exercises-instance
+ app.kubernetes.io/version: "1.0"
+ app.kubernetes.io/component: web
+ app.kubernetes.io/part-of: math-suite
+ app.kubernetes.io/managed-by: kustomize
\ No newline at end of file
diff --git a/deploy/base/network-policy.yaml b/deploy/base/network-policy.yaml
new file mode 100644
index 0000000..4bf8720
--- /dev/null
+++ b/deploy/base/network-policy.yaml
@@ -0,0 +1,35 @@
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: math-exercises-netpol
+spec:
+ podSelector:
+ matchLabels:
+ app: math-exercises
+ policyTypes:
+ - Ingress
+ - Egress
+ ingress:
+ # Allow inbound traffic from the ingress controller only
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ name: ingress-nginx
+ ports:
+ - protocol: TCP
+ port: 8000
+ egress:
+ # Allow outbound DNS resolution
+ - to:
+ - namespaceSelector:
+ matchLabels:
+ name: kube-system
+ ports:
+ - protocol: TCP
+ port: 53
+ - protocol: UDP
+ port: 53
+ # Allow outbound HTTPS for package updates or external APIs
+ - ports:
+ - protocol: TCP
+ port: 443
\ No newline at end of file
diff --git a/deploy/base/pod-disruption-budget.yaml b/deploy/base/pod-disruption-budget.yaml
new file mode 100644
index 0000000..11edc19
--- /dev/null
+++ b/deploy/base/pod-disruption-budget.yaml
@@ -0,0 +1,9 @@
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: math-exercises-pdb
+spec:
+ minAvailable: 1
+ selector:
+ matchLabels:
+ app: math-exercises
\ No newline at end of file
diff --git a/deploy/base/service.yaml b/deploy/base/service.yaml
new file mode 100644
index 0000000..d712e4a
--- /dev/null
+++ b/deploy/base/service.yaml
@@ -0,0 +1,18 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: math-exercises-service
+ annotations:
+ # Security annotations
+ service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
+spec:
+ selector:
+ app: math-exercises
+ ports:
+ - name: http
+ protocol: TCP
+ port: 80
+ targetPort: 8000
+ type: ClusterIP
+ # Only accessible within the cluster
+ internalTrafficPolicy: Local
\ No newline at end of file
diff --git a/deploy/kustomization.yaml b/deploy/kustomization.yaml
new file mode 100644
index 0000000..1b30247
--- /dev/null
+++ b/deploy/kustomization.yaml
@@ -0,0 +1,5 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+- base
\ No newline at end of file
diff --git a/deploy/overlays/development/deployment-patch.yaml b/deploy/overlays/development/deployment-patch.yaml
new file mode 100644
index 0000000..7983866
--- /dev/null
+++ b/deploy/overlays/development/deployment-patch.yaml
@@ -0,0 +1,26 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: math-exercises-app
+ annotations:
+ # Development environment annotation
+ environment: development
+spec:
+ replicas: 1
+ template:
+ spec:
+ containers:
+ - name: math-exercises
+ env:
+ - name: ENVIRONMENT
+ value: development
+ - name: DEBUG
+ value: "false"
+ # Reduce resource consumption in development
+ resources:
+ requests:
+ memory: "32Mi"
+ cpu: "100m"
+ limits:
+ memory: "64Mi"
+ cpu: "200m"
\ No newline at end of file
diff --git a/deploy/overlays/development/kustomization.yaml b/deploy/overlays/development/kustomization.yaml
new file mode 100644
index 0000000..2f1f35d
--- /dev/null
+++ b/deploy/overlays/development/kustomization.yaml
@@ -0,0 +1,20 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+- ../../base
+
+# Development-specific patches
+patchesStrategicMerge:
+- deployment-patch.yaml
+
+# Development-specific configurations
+images:
+- name: math-exercises
+ newName: math-exercises
+ newTag: dev-latest
+
+# Development-specific labels
+commonLabels:
+ environment: development
+ security-level: standard
\ No newline at end of file
diff --git a/deploy/overlays/production/deployment-patch.yaml b/deploy/overlays/production/deployment-patch.yaml
new file mode 100644
index 0000000..286692f
--- /dev/null
+++ b/deploy/overlays/production/deployment-patch.yaml
@@ -0,0 +1,37 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: math-exercises-app
+ annotations:
+ # Production environment annotation
+ environment: production
+ # Security annotations
+ seccomp.security.alpha.kubernetes.io/pod: docker/default
+spec:
+ replicas: 1
+ template:
+ spec:
+ containers:
+ - name: math-exercises
+ env:
+ - name: ENVIRONMENT
+ value: production
+ - name: DEBUG
+ value: "false"
+ # Enhanced security for production
+ securityContext:
+ readOnlyRootFilesystem: true
+ allowPrivilegeEscalation: false
+ runAsNonRoot: true
+ runAsUser: 1000
+ capabilities:
+ drop:
+ - ALL
+ # Production resource settings
+ resources:
+ requests:
+ memory: "64Mi"
+ cpu: "250m"
+ limits:
+ memory: "128Mi"
+ cpu: "500m"
\ No newline at end of file
diff --git a/deploy/overlays/production/ingress-patch.yaml b/deploy/overlays/production/ingress-patch.yaml
new file mode 100644
index 0000000..979c605
--- /dev/null
+++ b/deploy/overlays/production/ingress-patch.yaml
@@ -0,0 +1,23 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: math-exercises-ingress
+ annotations:
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - math-tables.cl1.parano.ch
+ secretName: math-exercises-tls
+ rules:
+ - host: math-tables.cl1.parano.ch
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: math-exercises-service
+ port:
+ number: 80
\ No newline at end of file
diff --git a/deploy/overlays/production/kustomization.yaml b/deploy/overlays/production/kustomization.yaml
new file mode 100644
index 0000000..c9742a1
--- /dev/null
+++ b/deploy/overlays/production/kustomization.yaml
@@ -0,0 +1,25 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: math-tables
+
+resources:
+- ../../base
+- namespace.yaml
+
+# Production-specific patches
+patchesStrategicMerge:
+- deployment-patch.yaml
+- security-patch.yaml
+- ingress-patch.yaml
+
+# Production-specific configurations
+images:
+- name: math-exercises
+ newName: harbor.cl1.parano.ch/library/math-exercice
+ newTag: 1.0.0
+
+# Production-specific labels
+commonLabels:
+ environment: production
+ security-level: high
\ No newline at end of file
diff --git a/deploy/overlays/production/namespace.yaml b/deploy/overlays/production/namespace.yaml
new file mode 100644
index 0000000..776395b
--- /dev/null
+++ b/deploy/overlays/production/namespace.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: math-tables
\ No newline at end of file
diff --git a/deploy/overlays/production/security-patch.yaml b/deploy/overlays/production/security-patch.yaml
new file mode 100644
index 0000000..a46ed89
--- /dev/null
+++ b/deploy/overlays/production/security-patch.yaml
@@ -0,0 +1,27 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: math-exercises-app
+spec:
+ template:
+ spec:
+ # Additional security context for production
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ fsGroup: 2000
+ seccompProfile:
+ type: RuntimeDefault
+ containers:
+ - name: math-exercises
+ # Additional security settings for production
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsUser: 1000
+ capabilities:
+ drop:
+ - ALL
+ add:
+ - NET_BIND_SERVICE
\ No newline at end of file
diff --git a/k8s-deployment.yaml b/k8s-deployment.yaml
new file mode 100644
index 0000000..46dbd76
--- /dev/null
+++ b/k8s-deployment.yaml
@@ -0,0 +1,53 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: math-exercises-app
+ labels:
+ app: math-exercises
+spec:
+ replicas: 2
+ selector:
+ matchLabels:
+ app: math-exercises
+ template:
+ metadata:
+ labels:
+ app: math-exercises
+ spec:
+ containers:
+ - name: math-exercises
+ image: math-exercises:latest
+ ports:
+ - containerPort: 8000
+ resources:
+ requests:
+ memory: "64Mi"
+ cpu: "250m"
+ limits:
+ memory: "128Mi"
+ cpu: "500m"
+ livenessProbe:
+ httpGet:
+ path: /
+ port: 8000
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /
+ port: 8000
+ initialDelaySeconds: 5
+ periodSeconds: 10
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: math-exercises-service
+spec:
+ selector:
+ app: math-exercises
+ ports:
+ - protocol: TCP
+ port: 80
+ targetPort: 8000
+ type: ClusterIP
\ No newline at end of file