--- # Auth Service Deployment apiVersion: apps/v1 kind: Deployment metadata: name: auth-service namespace: {{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }} spec: replicas: 2 selector: matchLabels: app: auth-service template: metadata: labels: app: auth-service spec: containers: - name: auth-service image: {{ .Values.authService.image }}:{{ .Values.authService.tag }} ports: - containerPort: 8080 env: - name: JWT_SECRET valueFrom: secretKeyRef: name: auth-secrets key: jwt-secret - name: TOKEN_EXPIRE_HOURS value: "8" - name: ALLOWED_DOMAINS value: "{{ .Values.authService.allowedDomains }}" - name: AUTH_DOMAIN value: "{{ .Values.authService.domain }}" - name: CORS_ORIGINS value: "{{ .Values.authService.corsOrigins }}" - name: AD_SERVER value: "{{ .Values.authService.activeDirectory.server }}" - name: AD_BASE_DN value: "{{ .Values.authService.activeDirectory.baseDN }}" - name: AD_USER_SEARCH_BASE value: "{{ .Values.authService.activeDirectory.userSearchBase }}" - name: AD_BIND_USER valueFrom: secretKeyRef: name: auth-secrets key: ad-bind-user - name: AD_BIND_PASSWORD valueFrom: secretKeyRef: name: auth-secrets key: ad-bind-password livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 5 resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "200m" --- # Auth Service apiVersion: v1 kind: Service metadata: name: auth-service namespace: {{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }} spec: selector: app: auth-service ports: - port: 8080 targetPort: 8080 type: ClusterIP --- # Auth Secrets apiVersion: v1 kind: Secret metadata: name: auth-secrets namespace: {{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }} type: Opaque data: # Base64 encoded values - update these with your actual values jwt-secret: {{ .Values.authService.jwtSecret | b64enc }} ad-bind-user: {{ .Values.authService.activeDirectory.bindUser | b64enc }} ad-bind-password: {{ .Values.authService.activeDirectory.bindPassword | b64enc }} --- # Traefik ForwardAuth Middleware apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: auth-forward namespace: {{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }} spec: forwardAuth: address: http://auth-service.{{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }}.svc.cluster.local:8080/auth/verify authResponseHeaders: - "X-Auth-User" - "X-Auth-Email" - "X-Auth-Groups" - "X-Auth-Display-Name" authRequestHeaders: - "X-Forwarded-Proto" - "X-Forwarded-Host" - "X-Forwarded-Uri" - "X-Original-URL" --- # Traefik IngressRoute for Auth Service apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: auth-service-route namespace: {{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }} spec: entryPoints: - websecure routes: - match: Host(`{{ .Values.authService.domain }}`) kind: Rule services: - name: auth-service port: 8080 tls: certResolver: letsencrypt --- # Protected API with ForwardAuth apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: arti-api-protected namespace: {{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }} spec: entryPoints: - websecure routes: # Public endpoints (no auth required) - match: Host(`{{ .Values.global.Api.Url }}`) && (Path(`/`) || Path(`/health`)) kind: Rule priority: 1000 services: - name: api port: 8000 # Protected endpoints (require authentication) - match: Host(`{{ .Values.global.Api.Url }}`) kind: Rule priority: 500 services: - name: api port: 8000 middlewares: - name: auth-forward tls: certResolver: letsencrypt --- # Multi-domain Auth Configuration # This creates ForwardAuth protection for any subdomain under your domain apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: multi-domain-auth namespace: {{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }} spec: entryPoints: - websecure routes: # Protect all subdomains except the auth service itself - match: HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.{{ .Values.authService.baseDomain }}`) && !Host(`{{ .Values.authService.domain }}`) kind: Rule priority: 100 middlewares: - name: auth-forward services: - name: upstream-service-selector port: 80 tls: certResolver: letsencrypt domains: - main: "{{ .Values.authService.baseDomain }}" sans: - "*.{{ .Values.authService.baseDomain }}" --- # Wildcard certificate for all subdomains apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: wildcard-cert namespace: {{ .Values.global.Category }}--{{ .Values.global.Name }}--{{ .Values.global.Type }} spec: secretName: wildcard-tls issuerRef: name: letsencrypt kind: ClusterIssuer commonName: "*.{{ .Values.authService.baseDomain }}" dnsNames: - "{{ .Values.authService.baseDomain }}" - "*.{{ .Values.authService.baseDomain }}"