# Deployment + Service — KeyCape (namespace: sso) # # KeyCape orchestrates OIDC. Pending logins and authorization codes are process-local; # use one replica with Recreate during replacement. Persistent identity state remains # in Authelia, LLDAP and privacyIDEA. Scoped authentication policy and receipts # persist separately in the keycape-authentication-policy PVC. # # 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-factor-read Secret — ESO delivery owned by railiance-platform RPF-WP-0040 # 3. policy-pvc.yaml # 4. This file # 5. middleware.yaml + ingress.yaml # # Container image: # KeyCape publishes immutable main- tags through Forgejo Actions. # K3s pulls through the HTTPS Forgejo registry origin. 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: Recreate # one issuer instance; process-local login/code state 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 the self-hosted Forgejo OCI registry (KEY-WP-0002). # KEY-WP-0012: canonical OIDC subject resolution for /userinfo. image: forgejo.coulomb.social/coulomb/key-cape@sha256:db2c5a13a47839049349e881c8d19bc39f720ee69d8518f9f2eba2b1f98af9d5 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 protocol: TCP env: - name: KEYCAPE_POLICY_PATH value: /var/lib/keycape-policy/policy.json - name: KEYCAPE_ACCOUNT_PORTAL_URL value: https://users.coulomb.social - name: KEYCAPE_BROWSER_LOGOUT_URL value: https://auth.coulomb.social/logout - name: KEYCAPE_CONFIG value: /etc/keycape/config.yaml - name: KEYCAPE_RAPP_QONTO_CLIENT_SECRET valueFrom: secretKeyRef: name: keycape-rapp-qonto-client key: client-secret - name: KEYCAPE_SECRETS_ENGINE_APPROVAL_CLIENT_SECRET valueFrom: secretKeyRef: name: keycape-secrets-engine-approval-client key: client-secret - name: KEYCAPE_APPROVAL_ENGINE_OPERATOR_CLIENT_SECRET valueFrom: secretKeyRef: name: keycape-approval-engine-operator-client key: client-secret volumeMounts: - name: authentication-policy mountPath: /var/lib/keycape-policy - name: factor-token mountPath: /etc/keycape-factor readOnly: true # 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: /readyz port: 8080 initialDelaySeconds: 0 periodSeconds: 10 failureThreshold: 3 resources: requests: cpu: "25m" memory: "32Mi" limits: cpu: "200m" memory: "128Mi" volumes: - name: authentication-policy persistentVolumeClaim: claimName: keycape-authentication-policy - name: factor-token secret: secretName: keycape-factor-read defaultMode: 0440 items: - key: admin-token path: admin-token - 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