sidecar oidc

This commit is contained in:
Danijel Simeunovic
2026-03-13 21:57:51 +01:00
parent 36ba7023f4
commit 0c9c4b6b0d

View File

@@ -10,7 +10,16 @@ metadata:
policies.kyverno.io/severity: medium policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >- 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: spec:
background: false background: false
rules: rules:
@@ -38,6 +47,9 @@ spec:
operator: In operator: In
value: value:
- CREATE - CREATE
- key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-type\" || 'token' }}"
operator: Equals
value: "token"
generate: generate:
synchronize: false synchronize: false
apiVersion: v1 apiVersion: v1
@@ -51,7 +63,45 @@ spec:
app.kubernetes.io/created-by: inject-auth-sidecar app.kubernetes.io/created-by: inject-auth-sidecar
type: Opaque type: Opaque
data: {} 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 skipBackgroundRequests: true
match: match:
any: any:
@@ -69,6 +119,11 @@ spec:
- argocd - argocd
- cert-manager - cert-manager
- monitoring - monitoring
preconditions:
all:
- key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-type\" || 'token' }}"
operator: Equals
value: "token"
context: context:
- name: appPort - name: appPort
variable: variable:
@@ -126,6 +181,87 @@ spec:
secret: secret:
secretName: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-token-secret-name\" || 'auth-tokens' }}" secretName: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-token-secret-name\" || 'auth-tokens' }}"
optional: true 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 - name: generate-auth-network-policy
skipBackgroundRequests: true skipBackgroundRequests: true
match: match: