From d4a57cc4f54f40ab80c164f70fd648d95dc27291 Mon Sep 17 00:00:00 2001 From: migatu Date: Wed, 22 Jul 2026 23:26:38 +0200 Subject: [PATCH 1/2] feat(astrololo): wejscie po https z wlasnym CA (PRE-16) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do tej pory aplikacja chodzila po zwyklym http, a logowanie szlo przez HTTP Basic — czyli haslo leciało siecia w postaci trywialnej do podsluchania. Poza bezpieczenstwem TLS naprawia DWIE funkcje zepsute dzis z tego samego powodu: geolokalizacja przegladarki („Tu i teraz") i kopiowanie promptu do schowka dzialaja wylacznie w secure context, wiec po http po prostu odmawialy. Wlasne CA, nie Let's Encrypt — klaster stoi w LAN (traefik trzyma LoadBalancera na 192.168.1.x), wiec walidacja HTTP-01 nie ma jak dojsc z internetu, a DNS-01 wymagalby trzymania w klastrze tokena API do domeny. Co dochodzi: - tls.yaml — Issuer selfSigned -> korzen CA (10 lat, importowany raz do przegladarki) -> Issuer CA -> certyfikat serwera (90 dni, odnawiany sam). Krotki termin certyfikatu serwera jest CELOWY: odnawianie sprawdza sie wtedy co kwartal, a nie dopiero za dekade. - ingress.yaml — wejscie po https + naglowki (HSTS rok, nosniff, frameDeny) oraz osobny Ingress na porcie 80 robiacy przekierowanie. Rozdzielone swiadomie: gdyby redirect wisial na tym samym routerze co wejscie po https, odsylalby sam do siebie w kolko. - presentation: Service NodePort -> ClusterIP. NodePort byl druga, nieszyfrowana droga do aplikacji, czyli obejsciem calego PRE-16. Zmiana wymagajaca uwagi: TRUST_PROXY=true. Za Ingressem bezposrednim rozmowca jest zawsze pod Traefika, wiec bez tego limit zadan liczylby WSZYSTKICH do jednego wiadra i pierwsza osoba, ktora go wyklika, odcielaby pozostalych. Sprawdzone: Ingress i Middleware przechodza `kubectl apply --dry-run=server` na zywym klastrze (CRD traefik.io/v1alpha1 sa, entrypointy web/websecure sa). Obiekty cert-managera zwalidowane offline wobec oficjalnego schematu z CRD v1.21.0 z additionalProperties=false — literowka w nazwie pola zostalaby zlapana. `kubectl kustomize` przechodzi dla obu profili (bazowego i swisseph). Co-Authored-By: Claude Opus 4.8 --- astrololo/README.md | 84 +++++++++++++++++++++++++++++++++--- astrololo/ingress.yaml | 75 ++++++++++++++++++++++++++++++++ astrololo/kustomization.yaml | 2 + astrololo/presentation.yaml | 12 +++++- astrololo/tls.yaml | 65 ++++++++++++++++++++++++++++ 5 files changed, 230 insertions(+), 8 deletions(-) create mode 100644 astrololo/ingress.yaml create mode 100644 astrololo/tls.yaml diff --git a/astrololo/README.md b/astrololo/README.md index c6e2900..a3b726a 100644 --- a/astrololo/README.md +++ b/astrololo/README.md @@ -3,8 +3,10 @@ Manifesty k8s składane Kustomize. Obrazy podbija automatycznie image-updater (`kustomization.yaml` → `images: newTag`) po każdym buildzie z repo aplikacji. -Warstwy: `presentation` (NodePort, wejście z przeglądarki) → `logic` → `data` -(pliki Excel montowane **z NFS**, nie z obrazu). +Warstwy: `presentation` (wejście z przeglądarki przez **Ingress po https**) → +`logic` → `data` (pliki Excel montowane **z NFS**, nie z obrazu). + +Adres aplikacji: **https://astrololo.czernobog.pl** — patrz [TLS](#-tls--wymagane-kroki-przed-wdrożeniem). ## ⚠️ Sekret `astrololo-auth` — utwórz PRZED wdrożeniem @@ -50,12 +52,79 @@ trzech** usług naraz, inaczej przestaną się dogadywać.) ### Sprawdzenie po wdrożeniu ```bash kubectl -n astrololo rollout status deploy/presentation deploy/logic deploy/data -NODE_PORT=$(kubectl -n astrololo get svc presentation -o jsonpath='{.spec.ports[0].nodePort}') -curl -s -o /dev/null -w "bez hasła: %{http_code}\n" http://:$NODE_PORT/ -curl -s -o /dev/null -w "z hasłem: %{http_code}\n" -u astrololo:'' http://:$NODE_PORT/ +curl -s -o /dev/null -w "bez hasła: %{http_code}\n" https://astrololo.czernobog.pl/ +curl -s -o /dev/null -w "z hasłem: %{http_code}\n" -u astrololo:'' https://astrololo.czernobog.pl/ ``` Oczekiwane: **401** bez hasła, **200** z hasłem. `/health` zostaje publiczny (sondy k8s). +## 🔒 TLS — wymagane kroki przed wdrożeniem + +Do tej pory Basic Auth szedł siecią po zwykłym http, czyli **hasło dało się +podsłuchać** (base64 to nie szyfrowanie). Poza tym http blokował dwie funkcje, +bo przeglądarki udostępniają je wyłącznie w tzw. *secure context*: +**geolokalizacja** („Tu i teraz") i **kopiowanie do schowka**. Certyfikat załatwia +oba tematy naraz. + +Certyfikat wystawia **własne CA** trzymane w klastrze (cert-manager). Let's Encrypt +odpada, bo klaster stoi w LAN — walidacja HTTP-01 nie ma jak do niego dojść z +internetu, a DNS-01 wymagałby trzymania tu tokena API do domeny. + +**Kolejność ma znaczenie — oba kroki PRZED synchronizacją ArgoCD.** + +### 1. cert-manager (jednorazowo, cały klaster) +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.21.0/cert-manager.yaml +kubectl -n cert-manager rollout status deploy/cert-manager deploy/cert-manager-webhook +``` +Bez tego API odrzuci `Certificate` i `Issuer` jako nieznane rodzaje zasobów, +a ArgoCD pokaże aplikację jako niezsynchronizowaną. + +### 2. DNS: `astrololo.czernobog.pl` → adres Traefika +```bash +kubectl -n kube-system get svc traefik -o jsonpath='{.status.loadBalancer.ingress[*].ip}'; echo +``` +Wpis w routerze / lokalnym DNS-ie (albo doraźnie `/etc/hosts`). **Service +`presentation` jest teraz `ClusterIP`** — NodePort był drugą, nieszyfrowaną drogą +do aplikacji, więc został zdjęty. Zanim DNS zacznie odpowiadać, jedyne wejście to: +```bash +kubectl -n astrololo port-forward svc/presentation 8000:8000 # awaryjnie, http://localhost:8000 +``` + +### 3. Zaufanie do własnego CA (raz na urządzenie) +Bez tego przeglądarka pokaże ostrzeżenie o certyfikacie. Korzeń ważny 10 lat, +więc import robisz raz: +```bash +kubectl -n astrololo get secret astrololo-ca -o jsonpath='{.data.ca\.crt}' \ + | base64 -d > astrololo-ca.crt + +# macOS — do systemowego zaufania (poprosi o hasło administratora) +sudo security add-trusted-cert -d -r trustRoot \ + -k /Library/Keychains/System.keychain astrololo-ca.crt + +# Linux (Debian/Ubuntu) +sudo cp astrololo-ca.crt /usr/local/share/ca-certificates/ && sudo update-ca-certificates +``` +Firefox ma własny magazyn — tam import przez *Ustawienia → Prywatność → +Wyświetl certyfikaty → Organy certyfikacji*. + +### Sprawdzenie samego TLS +```bash +# certyfikat wystawiony i gotowy +kubectl -n astrololo get certificate +# oczekiwane: astrololo-ca True, astrololo-tls True + +# http odsyła na https +curl -sI http://astrololo.czernobog.pl/ | head -2 # 301 + Location: https://... + +# HSTS obecny +curl -skI -u astrololo:'' https://astrololo.czernobog.pl/ | grep -i strict-transport +``` + +### Odnawianie +Certyfikat serwera żyje 90 dni i odnawia się sam 30 dni przed końcem. Termin jest +krótki **celowo** — odnawianie sprawdza się wtedy w praktyce co kwartał, a nie +dopiero za dziesięć lat, gdy nikt nie będzie pamiętał, jak to było skonfigurowane. + ## Klucze do modeli w chmurze — sekret `astrololo-llm` (opcjonalny) Domyślnie działa **model lokalny** i nic nie opuszcza sieci. Żeby móc wybrać w UI @@ -94,8 +163,9 @@ gdzie faktycznie stoi Ollama/vLLM. Konfiguracja jest **per dostawca** > Retention — patrz LOG-32. ## Czego to nie załatwia -- **Brak TLS** — Basic Auth idzie po sieci w postaci łatwej do podsłuchania. Przy - niezaufanej sieci potrzebny ingress z certyfikatem. +- **Własne CA to nie to samo co publiczne zaufanie** — każde nowe urządzenie + wymaga importu korzenia (krok 3 powyżej). Gdyby aplikacja miała kiedyś wyjść + na świat, właściwą drogą jest Let's Encrypt przez DNS-01. - **NFS `192.168.1.34:/mnt/Tank1/astrololo`** — kto ma dostęp do share'u, bierze pliki baz **z pominięciem całej aplikacji**. Do zamknięcia po stronie infrastruktury (eksport tylko dla IP węzłów, `root_squash`, najlepiej read-only). diff --git a/astrololo/ingress.yaml b/astrololo/ingress.yaml new file mode 100644 index 0000000..01d4f8a --- /dev/null +++ b/astrololo/ingress.yaml @@ -0,0 +1,75 @@ +# Wejście do aplikacji po HTTPS (PRE-16). +# +# Poza bezpieczeństwem — Basic Auth po zwykłym http leci siecią czytelny dla +# każdego, kto słucha — TLS naprawia DWIE funkcje zepsute dziś z tego samego +# powodu: geolokalizacja przeglądarki („Tu i teraz") oraz kopiowanie promptu do +# schowka działają wyłącznie w tzw. secure context i po http po prostu odmawiają. +--- +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: security-headers + namespace: astrololo +spec: + headers: + stsSeconds: 31536000 # HSTS: rok + stsIncludeSubdomains: false # dotyczy tylko tego hosta + stsPreload: false # preload to wpis na listę w przeglądarkach + # — praktycznie nieodwracalny, nie wchodzimy + forceSTSHeader: true # nagłówek także przy odpowiedziach z backendu + contentTypeNosniff: true + frameDeny: true + referrerPolicy: same-origin +--- +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: redirect-https + namespace: astrololo +spec: + redirectScheme: + scheme: https + permanent: true +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: astrololo + namespace: astrololo + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: astrololo-security-headers@kubernetescrd +spec: + tls: + - hosts: [astrololo.czernobog.pl] + secretName: astrololo-tls # wypełnia cert-manager (tls.yaml) + rules: + - host: astrololo.czernobog.pl + http: + paths: + - path: / + pathType: Prefix + backend: + service: { name: presentation, port: { number: 8000 } } +--- +# Osobny Ingress wyłącznie na porcie 80 — istnieje po to, żeby odesłać na https. +# Rozdzielone świadomie: gdyby przekierowanie wisiało na tym samym routerze, co +# wejście po https, odsyłałoby samo do siebie w kółko. Backend jest tu formalnością, +# bo żadne żądanie do niego nie dojdzie. +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: astrololo-redirect + namespace: astrololo + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web + traefik.ingress.kubernetes.io/router.middlewares: astrololo-redirect-https@kubernetescrd +spec: + rules: + - host: astrololo.czernobog.pl + http: + paths: + - path: / + pathType: Prefix + backend: + service: { name: presentation, port: { number: 8000 } } diff --git a/astrololo/kustomization.yaml b/astrololo/kustomization.yaml index 1cd6e1f..f880cc5 100644 --- a/astrololo/kustomization.yaml +++ b/astrololo/kustomization.yaml @@ -5,6 +5,8 @@ resources: - data.yaml - logic.yaml - presentation.yaml + - tls.yaml # certyfikat z własnego CA (wymaga cert-managera) + - ingress.yaml # wejście po https + przekierowanie z http images: - name: gitea.czernobog.pl/gitea/astrololo-data newTag: 877ec91f diff --git a/astrololo/presentation.yaml b/astrololo/presentation.yaml index 89841e4..43dbb9e 100644 --- a/astrololo/presentation.yaml +++ b/astrololo/presentation.yaml @@ -30,6 +30,13 @@ spec: value: "astrololo" - name: RATE_LIMIT_PER_MIN value: "120" # 0 = bez limitu + # Aplikacja stoi za Ingressem, więc bezpośrednim rozmówcą jest zawsze + # pod Traefika. Bez tego limit żądań liczyłby WSZYSTKICH do jednego + # wiadra i pierwsza osoba, która go wyklika, odcięłaby pozostałych. + # Włączać wyłącznie gdy ruch faktycznie idzie przez proxy — inaczej + # nagłówek staje się furtką do ominięcia limitu. + - name: TRUST_PROXY + value: "true" resources: requests: { cpu: "100m", memory: "128Mi" } limits: { cpu: "300m", memory: "256Mi" } @@ -40,7 +47,10 @@ metadata: name: presentation namespace: astrololo spec: - type: NodePort # wejście z przeglądarki + # Wejście z przeglądarki idzie teraz WYŁĄCZNIE przez Ingress po https + # (ingress.yaml). NodePort był drugą, nieszyfrowaną drogą do środka — czyli + # obejściem całego PRE-16 — więc znika. + type: ClusterIP selector: { app: presentation } ports: [{ port: 8000, targetPort: 8000 }] diff --git a/astrololo/tls.yaml b/astrololo/tls.yaml new file mode 100644 index 0000000..771ae16 --- /dev/null +++ b/astrololo/tls.yaml @@ -0,0 +1,65 @@ +# Certyfikat dla wejścia do aplikacji (PRE-16). +# +# Dlaczego WŁASNE CA, a nie Let's Encrypt: klaster stoi w LAN (traefik trzyma +# LoadBalancera na 192.168.1.x), więc walidacja HTTP-01 nie ma jak dojść z +# internetu, a DNS-01 wymagałby trzymania w klastrze tokena API do domeny. +# Własne CA nie potrzebuje niczego z zewnątrz, a certyfikaty odnawia samo. +# +# WYMAGANIE WSTĘPNE: cert-manager musi być w klastrze PRZED synchronizacją tego +# katalogu — inaczej API odrzuci poniższe obiekty jako nieznane rodzaje zasobów. +# Instalacja jednorazowa: patrz README.md. +# +# Wszystko jest w namespace `astrololo` (Issuer, nie ClusterIssuer) świadomie: +# ArgoCD ma tu włączone `prune`, a zasoby o zasięgu całego klastra chcemy trzymać +# poza aplikacją, która może zostać skasowana. +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned + namespace: astrololo +spec: + selfSigned: {} +--- +# Korzeń zaufania. TO JEST certyfikat, który raz importujesz do przeglądarki +# i systemu — patrz README. Stąd długi termin ważności: importu nie chcemy +# powtarzać co kwartał. +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: astrololo-ca + namespace: astrololo +spec: + isCA: true + commonName: astrololo internal CA + secretName: astrololo-ca # tu lądują klucz i certyfikat korzenia + duration: 87600h # 10 lat + renewBefore: 8760h # odnowienie na rok przed końcem + privateKey: { algorithm: ECDSA, size: 256 } + issuerRef: { name: selfsigned, kind: Issuer, group: cert-manager.io } +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: astrololo-ca + namespace: astrololo +spec: + ca: { secretName: astrololo-ca } +--- +# Właściwy certyfikat serwera. Krótki termin CELOWO: przy 90 dniach odnawianie +# jest sprawdzane w praktyce co kwartał, więc awaria wyjdzie od razu, a nie za +# dziesięć lat, gdy nikt już nie będzie pamiętał, jak to działa. +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: astrololo-tls + namespace: astrololo +spec: + secretName: astrololo-tls # tego szuka Ingress + commonName: astrololo.czernobog.pl + dnsNames: + - astrololo.czernobog.pl + duration: 2160h # 90 dni + renewBefore: 720h # 30 dni zapasu + privateKey: { algorithm: ECDSA, size: 256, rotationPolicy: Always } + issuerRef: { name: astrololo-ca, kind: Issuer, group: cert-manager.io } -- 2.52.0 From a30a4afece8ce14a4c5b31fd57447bccf4f7d1ff Mon Sep 17 00:00:00 2001 From: migatu Date: Wed, 22 Jul 2026 23:52:41 +0200 Subject: [PATCH 2/2] feat(astrololo): klucze szyfrowania lacz miedzy warstwami (PRE-16) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Domyka PRE-16 po stronie manifestow. Kod (astrololo#21) potrafi juz szyfrowac ruch miedzy warstwami AES-256-GCM; tu dokladamy klucze i wymuszenie. - astrololo-link: nowy sekret z dwoma kluczami (LINK_KEY_PRESENTATION_LOGIC, LINK_KEY_LOGIC_DATA), tworzony POZA repo jak pozostale. Osobny klucz na pare rozmowcow: przejecie klucza prezentacji nie otwiera warstwy danych. Logika bierze oba, prezentacja i dane wylacznie swoj (secretKeyRef). - LINK_ENCRYPTION_REQUIRED=true we wszystkich trzech: bez klucza pod NIE wstaje, a klient nie wysyla niczego. Fail-closed w obie strony jest celowy — usluga, ktora wstala i po cichu nie szyfruje, jest gorsza niz CrashLoop, bo awarii nie widac. README: sekcja o sekrecie astrololo-link (tworzenie, wymiana, restart calej trojki naraz) oraz uczciwa nota, ze szyfrowane sa ciala, nie naglowki — sciezka i token jada czytelnie, ale sam token bez klucza nic nie daje. Sprawdzone: kubectl kustomize + apply --dry-run=server przechodza dla obu profili. Pelna instrukcja wdrozenia: docs/wdrozenie-pre16.md w repo astrololo. Co-Authored-By: Claude Opus 4.8 --- astrololo/README.md | 36 ++++++++++++++++++++++++++++++++++++ astrololo/data.yaml | 11 +++++++++++ astrololo/logic.yaml | 14 ++++++++++++++ astrololo/presentation.yaml | 11 +++++++++++ 4 files changed, 72 insertions(+) diff --git a/astrololo/README.md b/astrololo/README.md index a3b726a..1621913 100644 --- a/astrololo/README.md +++ b/astrololo/README.md @@ -125,6 +125,39 @@ Certyfikat serwera żyje 90 dni i odnawia się sam 30 dni przed końcem. Termin krótki **celowo** — odnawianie sprawdza się wtedy w praktyce co kwartał, a nie dopiero za dziesięć lat, gdy nikt nie będzie pamiętał, jak to było skonfigurowane. +## ⚠️ Sekret `astrololo-link` — szyfrowanie między warstwami + +Token międzywarstwowy mówi **kto** pyta, ale nie ukrywa **czego dotyczy odpowiedź** +— a płyną nią surowe wiersze oryginalnych baz. Kto podsłuchał ruch wewnątrz sieci +(drugi pod, mirror portu na switchu, zrzut z węzła), miał je w całości. Łącza są +więc szyfrowane **AES-256-GCM**, osobnym kluczem na każdą parę rozmówców. + +```bash +kubectl -n astrololo create secret generic astrololo-link \ + --from-literal=LINK_KEY_PRESENTATION_LOGIC="$(openssl rand -hex 32)" \ + --from-literal=LINK_KEY_LOGIC_DATA="$(openssl rand -hex 32)" +``` + +Kluczy **nikt nigdy nie musi oglądać** — służą tylko usługom. Rozdzielenie jest +celowe: przejęcie klucza prezentacji nie daje dostępu do warstwy danych, gdzie +leżą całe bazy. Logika trzyma oba, bo rozmawia w obie strony; prezentacja i dane +dostają przez `secretKeyRef` wyłącznie swój. + +**Pody nie wstaną bez tych kluczy** (`LINK_ENCRYPTION_REQUIRED=true`) — i tak ma +być. Usługa, która wstała i po cichu nie szyfruje, jest gorsza niż pod w CrashLoop, +bo awarii nie widać. + +### Wymiana kluczy +```bash +kubectl -n astrololo create secret generic astrololo-link \ + --from-literal=LINK_KEY_PRESENTATION_LOGIC="$(openssl rand -hex 32)" \ + --from-literal=LINK_KEY_LOGIC_DATA="$(openssl rand -hex 32)" \ + --dry-run=client -o yaml | kubectl apply -f - +kubectl -n astrololo rollout restart deploy/presentation deploy/logic deploy/data +``` +Restart **wszystkich trzech naraz** — w trakcie wymiany warstwy chwilowo się nie +dogadują (klucze muszą być zgodne po obu stronach łącza). + ## Klucze do modeli w chmurze — sekret `astrololo-llm` (opcjonalny) Domyślnie działa **model lokalny** i nic nie opuszcza sieci. Żeby móc wybrać w UI @@ -166,6 +199,9 @@ gdzie faktycznie stoi Ollama/vLLM. Konfiguracja jest **per dostawca** - **Własne CA to nie to samo co publiczne zaufanie** — każde nowe urządzenie wymaga importu korzenia (krok 3 powyżej). Gdyby aplikacja miała kiedyś wyjść na świat, właściwą drogą jest Let's Encrypt przez DNS-01. +- **Szyfrowane są ciała żądań, nie nagłówki** — ścieżka (`/search`) i token + międzywarstwowy jadą czytelnie. Sam token nikomu nic nie daje: bez klucza łącza + każde żądanie kończy się odmową. Pełne ukrycie metadanych wymagałoby mTLS. - **NFS `192.168.1.34:/mnt/Tank1/astrololo`** — kto ma dostęp do share'u, bierze pliki baz **z pominięciem całej aplikacji**. Do zamknięcia po stronie infrastruktury (eksport tylko dla IP węzłów, `root_squash`, najlepiej read-only). diff --git a/astrololo/data.yaml b/astrololo/data.yaml index 600810d..a33a80a 100644 --- a/astrololo/data.yaml +++ b/astrololo/data.yaml @@ -29,6 +29,17 @@ spec: - name: INTERNAL_TOKEN valueFrom: secretKeyRef: { name: astrololo-auth, key: INTERNAL_TOKEN } + # Szyfrowanie łącza między warstwami (PRE-16). OSOBNY klucz na każdą + # parę rozmówców: przejęcie klucza prezentacji nie otwiera warstwy + # danych, gdzie leżą całe bazy. Sekret tworzony POZA repo — patrz README. + - name: LINK_KEY_LOGIC_DATA + valueFrom: + secretKeyRef: { name: astrololo-link, key: LINK_KEY_LOGIC_DATA } + # Bez klucza usługa ma NIE wstać, a klient ma nie wysłać niczego. + # Sam serwer broni się fail-closed, ale to za mało: klient bez klucza + # zdążyłby wypuścić zapytanie jawnym tekstem, zanim dostanie odmowę. + - name: LINK_ENCRYPTION_REQUIRED + value: "true" volumeMounts: - name: cache mountPath: /app/.cache diff --git a/astrololo/logic.yaml b/astrololo/logic.yaml index d0c8b6e..d575aa4 100644 --- a/astrololo/logic.yaml +++ b/astrololo/logic.yaml @@ -26,6 +26,20 @@ spec: - name: INTERNAL_TOKEN valueFrom: secretKeyRef: { name: astrololo-auth, key: INTERNAL_TOKEN } + # Szyfrowanie łącza między warstwami (PRE-16). OSOBNY klucz na każdą + # parę rozmówców: przejęcie klucza prezentacji nie otwiera warstwy + # danych, gdzie leżą całe bazy. Sekret tworzony POZA repo — patrz README. + - name: LINK_KEY_PRESENTATION_LOGIC + valueFrom: + secretKeyRef: { name: astrololo-link, key: LINK_KEY_PRESENTATION_LOGIC } + - name: LINK_KEY_LOGIC_DATA + valueFrom: + secretKeyRef: { name: astrololo-link, key: LINK_KEY_LOGIC_DATA } + # Bez klucza usługa ma NIE wstać, a klient ma nie wysłać niczego. + # Sam serwer broni się fail-closed, ale to za mało: klient bez klucza + # zdążyłby wypuścić zapytanie jawnym tekstem, zanim dostanie odmowę. + - name: LINK_ENCRYPTION_REQUIRED + value: "true" # --- Model językowy (LOG-31) --- # Domyślnie LOKALNY: prompt niesie oryginalne opisy z baz, więc nic nie diff --git a/astrololo/presentation.yaml b/astrololo/presentation.yaml index 43dbb9e..9a2cd4c 100644 --- a/astrololo/presentation.yaml +++ b/astrololo/presentation.yaml @@ -37,6 +37,17 @@ spec: # nagłówek staje się furtką do ominięcia limitu. - name: TRUST_PROXY value: "true" + # Szyfrowanie łącza między warstwami (PRE-16). OSOBNY klucz na każdą + # parę rozmówców: przejęcie klucza prezentacji nie otwiera warstwy + # danych, gdzie leżą całe bazy. Sekret tworzony POZA repo — patrz README. + - name: LINK_KEY_PRESENTATION_LOGIC + valueFrom: + secretKeyRef: { name: astrololo-link, key: LINK_KEY_PRESENTATION_LOGIC } + # Bez klucza usługa ma NIE wstać, a klient ma nie wysłać niczego. + # Sam serwer broni się fail-closed, ale to za mało: klient bez klucza + # zdążyłby wypuścić zapytanie jawnym tekstem, zanim dostanie odmowę. + - name: LINK_ENCRYPTION_REQUIRED + value: "true" resources: requests: { cpu: "100m", memory: "128Mi" } limits: { cpu: "300m", memory: "256Mi" } -- 2.52.0