# Ory Kratos — identity service for honeyDue. # # Deployed once the operator has completed the prerequisites in kratos/README.md # (Neon `kratos` database, auth.myhoneydue.com DNS, Apple Sign In OIDC client, # and the kratos-secrets Secret). Until then 03-deploy.sh skips the Kratos # apply, so the existing stack is unaffected. # # IMAGE: pinned to oryd/kratos v26.2.0 (CalVer current stable as of 2026-06-03) # with the linux/amd64 digest. The schema-migration Job is in migrate-job.yaml # and runs before this Deployment rolls. # # OIDC: currently Apple-only (configmap.yaml providers[0]). Google was scoped # out at deploy time; adding it later is additive — append to providers[] in # configmap.yaml and add the matching CLIENT_SECRET env binding here. --- apiVersion: apps/v1 kind: Deployment metadata: name: kratos namespace: honeydue labels: app.kubernetes.io/name: kratos app.kubernetes.io/part-of: honeydue spec: replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 1 selector: matchLabels: app.kubernetes.io/name: kratos template: metadata: labels: app.kubernetes.io/name: kratos app.kubernetes.io/part-of: honeydue spec: automountServiceAccountToken: false securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - name: kratos image: oryd/kratos:v26.2.0@sha256:92eedc292ff8e1a918ac442c88ed0abe44610c75121700963114549908a45ac3 imagePullPolicy: IfNotPresent args: - serve - --config - /etc/kratos/kratos.yml - --watch-courier # send verification/recovery email in-process ports: - name: public containerPort: 4433 - name: admin containerPort: 4434 env: # Kratos is configured natively via env vars; secrets come from # the kratos-secrets Secret rather than the ConfigMap. - name: DSN valueFrom: { secretKeyRef: { name: kratos-secrets, key: dsn } } - name: SECRETS_COOKIE valueFrom: { secretKeyRef: { name: kratos-secrets, key: secrets_cookie } } - name: SECRETS_CIPHER valueFrom: { secretKeyRef: { name: kratos-secrets, key: secrets_cipher } } - name: COURIER_SMTP_CONNECTION_URI valueFrom: { secretKeyRef: { name: kratos-secrets, key: smtp_connection_uri } } # OIDC provider secrets — index must match the providers list # order in configmap.yaml. Apple-only for now (index 0). - name: SELFSERVICE_METHODS_OIDC_CONFIG_PROVIDERS_0_APPLE_PRIVATE_KEY valueFrom: { secretKeyRef: { name: kratos-secrets, key: apple_private_key } } volumeMounts: - name: config mountPath: /etc/kratos readOnly: true - name: tmp mountPath: /tmp readinessProbe: httpGet: path: /health/ready port: 4434 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: path: /health/alive port: 4434 initialDelaySeconds: 10 periodSeconds: 30 resources: requests: cpu: 100m memory: 128Mi limits: cpu: "1" memory: 512Mi securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] volumes: - name: config configMap: name: kratos-config - name: tmp emptyDir: sizeLimit: 64Mi --- apiVersion: v1 kind: Service metadata: name: kratos namespace: honeydue labels: app.kubernetes.io/name: kratos app.kubernetes.io/part-of: honeydue spec: selector: app.kubernetes.io/name: kratos ports: - name: public port: 4433 targetPort: 4433 - name: admin port: 4434 targetPort: 4434 --- # Ingress to Kratos. Traefik (the auth.myhoneydue.com IngressRoute) reaches # only the public API :4433. The honeyDue api pods reach the public API :4433 # (session whoami) AND the admin API :4434 (identity deletion on account # close). The admin API :4434 takes no other cluster ingress. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-ingress-to-kratos namespace: honeydue spec: podSelector: matchLabels: app.kubernetes.io/name: kratos policyTypes: - Ingress ingress: # Traefik ingress controller -> public API only. - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports: - port: 4433 protocol: TCP # honeyDue api pods -> public API (whoami) + admin API (identity deletion). - from: - podSelector: matchLabels: app.kubernetes.io/name: api ports: - port: 4433 protocol: TCP - port: 4434 protocol: TCP --- # Kratos egress: DNS, the Neon Postgres database, SMTP, and HTTPS to the # OIDC providers (Apple/Google token + JWKS endpoints). apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress-from-kratos namespace: honeydue spec: podSelector: matchLabels: app.kubernetes.io/name: kratos policyTypes: - Egress egress: - to: - namespaceSelector: {} ports: - port: 53 protocol: UDP - port: 53 protocol: TCP # Neon Postgres (external) - to: - ipBlock: cidr: 0.0.0.0/0 except: - 10.42.0.0/16 - 10.43.0.0/16 ports: - port: 5432 protocol: TCP # SMTP (Fastmail) + HTTPS to Apple/Google OIDC endpoints (external) - to: - ipBlock: cidr: 0.0.0.0/0 except: - 10.42.0.0/16 - 10.43.0.0/16 ports: - port: 465 protocol: TCP - port: 443 protocol: TCP