# ============================================================================== # EXAMPLE: JWT Validator Plugin for Kubernetes # ============================================================================== # # JWT PUBLIC KEY CONFIGURATION OPTIONS: # There are three ways to provide the JWT public key: # # 1. pubkey_path - Mount a file and reference the path (requires ConfigMap or Volume) # easyhaproxy.plugin.jwt_validator.pubkey_path: "/etc/haproxy/jwt_keys/api_pubkey.pem" # # 2. k8s_secret.pubkey - Reference a Kubernetes secret (RECOMMENDED) # Auto-detect key (tries common variations): # easyhaproxy.plugin.jwt_validator.k8s_secret.pubkey: "my-jwt-secret" # Explicit key (no variations): # easyhaproxy.plugin.jwt_validator.k8s_secret.pubkey: "my-jwt-secret/custom-key-name" # See jwt-validator-secret-example.yml for full example # # 3. pubkey - Inline base64-encoded key (for testing only, not recommended for production) # easyhaproxy.plugin.jwt_validator.pubkey: "LS0tLS1CRUdJTi..." # # This example shows option #1 (pubkey_path) for backward compatibility # # WHAT THIS DEMONSTRATES: # - JWT token validation for API protection in Kubernetes # - RS256 algorithm signature verification # - Using ConfigMaps to mount JWT public keys # - Issuer and audience validation # # REQUIREMENTS (run these first): # ```bash # # 1. Ensure EasyHAProxy is installed in your cluster # kubectl create namespace easyhaproxy # kubectl apply -f https://raw.githubusercontent.com/byjg/docker-easy-haproxy/5.0.0/deploy/kubernetes/easyhaproxy-daemonset.yml # # # 2. Generate RSA key pair (idempotent - skips if exists) # [ -f jwt_private.pem ] || openssl genrsa -out jwt_private.pem 2048 # [ -f jwt_pubkey.pem ] || openssl rsa -in jwt_private.pem -pubout -out jwt_pubkey.pem # # # 3. Create ConfigMap with public key # kubectl create configmap jwt-keys --from-file=api_pubkey.pem=jwt_pubkey.pem # # # 4. Mount the ConfigMap in EasyHAProxy deployment: # # Edit your EasyHAProxy deployment and add: # # volumeMounts: # # - name: jwt-keys # # mountPath: /etc/haproxy/jwt_keys # # volumes: # # - name: jwt-keys # # configMap: # # name: jwt-keys # ``` # # HOW TO START: # ```bash # kubectl apply -f jwt-validator.yml # ``` # # HOW TO VERIFY IT'S WORKING: # ```bash # # Check resources are created # kubectl get deployment,service,ingress -l app=api # # # Test without token (should fail) # kubectl port-forward -n easyhaproxy deployment/easyhaproxy 8080:80 # curl -H "Host: api.example.local" http://localhost:8080 # # Expected: HTTP 403 - Missing Authorization HTTP header # # # Generate test JWT at https://jwt.io with: # # - Algorithm: RS256 # # - Payload: {"iss":"https://auth.example.com/","aud":"https://api.example.com","exp":9999999999} # # - Paste contents of jwt_private.pem in private key field # # # Test with valid token # TOKEN="eyJhbGc..." # Replace with your generated token # curl -H "Authorization: Bearer $TOKEN" -H "Host: api.example.local" http://localhost:8080 # # Expected: 200 OK with "Protected API - JWT Required" # ``` # # CLEAN UP: # ```bash # kubectl delete -f jwt-validator.yml # ``` # # ============================================================================== --- apiVersion: v1 kind: Service metadata: name: api-service namespace: default spec: ports: - port: 8080 targetPort: 8080 selector: app: api type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: api namespace: default spec: replicas: 3 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: api image: byjg/static-httpserver ports: - containerPort: 8080 env: - name: TITLE value: "Protected API - JWT Required" resources: limits: cpu: '0.1' memory: '64Mi' requests: cpu: '0.05' memory: '32Mi' --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: # Enable JWT validator plugin easyhaproxy.plugins: "jwt_validator" # JWT validator configuration easyhaproxy.plugin.jwt_validator.algorithm: "RS256" easyhaproxy.plugin.jwt_validator.issuer: "https://auth.example.com/" easyhaproxy.plugin.jwt_validator.audience: "https://api.example.com" easyhaproxy.plugin.jwt_validator.pubkey_path: "/etc/haproxy/jwt_keys/api_pubkey.pem" name: api-ingress-jwt namespace: default spec: # Use ingressClassName instead of the deprecated annotation # For backward compatibility, annotation kubernetes.io/ingress.class is still supported ingressClassName: easyhaproxy rules: - host: api.example.local http: paths: - backend: service: name: api-service port: number: 8080 pathType: ImplementationSpecific