diff --git a/base/ingress/pingora-config.yaml b/base/ingress/pingora-config.yaml index 977aa13..e5a93d5 100644 --- a/base/ingress/pingora-config.yaml +++ b/base/ingress/pingora-config.yaml @@ -21,7 +21,7 @@ data: key_path = "/etc/tls/tls.key" [telemetry] - otlp_endpoint = "http://tempo.monitoring.svc.cluster.local:4318" + otlp_endpoint = "" metrics_port = 9090 # Kubernetes resource names for cert/config watchers. @@ -31,22 +31,20 @@ data: tls_secret = "pingora-tls" config_configmap = "pingora-config" - # DDoS detection — KNN-based per-IP behavioral classification. + # DDoS detection — decision tree + MLP ensemble (compiled-in weights). [ddos] enabled = true - model_path = "/models/ddos_model.bin" - k = 5 + observe_only = true threshold = 0.6 window_secs = 60 window_capacity = 1000 min_events = 10 - # Scanner detection — logistic regression per-request classification. + # Scanner detection — decision tree + MLP ensemble (compiled-in weights). [scanner] enabled = true - model_path = "/models/scanner_model.bin" + observe_only = true threshold = 0.5 - poll_interval_secs = 30 bot_cache_ttl_secs = 86400 [[scanner.allowlist]] @@ -61,6 +59,10 @@ data: dns_suffixes = ["search.msn.com"] cidrs = ["40.77.167.0/24", "157.55.39.0/24"] + [[scanner.allowlist]] + ua_prefix = "containerd" + reason = "Container registry client (buildkitd/containerd)" + # Rate limiting — leaky bucket per-identity throttling. [rate_limit] enabled = true @@ -146,7 +148,7 @@ data: backend = "http://messages-frontend.lasuite.svc.cluster.local:80" [[routes]] - host_prefix = "chat" + host_prefix = "messages" backend = "http://tuwunel.matrix.svc.cluster.local:6167" websocket = true @@ -181,10 +183,10 @@ data: backend = "http://gitea-http.devtools.svc.cluster.local:3000" websocket = true - # auth: login-ui handles browser UI; Hydra handles OAuth2/OIDC; Kratos handles self-service flows. + # auth: unified IAM dashboard; Hydra handles OAuth2/OIDC; Kratos handles self-service flows. [[routes]] host_prefix = "auth" - backend = "http://login-ui.ory.svc.cluster.local:3000" + backend = "http://kratos-admin-ui.ory.svc.cluster.local:3000" [[routes.paths]] prefix = "/oauth2" @@ -204,10 +206,6 @@ data: backend = "http://kratos-public.ory.svc.cluster.local:80" strip_prefix = true - [[routes]] - host_prefix = "admin" - backend = "http://kratos-admin-ui.ory.svc.cluster.local:3000" - [[routes]] host_prefix = "integration" backend = "http://integration.lasuite.svc.cluster.local:80" diff --git a/base/ory/hydra-values.yaml b/base/ory/hydra-values.yaml index a172b02..6f7c067 100644 --- a/base/ory/hydra-values.yaml +++ b/base/ory/hydra-values.yaml @@ -16,9 +16,12 @@ hydra: error: https://auth.DOMAIN_SUFFIX/error ttl: - # Short access tokens — API-level auth window is tight. - access_token: 5m - id_token: 5m + # Login session persists 30 days — matches Kratos session lifespan so the + # Hydra session cookie survives browser restarts and prompt=none keeps working. + authentication_session: 720h + # Access/ID tokens renewed via refresh token; 1h keeps the window short. + access_token: 1h + id_token: 1h # Refresh tokens last 30 days; Kratos session carries silent re-auth. # Revoking a Kratos session (sunbeam user disable) prevents refresh. refresh_token: 720h @@ -42,6 +45,7 @@ secret: hydra-maester: enabledNamespaces: - lasuite + - matrix deployment: extraEnv: diff --git a/base/ory/kratos-admin-deployment.yaml b/base/ory/kratos-admin-deployment.yaml index 47a82a4..0acf347 100644 --- a/base/ory/kratos-admin-deployment.yaml +++ b/base/ory/kratos-admin-deployment.yaml @@ -25,12 +25,18 @@ spec: value: "http://kratos-public.ory.svc.cluster.local:80" - name: KRATOS_ADMIN_URL value: "http://kratos-admin.ory.svc.cluster.local:80" + - name: HYDRA_ADMIN_URL + value: "http://hydra-admin.ory.svc.cluster.local:4445" - name: PUBLIC_URL - value: "https://admin.DOMAIN_SUFFIX" + value: "https://auth.DOMAIN_SUFFIX" - name: CUNNINGHAM_THEME value: "dsfr-light" - name: PORT value: "3000" + - name: TRUSTED_CLIENT_IDS + value: "" + - name: SEAWEEDFS_S3_URL + value: "http://seaweedfs-filer.storage.svc.cluster.local:8333" - name: ADMIN_IDENTITY_IDS valueFrom: secretKeyRef: @@ -46,9 +52,19 @@ spec: secretKeyRef: name: kratos-admin-ui-secrets key: csrf-cookie-secret + - name: SEAWEEDFS_ACCESS_KEY + valueFrom: + secretKeyRef: + name: kratos-admin-ui-secrets + key: s3-access-key + - name: SEAWEEDFS_SECRET_KEY + valueFrom: + secretKeyRef: + name: kratos-admin-ui-secrets + key: s3-secret-key resources: limits: - memory: 256Mi + memory: 384Mi requests: memory: 64Mi cpu: 25m diff --git a/base/ory/kratos-selfservice-urls.yaml b/base/ory/kratos-selfservice-urls.yaml index d2fdd8a..5b0437f 100644 --- a/base/ory/kratos-selfservice-urls.yaml +++ b/base/ory/kratos-selfservice-urls.yaml @@ -17,7 +17,7 @@ data: - https://meet.DOMAIN_SUFFIX/ - https://drive.DOMAIN_SUFFIX/ - https://mail.DOMAIN_SUFFIX/ - - https://chat.DOMAIN_SUFFIX/ + - https://messages.DOMAIN_SUFFIX/ - https://people.DOMAIN_SUFFIX/ - https://src.DOMAIN_SUFFIX/ - https://admin.DOMAIN_SUFFIX/ diff --git a/base/ory/kratos-values.yaml b/base/ory/kratos-values.yaml index e3fc53b..bebeb5d 100644 --- a/base/ory/kratos-values.yaml +++ b/base/ory/kratos-values.yaml @@ -16,7 +16,7 @@ kratos: - https://meet.DOMAIN_SUFFIX/ - https://drive.DOMAIN_SUFFIX/ - https://mail.DOMAIN_SUFFIX/ - - https://chat.DOMAIN_SUFFIX/ + - https://messages.DOMAIN_SUFFIX/ - https://people.DOMAIN_SUFFIX/ - https://src.DOMAIN_SUFFIX/ - https://find.DOMAIN_SUFFIX/ @@ -32,14 +32,19 @@ kratos: recovery: enabled: true ui_url: https://auth.DOMAIN_SUFFIX/recovery + verification: + enabled: true + ui_url: https://auth.DOMAIN_SUFFIX/verification settings: ui_url: https://auth.DOMAIN_SUFFIX/settings identity: - default_schema_id: default + default_schema_id: employee schemas: - - id: default - url: base64://ewogICIkaWQiOiAiaHR0cHM6Ly9zY2hlbWFzLnN1bmJlYW0uc3R1ZGlvL2lkZW50aXR5Lmpzb24iLAogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInR5cGUiOiAib2JqZWN0IiwKICAidGl0bGUiOiAiUGVyc29uIiwKICAicHJvcGVydGllcyI6IHsKICAgICJ0cmFpdHMiOiB7CiAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICJlbWFpbCI6IHsKICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAiZm9ybWF0IjogImVtYWlsIiwKICAgICAgICAgICJ0aXRsZSI6ICJFbWFpbCIsCiAgICAgICAgICAib3J5LnNoL2tyYXRvcyI6IHsKICAgICAgICAgICAgImNyZWRlbnRpYWxzIjogewogICAgICAgICAgICAgICJwYXNzd29yZCI6IHsKICAgICAgICAgICAgICAgICJpZGVudGlmaWVyIjogdHJ1ZQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlY292ZXJ5IjogewogICAgICAgICAgICAgICJ2aWEiOiAiZW1haWwiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2ZXJpZmljYXRpb24iOiB7CiAgICAgICAgICAgICAgInZpYSI6ICJlbWFpbCIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgIm5hbWUiOiB7CiAgICAgICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICJmaXJzdCI6IHsgInR5cGUiOiAic3RyaW5nIiwgInRpdGxlIjogIkZpcnN0IG5hbWUiIH0sCiAgICAgICAgICAgICJsYXN0IjogeyAidHlwZSI6ICJzdHJpbmciLCAidGl0bGUiOiAiTGFzdCBuYW1lIiB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9LAogICAgICAicmVxdWlyZWQiOiBbImVtYWlsIl0KICAgIH0KICB9Cn0K + - id: employee + url: base64://ewogICIkaWQiOiAiaHR0cHM6Ly9zY2hlbWFzLnN1bmJlYW0uc3R1ZGlvL2VtcGxveWVlLmpzb24iLAogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInR5cGUiOiAib2JqZWN0IiwKICAidGl0bGUiOiAiRW1wbG95ZWUiLAogICJwcm9wZXJ0aWVzIjogewogICAgInRyYWl0cyI6IHsKICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgImVtYWlsIjogewogICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICJmb3JtYXQiOiAiZW1haWwiLAogICAgICAgICAgInRpdGxlIjogIkVtYWlsIiwKICAgICAgICAgICJvcnkuc2gva3JhdG9zIjogewogICAgICAgICAgICAiY3JlZGVudGlhbHMiOiB7ICJwYXNzd29yZCI6IHsgImlkZW50aWZpZXIiOiB0cnVlIH0gfSwKICAgICAgICAgICAgInJlY292ZXJ5IjogeyAidmlhIjogImVtYWlsIiB9LAogICAgICAgICAgICAidmVyaWZpY2F0aW9uIjogeyAidmlhIjogImVtYWlsIiB9CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiZ2l2ZW5fbmFtZSI6IHsgInR5cGUiOiAic3RyaW5nIiwgInRpdGxlIjogIkZpcnN0IG5hbWUiIH0sCiAgICAgICAgImZhbWlseV9uYW1lIjogeyAidHlwZSI6ICJzdHJpbmciLCAidGl0bGUiOiAiTGFzdCBuYW1lIiB9LAogICAgICAgICJtaWRkbGVfbmFtZSI6IHsgInR5cGUiOiAic3RyaW5nIiwgInRpdGxlIjogIk1pZGRsZSBuYW1lIiB9LAogICAgICAgICJuaWNrbmFtZSI6IHsgInR5cGUiOiAic3RyaW5nIiwgInRpdGxlIjogIk5pY2tuYW1lIiB9LAogICAgICAgICJwaWN0dXJlIjogeyAidHlwZSI6ICJzdHJpbmciLCAiZm9ybWF0IjogInVyaSIsICJ0aXRsZSI6ICJQcm9maWxlIHBpY3R1cmUiIH0sCiAgICAgICAgInBob25lX251bWJlciI6IHsgInR5cGUiOiAic3RyaW5nIiwgInRpdGxlIjogIlBob25lIG51bWJlciIgfSwKICAgICAgICAiam9iX3RpdGxlIjogeyAidHlwZSI6ICJzdHJpbmciLCAidGl0bGUiOiAiSm9iIHRpdGxlIiB9LAogICAgICAgICJkZXBhcnRtZW50IjogeyAidHlwZSI6ICJzdHJpbmciLCAidGl0bGUiOiAiRGVwYXJ0bWVudCIgfSwKICAgICAgICAib2ZmaWNlX2xvY2F0aW9uIjogeyAidHlwZSI6ICJzdHJpbmciLCAidGl0bGUiOiAiT2ZmaWNlIGxvY2F0aW9uIiB9LAogICAgICAgICJlbXBsb3llZV9pZCI6IHsgInR5cGUiOiAic3RyaW5nIiwgInRpdGxlIjogIkVtcGxveWVlIElEIiB9LAogICAgICAgICJoaXJlX2RhdGUiOiB7ICJ0eXBlIjogInN0cmluZyIsICJmb3JtYXQiOiAiZGF0ZSIsICJ0aXRsZSI6ICJIaXJlIGRhdGUiIH0sCiAgICAgICAgIm1hbmFnZXIiOiB7ICJ0eXBlIjogInN0cmluZyIsICJ0aXRsZSI6ICJNYW5hZ2VyIiB9CiAgICAgIH0sCiAgICAgICJyZXF1aXJlZCI6IFsiZW1haWwiXQogICAgfQogIH0KfQo= + - id: external + url: base64://ewogICIkaWQiOiAiaHR0cHM6Ly9zY2hlbWFzLnN1bmJlYW0uc3R1ZGlvL2V4dGVybmFsLmpzb24iLAogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInR5cGUiOiAib2JqZWN0IiwKICAidGl0bGUiOiAiRXh0ZXJuYWwgVXNlciIsCiAgInByb3BlcnRpZXMiOiB7CiAgICAidHJhaXRzIjogewogICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAiZW1haWwiOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgImZvcm1hdCI6ICJlbWFpbCIsCiAgICAgICAgICAidGl0bGUiOiAiRW1haWwiLAogICAgICAgICAgIm9yeS5zaC9rcmF0b3MiOiB7CiAgICAgICAgICAgICJjcmVkZW50aWFscyI6IHsgInBhc3N3b3JkIjogeyAiaWRlbnRpZmllciI6IHRydWUgfSB9LAogICAgICAgICAgICAicmVjb3ZlcnkiOiB7ICJ2aWEiOiAiZW1haWwiIH0sCiAgICAgICAgICAgICJ2ZXJpZmljYXRpb24iOiB7ICJ2aWEiOiAiZW1haWwiIH0KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJnaXZlbl9uYW1lIjogeyAidHlwZSI6ICJzdHJpbmciLCAidGl0bGUiOiAiRmlyc3QgbmFtZSIgfSwKICAgICAgICAiZmFtaWx5X25hbWUiOiB7ICJ0eXBlIjogInN0cmluZyIsICJ0aXRsZSI6ICJMYXN0IG5hbWUiIH0sCiAgICAgICAgIm5pY2tuYW1lIjogeyAidHlwZSI6ICJzdHJpbmciLCAidGl0bGUiOiAiTmlja25hbWUiIH0sCiAgICAgICAgInBpY3R1cmUiOiB7ICJ0eXBlIjogInN0cmluZyIsICJmb3JtYXQiOiAidXJpIiwgInRpdGxlIjogIlByb2ZpbGUgcGljdHVyZSIgfQogICAgICB9LAogICAgICAicmVxdWlyZWQiOiBbImVtYWlsIl0KICAgIH0KICB9Cn0K courier: smtp: @@ -56,6 +61,8 @@ kratos: # receive it. Without this Kratos scopes the cookie to auth.* only, causing # redirect loops on admin.*. domain: DOMAIN_SUFFIX + persistent: true + lifespan: 720h serve: public: diff --git a/base/ory/kustomization.yaml b/base/ory/kustomization.yaml index 72928ad..adf965f 100644 --- a/base/ory/kustomization.yaml +++ b/base/ory/kustomization.yaml @@ -9,7 +9,6 @@ kind: Kustomization resources: - namespace.yaml - - login-ui-deployment.yaml - kratos-admin-deployment.yaml # Hydra chart CRDs are not rendered by helm template; apply manually. - hydra-oauth2client-crd.yaml diff --git a/overlays/production/cert-manager.yaml b/overlays/production/cert-manager.yaml index a4911d5..74ae3f7 100644 --- a/overlays/production/cert-manager.yaml +++ b/overlays/production/cert-manager.yaml @@ -58,12 +58,15 @@ spec: - meet.DOMAIN_SUFFIX - drive.DOMAIN_SUFFIX - mail.DOMAIN_SUFFIX - - chat.DOMAIN_SUFFIX + - messages.DOMAIN_SUFFIX - people.DOMAIN_SUFFIX - src.DOMAIN_SUFFIX - auth.DOMAIN_SUFFIX - s3.DOMAIN_SUFFIX - - grafana.DOMAIN_SUFFIX + - metrics.DOMAIN_SUFFIX + - systemmetrics.DOMAIN_SUFFIX + - systemlogs.DOMAIN_SUFFIX + - systemtracing.DOMAIN_SUFFIX - admin.DOMAIN_SUFFIX - integration.DOMAIN_SUFFIX - livekit.DOMAIN_SUFFIX diff --git a/overlays/production/kustomization.yaml b/overlays/production/kustomization.yaml index 8424ce5..ef09472 100644 --- a/overlays/production/kustomization.yaml +++ b/overlays/production/kustomization.yaml @@ -7,6 +7,7 @@ kind: Kustomization # sunbeam apply --env production --domain yourdomain.com resources: + - ../../base/build - ../../base/longhorn - ../../base/cert-manager - ../../base/ingress @@ -18,6 +19,7 @@ resources: - ../../base/devtools - ../../base/vso - ../../base/monitoring + - ../../base/matrix # cert-manager ClusterIssuer + Certificate (requires cert-manager to be installed) - cert-manager.yaml # CNPG daily backup schedule @@ -37,6 +39,36 @@ images: newName: src.DOMAIN_SUFFIX/studio/meet-frontend newTag: latest + # people-frontend — built from source with estudio theme baked in. + - name: lasuite/people-frontend + newName: src.DOMAIN_SUFFIX/studio/people-frontend + newTag: latest + + # Messages — built from source and pushed to Gitea registry. + - name: messages-backend + newName: src.DOMAIN_SUFFIX/studio/messages-backend + newTag: latest + - name: messages-frontend + newName: src.DOMAIN_SUFFIX/studio/messages-frontend + newTag: latest + - name: messages-mta-in + newName: src.DOMAIN_SUFFIX/studio/messages-mta-in + newTag: latest + - name: messages-mta-out + newName: src.DOMAIN_SUFFIX/studio/messages-mta-out + newTag: latest + - name: messages-mpa + newName: src.DOMAIN_SUFFIX/studio/messages-mpa + newTag: latest + - name: messages-socks-proxy + newName: src.DOMAIN_SUFFIX/studio/messages-socks-proxy + newTag: latest + + # Tuwunel Matrix homeserver — built and pushed by `sunbeam build tuwunel` + - name: tuwunel + newName: src.DOMAIN_SUFFIX/studio/tuwunel + newTag: latest + patches: # Pingora host ports — bind :80/:443 to the host network - path: patch-pingora-hostport.yaml @@ -53,5 +85,18 @@ patches: # OpenSearch: expand PVC to 50 Gi - path: patch-opensearch-storage.yaml + # Tuwunel: production resource limits and PVC sizing + - path: patch-tuwunel.yaml + # SeaweedFS volume: expand PVC to 600 Gi - path: patch-seaweedfs-volume-size.yaml + + # MTA-in: bind port 25 to the host for inbound email delivery + - patch: | + - op: add + path: /spec/template/spec/containers/0/ports/0/hostPort + value: 25 + target: + kind: Deployment + name: messages-mta-in + namespace: lasuite diff --git a/scripts/local-up.sh b/scripts/local-up.sh index 3a95744..4c72191 100755 --- a/scripts/local-up.sh +++ b/scripts/local-up.sh @@ -197,7 +197,7 @@ echo " Auth: https://auth.${DOMAIN}/" echo " Docs: https://docs.${DOMAIN}/" echo " Meet: https://meet.${DOMAIN}/" echo " Drive: https://drive.${DOMAIN}/" -echo " Chat: https://chat.${DOMAIN}/" +echo " Messages: https://messages.${DOMAIN}/" echo " Mail: https://mail.${DOMAIN}/" echo " People: https://people.${DOMAIN}/" echo " Gitea: https://src.${DOMAIN}/" diff --git a/scripts/local-urls.sh b/scripts/local-urls.sh index 602877c..f218c5b 100755 --- a/scripts/local-urls.sh +++ b/scripts/local-urls.sh @@ -18,7 +18,7 @@ echo " Docs: https://docs.${BASE}" echo " Meet: https://meet.${BASE}" echo " Drive: https://drive.${BASE}" echo " Mail: https://mail.${BASE}" -echo " Chat: https://chat.${BASE}" +echo " Messages: https://messages.${BASE}" echo " People: https://people.${BASE}" echo " Source: https://src.${BASE}" echo " Auth: https://auth.${BASE}"