Prepare renamed Access Engine runtime twins with exact reviewer scope
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
parent
0bc15925e9
commit
dd15d8cf3f
26 changed files with 1480 additions and 26 deletions
6
charts/access-engine/Chart.yaml
Normal file
6
charts/access-engine/Chart.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: v2
|
||||
name: access-engine
|
||||
description: Independently rollable access-engine policy-decision Deployment (one consumer per release).
|
||||
type: application
|
||||
version: 0.2.0
|
||||
appVersion: "0.1.0"
|
||||
35
charts/access-engine/templates/_helpers.tpl
Normal file
35
charts/access-engine/templates/_helpers.tpl
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{{- define "access-engine.image" -}}
|
||||
{{- if not .Values.image.digest }}
|
||||
{{- fail "image.digest is required (digest_policy=required); do not deploy by tag" }}
|
||||
{{- end }}
|
||||
{{- printf "%s@%s" .Values.image.repository .Values.image.digest -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "access-engine.name" -}}
|
||||
{{- required "name is required" .Values.name -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "access-engine.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "access-engine.name" . }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "access-engine.labels" -}}
|
||||
{{ include "access-engine.selectorLabels" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/part-of: access-engine
|
||||
{{- end -}}
|
||||
|
||||
{{- define "access-engine.callerAuth.mode" -}}
|
||||
{{- $mode := "disabled" -}}
|
||||
{{- if and (hasKey .Values "callerAuth") .Values.callerAuth (hasKey .Values.callerAuth "mode") .Values.callerAuth.mode -}}
|
||||
{{- $mode = .Values.callerAuth.mode -}}
|
||||
{{- end -}}
|
||||
{{- if not (has $mode (list "disabled" "warn" "enforce")) -}}
|
||||
{{- fail (printf "callerAuth.mode must be disabled, warn, or enforce; got %q" $mode) -}}
|
||||
{{- end -}}
|
||||
{{- $mode -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "access-engine.callerAuth.enabled" -}}
|
||||
{{- if has (include "access-engine.callerAuth.mode" .) (list "warn" "enforce") -}}true{{- else -}}false{{- end -}}
|
||||
{{- end -}}
|
||||
167
charts/access-engine/templates/deployment.yaml
Normal file
167
charts/access-engine/templates/deployment.yaml
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
{{- if .Values.auditDelivery.enabled }}
|
||||
{{- if ne (first .Values.args) "serve" }}
|
||||
{{- fail "auditDelivery currently supports serve decision pins only" }}
|
||||
{{- end }}
|
||||
{{- if not .Values.outbox.enabled }}
|
||||
{{- fail "auditDelivery requires enabled durable outbox" }}
|
||||
{{- end }}
|
||||
{{- if not (regexMatch "^https?://[^/?#@]+/v1/events$" .Values.auditDelivery.url) }}
|
||||
{{- fail "auditDelivery.url must be an explicit http(s) /v1/events endpoint" }}
|
||||
{{- end }}
|
||||
{{- if or (not (hasPrefix "/" .Values.auditDelivery.mountPath)) (contains ".." .Values.auditDelivery.mountPath) }}
|
||||
{{- fail "auditDelivery.mountPath must be an absolute normalized directory" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
name: {{ include "access-engine.name" . }}
|
||||
labels:
|
||||
{{- include "access-engine.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Values.outbox.enabled }}
|
||||
{{- if ne (int .Values.replicaCount) 1 }}
|
||||
{{- fail "outbox requires replicaCount=1: one writer per source and PVC" }}
|
||||
{{- end }}
|
||||
strategy:
|
||||
type: Recreate
|
||||
{{- end }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "access-engine.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "access-engine.labels" . | nindent 8 }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
{{- if eq (include "access-engine.callerAuth.enabled" .) "true" }}
|
||||
serviceAccountName: {{ include "access-engine.name" . }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 65532
|
||||
runAsGroup: 65532
|
||||
fsGroup: 65532
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: access-engine
|
||||
image: {{ include "access-engine.image" . }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
args:
|
||||
{{- toYaml .Values.args | nindent 12 }}
|
||||
{{- if .Values.outbox.enabled }}
|
||||
- --outbox-dir
|
||||
- {{ .Values.outbox.mountPath | quote }}
|
||||
- --emission-source
|
||||
- {{ required "outbox.source is required when outbox.enabled=true" .Values.outbox.source | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.auditDelivery.enabled }}
|
||||
- --audit-url
|
||||
- {{ .Values.auditDelivery.url | quote }}
|
||||
- --audit-token-file
|
||||
- {{ printf "%s/token" .Values.auditDelivery.mountPath | quote }}
|
||||
{{- end }}
|
||||
{{- if eq (include "access-engine.callerAuth.enabled" .) "true" }}
|
||||
{{- $binding := "" }}
|
||||
{{- if not (and .Values.readback .Values.readback.enabled) }}
|
||||
{{- $binding = required "callerAuth.binding is required when callerAuth.mode is warn or enforce" .Values.callerAuth.binding }}
|
||||
{{- end }}
|
||||
- --caller-audience
|
||||
- {{ required "callerAuth.audience is required" .Values.callerAuth.audience | quote }}
|
||||
- --caller-reviewer-token-file
|
||||
- {{ printf "%s/token" .Values.callerAuth.reviewer.mountPath | quote }}
|
||||
- --caller-ca-file
|
||||
- {{ printf "%s/ca.crt" .Values.callerAuth.reviewer.mountPath | quote }}
|
||||
- --caller-auth-mode
|
||||
- {{ include "access-engine.callerAuth.mode" . | quote }}
|
||||
- --caller-kubernetes-url
|
||||
- {{ required "callerAuth.kubernetesURL is required when callerAuth.mode is warn or enforce" .Values.callerAuth.kubernetesURL | quote }}
|
||||
{{- if and .Values.readback .Values.readback.enabled }}
|
||||
{{- /* serve-readback admits one readback caller and no /v1/check binding (FLEX-DEC-2026-019). */}}
|
||||
- --readback-caller
|
||||
- {{ required "readback.caller is required when readback.enabled=true" .Values.readback.caller | quote }}
|
||||
{{- else }}
|
||||
- --caller-binding
|
||||
- {{ $binding | quote }}
|
||||
{{- range .Values.callerAuth.extraBindings }}
|
||||
- --caller-binding
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.health.path }}
|
||||
port: http
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.health.path }}
|
||||
port: http
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
{{- if or .Values.outbox.enabled .Values.auditDelivery.enabled (eq (include "access-engine.callerAuth.enabled" .) "true") }}
|
||||
volumeMounts:
|
||||
{{- if .Values.auditDelivery.enabled }}
|
||||
- mountPath: {{ .Values.auditDelivery.mountPath | quote }}
|
||||
name: access-engine-audit
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.outbox.enabled }}
|
||||
- mountPath: {{ .Values.outbox.mountPath | quote }}
|
||||
name: access-engine-outbox
|
||||
{{- end }}
|
||||
{{- if eq (include "access-engine.callerAuth.enabled" .) "true" }}
|
||||
- mountPath: {{ .Values.callerAuth.reviewer.mountPath }}
|
||||
name: access-engine-reviewer
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if or .Values.outbox.enabled .Values.auditDelivery.enabled (eq (include "access-engine.callerAuth.enabled" .) "true") }}
|
||||
volumes:
|
||||
{{- if .Values.auditDelivery.enabled }}
|
||||
- name: access-engine-audit
|
||||
secret:
|
||||
secretName: {{ required "auditDelivery.secretName must name an admitted existing Secret" .Values.auditDelivery.secretName | quote }}
|
||||
defaultMode: 0440
|
||||
items:
|
||||
- key: {{ required "auditDelivery.secretKey is required" .Values.auditDelivery.secretKey | quote }}
|
||||
path: token
|
||||
{{- end }}
|
||||
{{- if .Values.outbox.enabled }}
|
||||
- name: access-engine-outbox
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ default (printf "%s-outbox" (include "access-engine.name" .)) .Values.outbox.existingClaim | quote }}
|
||||
{{- end }}
|
||||
{{- if eq (include "access-engine.callerAuth.enabled" .) "true" }}
|
||||
- name: access-engine-reviewer
|
||||
projected:
|
||||
defaultMode: 0440
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
{{- if .Values.callerAuth.reviewer.audience }}
|
||||
audience: {{ .Values.callerAuth.reviewer.audience | quote }}
|
||||
{{- end }}
|
||||
expirationSeconds: {{ .Values.callerAuth.reviewer.expirationSeconds }}
|
||||
path: token
|
||||
- configMap:
|
||||
name: kube-root-ca.crt
|
||||
items:
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
68
charts/access-engine/templates/networkpolicy.yaml
Normal file
68
charts/access-engine/templates/networkpolicy.yaml
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
name: {{ include "access-engine.name" . }}
|
||||
labels:
|
||||
{{- include "access-engine.labels" . | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- include "access-engine.selectorLabels" . | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
{{- if or .Values.auditDelivery.enabled (eq (include "access-engine.callerAuth.enabled" .) "true") }}
|
||||
egress:
|
||||
{{- if eq (include "access-engine.callerAuth.enabled" .) "true" }}
|
||||
- ports:
|
||||
- port: 443
|
||||
protocol: TCP
|
||||
- port: 6443
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- if .Values.auditDelivery.enabled }}
|
||||
{{- if or (not (regexMatch "^[1-9][0-9]*$" (toString .Values.auditDelivery.receiverPort))) (lt (int .Values.auditDelivery.receiverPort) 1) (gt (int .Values.auditDelivery.receiverPort) 65535) }}
|
||||
{{- fail "auditDelivery.receiverPort must be explicitly set to a valid receiver port" }}
|
||||
{{- end }}
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ required "auditDelivery.receiverNamespace is required" .Values.auditDelivery.receiverNamespace | quote }}
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ required "auditDelivery.receiverPodName is required" .Values.auditDelivery.receiverPodName | quote }}
|
||||
ports:
|
||||
- port: {{ .Values.auditDelivery.receiverPort }}
|
||||
protocol: TCP
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ required "auditDelivery.dnsNamespace is required" .Values.auditDelivery.dnsNamespace | quote }}
|
||||
podSelector:
|
||||
matchLabels:
|
||||
k8s-app: {{ required "auditDelivery.dnsPodLabel is required" .Values.auditDelivery.dnsPodLabel | quote }}
|
||||
ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
- port: 53
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
egress: []
|
||||
{{- end }}
|
||||
{{- if .Values.consumer.isolated }}
|
||||
ingress: []
|
||||
{{- else }}
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ required "consumer.namespace is required when not isolated" .Values.consumer.namespace }}
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ required "consumer.podName is required when not isolated" .Values.consumer.podName }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
20
charts/access-engine/templates/outbox-pvc.yaml
Normal file
20
charts/access-engine/templates/outbox-pvc.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{{- if and .Values.outbox.enabled (not .Values.outbox.existingClaim) }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
name: {{ include "access-engine.name" . }}-outbox
|
||||
annotations:
|
||||
helm.sh/resource-policy: keep
|
||||
labels:
|
||||
{{- include "access-engine.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
{{- if .Values.outbox.storageClassName }}
|
||||
storageClassName: {{ .Values.outbox.storageClassName | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.outbox.size | quote }}
|
||||
{{- end }}
|
||||
30
charts/access-engine/templates/rbac.yaml
Normal file
30
charts/access-engine/templates/rbac.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{{- if eq (include "access-engine.callerAuth.enabled" .) "true" }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "access-engine.name" . }}-tokenreviewer
|
||||
labels:
|
||||
{{- include "access-engine.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- authentication.k8s.io
|
||||
resources:
|
||||
- tokenreviews
|
||||
verbs:
|
||||
- create
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "access-engine.name" . }}-tokenreviewer
|
||||
labels:
|
||||
{{- include "access-engine.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "access-engine.name" . }}-tokenreviewer
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "access-engine.name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
14
charts/access-engine/templates/service.yaml
Normal file
14
charts/access-engine/templates/service.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
name: {{ include "access-engine.name" . }}
|
||||
labels:
|
||||
{{- include "access-engine.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "access-engine.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
10
charts/access-engine/templates/serviceaccount.yaml
Normal file
10
charts/access-engine/templates/serviceaccount.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{{- if eq (include "access-engine.callerAuth.enabled" .) "true" }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
name: {{ include "access-engine.name" . }}
|
||||
labels:
|
||||
{{- include "access-engine.labels" . | nindent 4 }}
|
||||
automountServiceAccountToken: false
|
||||
{{- end }}
|
||||
87
charts/access-engine/values.yaml
Normal file
87
charts/access-engine/values.yaml
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Default chart values. Real pins live in values/*.yaml — never promote a tag.
|
||||
name: access-engine
|
||||
namespace: access-engine
|
||||
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/access-engine
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
# Inert until enabled for an approved pin. The outbox is single-writer.
|
||||
outbox:
|
||||
enabled: false
|
||||
source: ""
|
||||
mountPath: /var/lib/access-engine/outbox
|
||||
size: 1Gi
|
||||
storageClassName: ""
|
||||
existingClaim: ""
|
||||
|
||||
# Inert preparation: caller provides reviewed existing Secret and exact receiver.
|
||||
# The chart never creates/mints sender credentials or registers a sender.
|
||||
auditDelivery:
|
||||
enabled: false
|
||||
url: ""
|
||||
secretName: ""
|
||||
secretKey: ""
|
||||
mountPath: /var/run/secrets/access-engine-audit
|
||||
receiverNamespace: ""
|
||||
receiverPodName: ""
|
||||
receiverPort: 0
|
||||
dnsNamespace: ""
|
||||
dnsPodLabel: ""
|
||||
|
||||
args:
|
||||
- serve
|
||||
- --addr
|
||||
- 0.0.0.0:8080
|
||||
- --registry
|
||||
- /opt/access-engine/examples/tenant-engine/registry_snapshot.json
|
||||
- --policy
|
||||
- /opt/access-engine/examples/tenant-engine/policy_package.md
|
||||
|
||||
service:
|
||||
port: 8080
|
||||
|
||||
health:
|
||||
path: /healthz
|
||||
|
||||
consumer:
|
||||
isolated: false
|
||||
namespace: ""
|
||||
podName: ""
|
||||
|
||||
# disabled keeps the image bootable without TokenReview (isolated canary).
|
||||
# Production pins set warn, then enforce, independently per consumer.
|
||||
# serve-readback pins (FLEX-WP-0035) admit one readback caller via
|
||||
# --readback-caller instead of --caller-binding.
|
||||
readback:
|
||||
enabled: false
|
||||
caller: ""
|
||||
|
||||
callerAuth:
|
||||
mode: disabled
|
||||
audience: access-engine
|
||||
kubernetesURL: https://kubernetes.default.svc
|
||||
binding: ""
|
||||
# Further resource.system=principal pairs, each rendered as its own
|
||||
# --caller-binding (e.g. ops-warden-fetch binds every catalog owner system
|
||||
# to the ops-warden ServiceAccount).
|
||||
extraBindings: []
|
||||
reviewer:
|
||||
mountPath: /var/run/secrets/access-engine-reviewer
|
||||
# Empty: kubelet mints the API server's default audiences so TokenReview
|
||||
# authenticates. A custom audience (e.g. https://kubernetes.default.svc)
|
||||
# 401s on this k3s cluster, whose API audiences are
|
||||
# https://kubernetes.default.svc.cluster.local and k3s.
|
||||
audience: ""
|
||||
expirationSeconds: 3600
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
cpu: 300m
|
||||
memory: 192Mi
|
||||
Loading…
Add table
Add a link
Reference in a new issue