Files
net-kingdom/sso-mfa/k8s/keycape/deployment.yaml

137 lines
4.0 KiB
YAML

# Deployment + Service — KeyCape (namespace: sso)
#
# KeyCape is the OIDC orchestration layer. It is stateless: all persistent
# state lives in Authelia (session), LLDAP (users), and privacyIDEA (MFA tokens).
# No PVC is required.
#
# Configuration is stored entirely in the keycape-config Secret, which holds
# a complete config.yaml and the RSA private key used to sign OIDC tokens
# issued to downstream applications.
#
# Prerequisites (apply in order):
# 1. keycape-config Secret — run keycape/create-secrets.sh
# 2. keycape-pi-token Secret — run keycape/create-pi-token.sh (after T04 bootstrap)
# 3. This file
# 4. middleware.yaml + ingress.yaml
#
# Container image:
# KeyCape has no published image. Build from ~/key-cape/ and push to a registry,
# or import directly into K3s (see README.md "Building the image").
# Image tag below is a placeholder — update before applying.
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycape
namespace: sso
labels:
app.kubernetes.io/name: keycape
app.kubernetes.io/part-of: net-kingdom-sso-mfa
net-kingdom/component: sso
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: keycape
strategy:
type: RollingUpdate # stateless — safe to roll
template:
metadata:
labels:
app.kubernetes.io/name: keycape
app.kubernetes.io/part-of: net-kingdom-sso-mfa
net-kingdom/component: sso
spec:
securityContext:
runAsNonRoot: true
runAsUser: 65534 # nobody — matches distroless static image
fsGroup: 65534
containers:
- name: keycape
# Image published to self-hosted Gitea OCI registry on CoulombCore (KEY-WP-0002).
# k3s insecure registry configured for 92.205.130.254:32166 — no pull secret needed.
# 2026-05-24: direct-imported into railiance01 k3s for the
# bootstrap-console OIDC/MFA rollout. Use IfNotPresent while the
# HTTP registry push/pull path is being cleaned up.
image: 92.205.130.254:32166/coulomb/key-cape:main-nonce-0601
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
env:
- name: KEYCAPE_CONFIG
value: /etc/keycape/config.yaml
volumeMounts:
# keycape-config Secret provides config.yaml and key.pem
- name: config-secret
mountPath: /etc/keycape
readOnly: true
startupProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
failureThreshold: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 0
periodSeconds: 15
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 0
periodSeconds: 10
failureThreshold: 3
resources:
requests:
cpu: "25m"
memory: "32Mi"
limits:
cpu: "200m"
memory: "128Mi"
volumes:
- name: config-secret
secret:
secretName: keycape-config
# Secret must contain two keys: config.yaml and key.pem
items:
- key: config.yaml
path: config.yaml
- key: key.pem
path: key.pem
mode: 0400 # key.pem is sensitive; restrict to owner read only
---
# Service — ClusterIP; Traefik reaches KeyCape via port 8080.
apiVersion: v1
kind: Service
metadata:
name: keycape
namespace: sso
labels:
app.kubernetes.io/name: keycape
app.kubernetes.io/part-of: net-kingdom-sso-mfa
net-kingdom/component: sso
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: keycape
ports:
- name: http
port: 8080
targetPort: 8080
protocol: TCP