--- # knoe-auth-deployment.yaml # Deploys the knoe-auth pod (Spring Boot + KDC sidecar) to knoe-dev-0 / knoe-system. # Based on deploy/opentofu/k3s/manifests/knoe/prole-auth-deployment.yaml. # Realm: KNOE.DEV (not PROLE.LOCAL) # Image: pulled from Artifact Registry — built by knoe-auth CI pipeline. # # Apply: kubectl -n knoe-system apply -f deploy/gcp/gke/knoe-auth-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: knoe-auth namespace: knoe-system labels: app: knoe-auth spec: replicas: 1 selector: matchLabels: app: knoe-auth template: metadata: labels: app: knoe-auth spec: initContainers: # keytab-bootstrap: runs kadmin.local inside the shared KDC data volume # to create the HTTP service principal and export the keytab before the # Spring Boot container starts. - name: keytab-bootstrap image: us-west3-docker.pkg.dev/plenary-truck-485623-p7/knoe-system/knoe-authority:latest imagePullPolicy: Always command: - /bin/bash - -lc - | set -euo pipefail export DEBIAN_FRONTEND=noninteractive realm="${KNOE_KDC_REALM:-KNOE.DEV}" admin_principal="${KNOE_KDC_ADMIN_PRINCIPAL:-admin/admin}" if [[ "${admin_principal}" != *"@"* ]]; then admin_principal="${admin_principal}@${realm}" fi svc_principal="${KNOE_KERBEROS_SERVICE_PRINCIPAL:?Missing KNOE_KERBEROS_SERVICE_PRINCIPAL}" if [[ "${svc_principal}" != *"@"* ]]; then svc_principal="${svc_principal}@${realm}" fi keytab_out="/etc/knoe/keytabs/http.keytab" mkdir -p "$(dirname "${keytab_out}")" # If a pre-provisioned keytab is provided as a Secret, use it directly. if [[ -f /mnt/keytab-secret/http.keytab ]]; then cp /mnt/keytab-secret/http.keytab "${keytab_out}" chmod 0400 "${keytab_out}" || true exit 0 fi if ! command -v kadmin.local >/dev/null 2>&1; then echo "Installing Kerberos packages..." echo "krb5-config krb5-config/default_realm string ${realm}" | debconf-set-selections || true echo "krb5-config krb5-config/kerberos_servers string 127.0.0.1" | debconf-set-selections || true echo "krb5-config krb5-config/admin_server string 127.0.0.1" | debconf-set-selections || true apt-get update -qq apt-get install -y --no-install-recommends krb5-kdc krb5-admin-server krb5-user dnsutils ca-certificates rm -rf /var/lib/apt/lists/* fi mkdir -p /etc/krb5kdc /var/lib/krb5kdc [[ -f /opt/knoe-kdc/krb5.conf ]] && cp /opt/knoe-kdc/krb5.conf /etc/krb5.conf [[ -f /opt/knoe-kdc/kdc.conf ]] && cp /opt/knoe-kdc/kdc.conf /etc/krb5kdc/kdc.conf [[ -f /opt/knoe-kdc/kadm5.acl ]] && cp /opt/knoe-kdc/kadm5.acl /etc/krb5kdc/kadm5.acl if [[ -z "${KNOE_KDC_MASTER_PASSWORD:-}" ]]; then echo "ERROR: Missing KNOE_KDC_MASTER_PASSWORD" >&2; exit 1 fi if [[ -z "${KNOE_KDC_ADMIN_PASSWORD:-}" ]]; then echo "ERROR: Missing KNOE_KDC_ADMIN_PASSWORD" >&2; exit 1 fi if [[ ! -f /var/lib/krb5kdc/principal ]]; then echo "Initializing realm database for ${realm}..." kdb5_util create -s -r "${realm}" -P "${KNOE_KDC_MASTER_PASSWORD}" fi if ! kadmin.local -q "get_principal ${admin_principal}" >/dev/null 2>&1; then kadmin.local -q "addprinc -pw ${KNOE_KDC_ADMIN_PASSWORD} ${admin_principal}" fi if ! kadmin.local -q "get_principal ${svc_principal}" >/dev/null 2>&1; then echo "Creating service principal ${svc_principal}..." kadmin.local -q "addprinc -randkey ${svc_principal}" fi kadmin.local -q "ktadd -k ${keytab_out} -norandkey ${svc_principal}" chmod 0400 "${keytab_out}" || true echo "Keytab written to ${keytab_out}" env: - name: KNOE_KDC_REALM value: "KNOE.DEV" - name: KNOE_KDC_ADMIN_PRINCIPAL value: "admin/admin" - name: KNOE_KDC_MASTER_PASSWORD valueFrom: secretKeyRef: name: knoe-kdc-secrets key: master_password - name: KNOE_KDC_ADMIN_PASSWORD valueFrom: secretKeyRef: name: knoe-kdc-secrets key: admin_password - name: KNOE_KERBEROS_SERVICE_PRINCIPAL value: "HTTP/auth.knoe.dev" volumeMounts: - name: keytab mountPath: /etc/knoe/keytabs - name: keytab-secret mountPath: /mnt/keytab-secret readOnly: true - name: knoe-kdc-config mountPath: /opt/knoe-kdc - name: knoe-kdc-data mountPath: /var/lib/krb5kdc - name: knoe-kdc-etc mountPath: /etc/krb5kdc containers: # ── Spring Boot / knoe-auth ────────────────────────────────────────── - name: knoe-auth image: us-west3-docker.pkg.dev/plenary-truck-485623-p7/knoe-system/knoe-authority:latest imagePullPolicy: Always ports: - name: http containerPort: 8080 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 20 periodSeconds: 10 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 60 periodSeconds: 30 env: - name: KNOE_AUTH_COOKIE_DOMAIN value: ".knoe.dev" - name: KNOE_AUTH_SESSION_SECRET valueFrom: secretKeyRef: name: knoe-auth-secrets key: sessionSecret # ── Kerberos ─────────────────────────────────────────────────── - name: KNOE_KERBEROS_SERVICE_PRINCIPAL value: "HTTP/auth.knoe.dev@KNOE.DEV" - name: KNOE_KERBEROS_KEYTAB_PATH value: "/etc/knoe/keytabs/http.keytab" - name: KNOE_KERBEROS_REALM value: "KNOE.DEV" # ── Google OAuth2 (enrollment corroboration) ─────────────────── - name: GOOGLE_CLIENT_ID valueFrom: secretKeyRef: name: knoe-auth-google-oidc key: client_id optional: true - name: GOOGLE_CLIENT_SECRET valueFrom: secretKeyRef: name: knoe-auth-google-oidc key: client_secret optional: true # ── Database (CNPG via cluster-internal service) ─────────────── - name: KNOE_DB_URL value: "jdbc:postgresql://knoe-db-rw.knoe-db-0.svc.cluster.local:5432/knoe" - name: KNOE_DB_USER value: "knoe" - name: KNOE_DB_PASSWORD valueFrom: secretKeyRef: name: knoe-db-app key: password optional: true # ── Enrollment ──────────────────────────────────────────────── - name: KNOE_ENROLL_INVITE_TTL_HOURS value: "72" - name: KNOE_ENROLL_OTP_TTL_MINUTES value: "10" - name: KNOE_ENROLL_OTP_MAX_ATTEMPTS value: "3" - name: KNOE_ENROLL_TOTP_ISSUER value: "Knoe.DEV" - name: KNOE_AUTH_BASE_URL value: "https://auth.knoe.dev" # ── Provisioning ───────────────────────────────────────────── - name: KNOE_PROVISIONING_POLL_INTERVAL_MS value: "10000" - name: KNOE_GITEA_URL value: "https://git.knoe.dev" - name: KNOE_GITEA_TOKEN valueFrom: secretKeyRef: name: knoe-gitea-admin key: token optional: true volumeMounts: - name: keytab mountPath: /etc/knoe/keytabs readOnly: true - name: knoe-kdc-config mountPath: /etc/krb5.conf subPath: krb5.conf readOnly: true # ── MIT Kerberos KDC sidecar ───────────────────────────────────────── - name: kdc image: us-west3-docker.pkg.dev/plenary-truck-485623-p7/knoe-system/knoe-authority:latest imagePullPolicy: Always command: ["/bin/bash", "/opt/knoe-kdc/entrypoint.sh"] env: - name: KNOE_KDC_REALM value: "KNOE.DEV" - name: KNOE_KDC_ADMIN_PRINCIPAL value: "admin/admin" - name: KNOE_KDC_MASTER_PASSWORD valueFrom: secretKeyRef: name: knoe-kdc-secrets key: master_password - name: KNOE_KDC_ADMIN_PASSWORD valueFrom: secretKeyRef: name: knoe-kdc-secrets key: admin_password ports: - name: krb5-udp containerPort: 88 protocol: UDP - name: krb5-tcp containerPort: 88 protocol: TCP - name: kpasswd-udp containerPort: 464 protocol: UDP - name: kpasswd-tcp containerPort: 464 protocol: TCP - name: kadmin containerPort: 749 protocol: TCP volumeMounts: - name: knoe-kdc-config mountPath: /opt/knoe-kdc - name: knoe-kdc-data mountPath: /var/lib/krb5kdc - name: knoe-kdc-etc mountPath: /etc/krb5kdc volumes: - name: keytab emptyDir: {} - name: keytab-secret secret: secretName: knoe-auth-keytab optional: true - name: knoe-kdc-config configMap: name: knoe-kdc-config defaultMode: 0755 - name: knoe-kdc-data emptyDir: {} - name: knoe-kdc-etc emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: knoe-auth namespace: knoe-system labels: app: knoe-auth spec: selector: app: knoe-auth ports: - name: http port: 80 targetPort: 8080 - name: krb5-tcp port: 88 targetPort: 88 protocol: TCP - name: krb5-udp port: 88 targetPort: 88 protocol: UDP - name: kadmin port: 749 targetPort: 749 protocol: TCP type: ClusterIP