apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: inject-auth-sidecar annotations: pod-policies.kyverno.io/autogen-controllers: none policies.kyverno.io/title: Inject Auth Sidecar policies.kyverno.io/minversion: 1.6.0 policies.kyverno.io/category: Security policies.kyverno.io/severity: medium policies.kyverno.io/subject: Pod policies.kyverno.io/description: >- Injects an auth sidecar container into Pods annotated with policies.forteapps.io/auth: "true". Supports three auth modes controlled by the policies.forteapps.io/auth-type annotation: "token" (default), "oidc", and "mcp". In token mode the sidecar reads credentials from a mounted Secret volume. In OIDC mode the sidecar uses OpenID Connect with authority and client-id provided via required annotations (policies.forteapps.io/auth-oidc-authority and policies.forteapps.io/auth-oidc-client-id) and secrets from an auth-oidc Secret. In MCP mode the sidecar implements OAuth 2.0 for MCP servers per RFC 9728 (Protected Resource Metadata) and RFC 7591 (Dynamic Client Registration), configured via policies.forteapps.io/auth-mcp-resource and policies.forteapps.io/auth-mcp-authority annotations. A NetworkPolicy is generated to restrict ingress to the sidecar port only. spec: background: false rules: - name: generate-auth-tokens-secret skipBackgroundRequests: true match: any: - resources: kinds: - Pod annotations: policies.forteapps.io/auth: "true" exclude: any: - resources: namespaces: - kube-system - kyverno - argocd - cert-manager - monitoring preconditions: all: - key: "{{ request.operation }}" operator: In value: - CREATE - key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-type\" || 'token' }}" operator: Equals value: "token" generate: synchronize: false apiVersion: v1 kind: Secret name: auth-tokens namespace: "{{ request.namespace }}" data: metadata: labels: app.kubernetes.io/managed-by: kyverno app.kubernetes.io/created-by: inject-auth-sidecar type: Opaque data: {} - name: generate-auth-oidc-secret skipBackgroundRequests: true match: any: - resources: kinds: - Pod annotations: policies.forteapps.io/auth: "true" policies.forteapps.io/auth-type: "oidc" exclude: any: - resources: namespaces: - kube-system - kyverno - argocd - cert-manager - monitoring preconditions: all: - key: "{{ request.operation }}" operator: In value: - CREATE generate: synchronize: false apiVersion: v1 kind: Secret name: auth-oidc namespace: "{{ request.namespace }}" data: metadata: labels: app.kubernetes.io/managed-by: kyverno app.kubernetes.io/created-by: inject-auth-sidecar type: Opaque data: {} - name: inject-sidecar-token skipBackgroundRequests: true match: any: - resources: kinds: - Pod annotations: policies.forteapps.io/auth: "true" exclude: any: - resources: namespaces: - kube-system - kyverno - argocd - cert-manager - monitoring preconditions: all: - key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-type\" || 'token' }}" operator: Equals value: "token" context: - name: appPort variable: jmesPath: request.object.spec.containers[?name != 'authn'] | [0].ports[0].containerPort || `3000` mutate: patchStrategicMerge: spec: containers: - name: authn image: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image\" || 'ghcr.io/snothub/stunning-memory' }}:{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image-version\" || 'latest' }}" ports: - containerPort: 8080 name: auth protocol: TCP env: - name: AUTH_LISTEN_ADDR value: ":8080" - name: AUTH_UPSTREAM_URL value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-upstream-url\" || join('', ['http://localhost:', to_string(appPort)]) }}" - name: AUTH_TOKEN_FILE value: "/etc/auth/tokens" - name: AUTH_MODE value: "token" volumeMounts: - name: auth-tokens mountPath: /etc/auth readOnly: true resources: limits: cpu: 50m memory: 64Mi requests: cpu: 10m memory: 32Mi readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 2 periodSeconds: 5 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 10 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL volumes: - name: auth-tokens secret: secretName: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-token-secret-name\" || 'auth-tokens' }}" optional: true - name: inject-sidecar-oidc skipBackgroundRequests: true match: any: - resources: kinds: - Pod annotations: policies.forteapps.io/auth: "true" policies.forteapps.io/auth-type: "oidc" exclude: any: - resources: namespaces: - kube-system - kyverno - argocd - cert-manager - monitoring context: - name: appPort variable: jmesPath: request.object.spec.containers[?name != 'authn'] | [0].ports[0].containerPort || `3000` mutate: patchStrategicMerge: spec: containers: - name: authn image: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image\" || 'ghcr.io/snothub/stunning-memory' }}:{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image-version\" || 'latest' }}" imagePullPolicy: Always ports: - containerPort: 8080 name: auth protocol: TCP env: - name: AUTH_MODE value: "oidc" - name: AUTH_LISTEN_ADDR value: ":8080" - name: AUTH_LOG_LEVEL value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-log-level\" || 'info' }}" - name: AUTH_UPSTREAM_URL value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-upstream-url\" || join('', ['http://localhost:', to_string(appPort)]) }}" - name: AUTH_OIDC_AUTHORITY value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-authority\" }}" - name: AUTH_OIDC_CLIENT_ID value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-client-id\" }}" - name: AUTH_OIDC_CALLBACK_URL value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-callback-path\" }}" - name: AUTH_OIDC_CALLBACK_PATH value: "{{ regex_replace_all('https?://[^/]*', request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-callback-path\", '') }}" - name: AUTH_OIDC_SCOPES value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-scopes\" || 'openid,profile,email' }}" - name: AUTH_OIDC_COOKIE_SECRET valueFrom: secretKeyRef: name: auth-oidc key: cookie-secret - name: AUTH_OIDC_CLIENT_SECRET valueFrom: secretKeyRef: name: auth-oidc key: client-secret resources: limits: cpu: 50m memory: 64Mi requests: cpu: 10m memory: 32Mi readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 2 periodSeconds: 5 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 10 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL - name: inject-sidecar-mcp skipBackgroundRequests: true match: any: - resources: kinds: - Pod annotations: policies.forteapps.io/auth: "true" policies.forteapps.io/auth-type: "mcp" exclude: any: - resources: namespaces: - kube-system - kyverno - argocd - cert-manager - monitoring context: - name: appPort variable: jmesPath: request.object.spec.containers[?name != 'authn'] | [0].ports[0].containerPort || `3000` mutate: patchStrategicMerge: spec: containers: - name: authn image: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image\" || 'ghcr.io/snothub/stunning-memory' }}:{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image-version\" || 'latest' }}" imagePullPolicy: Always ports: - containerPort: 8080 name: auth protocol: TCP env: - name: AUTH_MODE value: "mcp" - name: AUTH_LISTEN_ADDR value: ":8080" - name: AUTH_LOG_LEVEL value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-log-level\" || 'info' }}" - name: AUTH_UPSTREAM_URL value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-upstream-url\" || join('', ['http://localhost:', to_string(appPort)]) }}" - name: AUTH_MCP_RESOURCE value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-resource\" }}" - name: AUTH_MCP_AUTHORIZATION_SERVERS value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-authority\" }}" - name: AUTH_MCP_SCOPES_SUPPORTED value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-scopes\" || 'read,write' }}" resources: limits: cpu: 50m memory: 64Mi requests: cpu: 10m memory: 32Mi readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 2 periodSeconds: 5 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 10 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL - name: generate-auth-network-policy skipBackgroundRequests: true match: any: - resources: kinds: - Pod annotations: policies.forteapps.io/auth: "true" exclude: any: - resources: namespaces: - kube-system - kyverno - argocd - cert-manager - monitoring preconditions: all: - key: "{{ request.operation }}" operator: In value: - CREATE generate: synchronize: false apiVersion: networking.k8s.io/v1 kind: NetworkPolicy name: "{{ request.object.metadata.name }}-auth-ingress" namespace: "{{ request.namespace }}" data: metadata: labels: app.kubernetes.io/managed-by: kyverno app.kubernetes.io/created-by: inject-auth-sidecar spec: podSelector: matchLabels: "{{ request.object.metadata.labels }}" policyTypes: - Ingress ingress: - ports: - port: 8080 protocol: TCP