From 0c9c4b6b0d3652158ad25f7565ef4fd483e6859b Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Fri, 13 Mar 2026 21:57:51 +0100 Subject: [PATCH] sidecar oidc --- .../policies/auth-sidecar-injector.yaml | 140 +++++++++++++++++- 1 file changed, 138 insertions(+), 2 deletions(-) diff --git a/cluster-resources/policies/auth-sidecar-injector.yaml b/cluster-resources/policies/auth-sidecar-injector.yaml index 42ebbd1..7f98a78 100644 --- a/cluster-resources/policies/auth-sidecar-injector.yaml +++ b/cluster-resources/policies/auth-sidecar-injector.yaml @@ -10,7 +10,16 @@ metadata: 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". The sidecar proxies requests through a token-based auth layer and a NetworkPolicy is generated to restrict ingress to the sidecar port only. If the auth-tokens Secret does not exist in the namespace, an empty one is created to prevent volume mount failures. Upstream URL and image can be overridden via policies.forteapps.io/auth-upstream-url and policies.forteapps.io/auth-image annotations. When auth-upstream-url is not set, the first containerPort of the first existing container is used. + Injects an auth sidecar container into Pods annotated with + policies.forteapps.io/auth: "true". Supports two auth modes controlled + by the policies.forteapps.io/auth-type annotation: "token" (default) + and "oidc". 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. A NetworkPolicy is generated to restrict ingress + to the sidecar port only. spec: background: false rules: @@ -38,6 +47,9 @@ spec: operator: In value: - CREATE + - key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-type\" || 'token' }}" + operator: Equals + value: "token" generate: synchronize: false apiVersion: v1 @@ -51,7 +63,45 @@ spec: app.kubernetes.io/created-by: inject-auth-sidecar type: Opaque data: {} - - name: inject-sidecar + - 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: @@ -69,6 +119,11 @@ spec: - 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: @@ -126,6 +181,87 @@ spec: 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' }}" + ports: + - containerPort: 8080 + name: auth + protocol: TCP + env: + - name: AUTH_MODE + value: "oidc" + - 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_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_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: generate-auth-network-policy skipBackgroundRequests: true match: