namespace.yaml — explicit forte-drop Namespace at sync-wave -1, Prune=false (avoids first-sync race for namespaced resources; doesn't cascade-delete on base removal).
keycloak-client-forte-drop + keycloak-client-forte-drop-mcp — labeled config Secrets; the registrar creates the OIDC clients in the forte realm within ~2 min.
forte-drop-secrets SealedSecret — UpCloud S3 creds (existing drops bucket) + PG creds + PASSWORD_GATE_SECRET. Consumed by both deployments + the pg-backup CronJob.
forte-drop-web PDB — minAvailable 1 (selector verified against the live forteapp chart's pod labels).
Wired into apps/overlays/upc-dev (NOT base → stays out of upc-prod).
Post-merge manual step (one-time)
auth-oidc SealedSecret for the web sidecar is still commented out — it needs the client-secret the Keycloak registrar writes to forte-drop-oidc-credentials after first sync:
Two ArgoCD apps from the same forte-drop image:
- forte-drop (web): admin + public drops, sidecar in oidc mode,
ingress drop-k8s.hackathon.forteapps.net.
- forte-drop-mcp (mcp): MCP-over-HTTP, sidecar in mcp mode,
ingress mcp.drop-k8s.hackathon.forteapps.net.
Plus two labeled Keycloak client config Secrets — the registrar
creates the OIDC clients in the forte realm within ~2 min.
Sealed secrets (forte-drop-secrets + auth-oidc) added in a
follow-up commit by the maintainer:
cd /Users/sten/dev/work/forte_k8/launchpad
kubeseal --format=yaml \
--controller-name=sealed-secrets-controller \
--controller-namespace=kube-system \
< private/forte-drop-secrets.yaml \
> apps/base/forte-drop/forte-drop-secrets-sealed.yaml
# auth-oidc: wait for registrar, copy client-secret into private/,
# then seal as apps/base/forte-drop/auth-oidc-sealed.yaml.
# (mcp deployment is sidecar type=mcp — no auth-oidc Secret needed;
# only the web deployment requires it.)
forte-drop and forte-drop-mcp have hackathon-domain values hardcoded
(drop-k8s.hackathon.forteapps.net). Listing them in apps/base/
syncs them to both upc-dev and upc-prod overlays — prod sync would
create broken Applications pointing at non-existent prod ingress.
Move references to apps/overlays/upc-dev/ only.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sealed forte-drop-secrets with the real UpCloud Managed Object Storage
creds (existing drops bucket), PG creds matching the deployed
forte-drop-pg-creds, and PASSWORD_GATE_SECRET. Consumed by both web +
mcp deployments (envSecretName) and the pg-backup CronJob (S3 creds).
Codex review: the apps overlay applies namespaced resources
(keycloak-client Secrets, forte-drop-secrets, PDB) to forte-drop, but
no base created the namespace — first sync on a fresh cluster raced
ahead of the Applications' CreateNamespace and failed with
'namespaces forte-drop not found' until a retry.
Add an explicit Namespace at sync-wave -1 so it exists before the
wave-0 namespaced resources (covers both web + mcp bases via the
shared parent). Prune=false keeps removing a base from cascade-
deleting the namespace + postgres data + the other deployment.
jorgen.stensrud
requested review from danijel.simeunovic 2026-05-29 08:32:20 +00:00
jorgen.stensrud
removed review request for danijel.simeunovic 2026-05-29 08:32:52 +00:00
Using 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
targetRevision: main
#ai-review-inline
Using 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
```suggestion
targetRevision: main
```
#ai-review-inline
Using 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
targetRevision: main
#ai-review-inline
Using 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
```suggestion
targetRevision: main
```
#ai-review-inline
Using 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
targetRevision: main
#ai-review-inline
Using 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
```suggestion
targetRevision: main
```
#ai-review-inline
Using 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
targetRevision: main
#ai-review-inline
Using 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
```suggestion
targetRevision: main
```
#ai-review-inline
Using 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
targetRevision: main
#ai-review-inline
Using 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
```suggestion
targetRevision: main
```
#ai-review-inline
Using 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
targetRevision: main
#ai-review-inline
Using 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
```suggestion
targetRevision: main
```
#ai-review-inline
Using 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
targetRevision: main
#ai-review-inline
Using 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
```suggestion
targetRevision: main
```
#ai-review-inline
Using 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
targetRevision: main
#ai-review-inline
Using 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
```suggestion
targetRevision: main
```
#ai-review-inline
Line comment is truncated mid-sentence, making it unclear.
# forte-drop and forte-drop-mcp are scoped to upc-dev only — they have
#ai-review-inline
Line comment is truncated mid-sentence, making it unclear.
```suggestion
# forte-drop and forte-drop-mcp are scoped to upc-dev only — they have
```
#ai-review-inline
Line comment is truncated mid-sentence, making it unclear.
# hackathon-domain hardcoded values and must not sync to upc-prod.
#ai-review-inline
Line comment is truncated mid-sentence, making it unclear.
```suggestion
# hackathon-domain hardcoded values and must not sync to upc-prod.
```
#ai-review-inline
Line comment is truncated mid-sentence, making it unclear.
# forte-drop and forte-drop-mcp are scoped to upc-dev only — they have
#ai-review-inline
Line comment is truncated mid-sentence, making it unclear.
```suggestion
# forte-drop and forte-drop-mcp are scoped to upc-dev only — they have
```
#ai-review-inline
Line comment is truncated mid-sentence, making it unclear.
# hackathon-domain hardcoded values and must not sync to upc-prod.
#ai-review-inline
Line comment is truncated mid-sentence, making it unclear.
```suggestion
# hackathon-domain hardcoded values and must not sync to upc-prod.
```
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
---
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
```suggestion
---
```
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
---
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
```suggestion
---
```
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
---
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
```suggestion
---
```
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
---
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
```suggestion
---
```
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
---
#ai-review-inline
Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
```suggestion
---
```
#ai-review-inline
What changed: Added new ArgoCD Applications for Forte Drop web service and MCP service with supporting Kubernetes resources.
Affected services/namespaces:
Creates new forte-drop namespace
Deploys forte-drop (web) and forte-drop-mcp applications
Only targets upc-dev overlay (excluded from production)
Infrastructure impact:
Adds PodDisruptionBudget maintaining minimum 1 replica for web pods
Creates namespace with sync-wave ordering and prune protection
Enables automated sync with prune and self-heal for both applications
References external Helm charts from forteapps.net Git repositories
Security notes:
REQUIRES REVIEW: Adds SealedSecret with encrypted database and S3 credentials
REQUIRES REVIEW: Creates two Keycloak client configurations for OIDC authentication
Uses hardcoded hackathon domain URLs in redirect URIs
Contains encrypted sensitive data (passwords, API keys, endpoints)
#ai-review-summary
**What changed**: Added new ArgoCD Applications for Forte Drop web service and MCP service with supporting Kubernetes resources.
**Affected services/namespaces**:
- Creates new `forte-drop` namespace
- Deploys `forte-drop` (web) and `forte-drop-mcp` applications
- Only targets `upc-dev` overlay (excluded from production)
**Infrastructure impact**:
- Adds PodDisruptionBudget maintaining minimum 1 replica for web pods
- Creates namespace with sync-wave ordering and prune protection
- Enables automated sync with prune and self-heal for both applications
- References external Helm charts from forteapps.net Git repositories
**Security notes**:
- **REQUIRES REVIEW**: Adds SealedSecret with encrypted database and S3 credentials
- **REQUIRES REVIEW**: Creates two Keycloak client configurations for OIDC authentication
- Uses hardcoded hackathon domain URLs in redirect URIs
- Contains encrypted sensitive data (passwords, API keys, endpoints)
#ai-review-summary
Per reviewer (danijel): forte-drop's DB deployment belongs in apps/,
not infra/. Straight relocation — same structure (Application +
resources/ subdir), source.path updated to apps/base/forte-drop-postgresql/resources,
wired into apps/overlays/upc-dev. Backup CronJob + RESTORE.md + sealed
pg creds move with it.
Consolidates the whole forte-drop deployment (postgres + web + mcp)
under apps/. The infra PR (#17) is now superseded by this.
ai-review: a commented-out resource line reads as GitOps debt. Replace
the '# - auth-oidc-sealed.yaml' line with an explicit NOTE explaining
it's a deliberate post-deploy step (needs the registrar-generated
client-secret), not a disabled resource.
Gått igjennom alle inline-kommentarene. Én fikset, resten avvist med begrunnelse.
Fikset
Commented-out auth-oidc-sealed.yaml linje (61a8a2b) — erstattet med en tydelig NOTE som forklarer at det er et bevisst post-deploy steg (krever registrar-generert client-secret), ikke en disabled resource.
Avvist — konvensjon
Hardkodet domene i keycloak-client redirectUris/webOrigins — alle self-service + legacy clients gjør identisk: vaultwarden (https://vaultwarden.forteapps.net/*), gitea, grafana, argocd. Ingen templating finnes i launchpad for dette. Realmen er per-cluster (id.forteapps.net dev / id.fortedigital.com prod), og forte-drop er scoped til upc-dev-overlay. Templating ville vært en ny abstraksjon ingen andre clients bruker.
targetRevision: HEAD → main (×3) — alle eksisterende apps (mcp10x, argo-mcp, ts-mcp) bruker HEAD (6/6). Å endre kun forte-drop = inkonsistent.
Avvist — false positives
"Plain-text Secret" på keycloak-client-mcp — fila er registrar-input (labeled config Secret med client.json), inneholder ingen secret-verdi. clientAuthenticatorType: client-secret betyr Keycloak genererer secret; den står ikke i Git. Self-service-mønster per DEVELOPER-GUIDE.md.
"Truncated comment" i overlay kustomization — kommentaren er komplett multi-line, leses riktig i rekkefølge.
"Remove '# added' comments" (×10) i sealed secret — grep "# added" = ingen treff. Disse kommentarene finnes ikke i fila.
Klar for menneskelig review.
## ai-review triage
Gått igjennom alle inline-kommentarene. Én fikset, resten avvist med begrunnelse.
### Fikset
- **Commented-out `auth-oidc-sealed.yaml` linje** (`61a8a2b`) — erstattet med en tydelig NOTE som forklarer at det er et bevisst post-deploy steg (krever registrar-generert client-secret), ikke en disabled resource.
### Avvist — konvensjon
- **Hardkodet domene i keycloak-client redirectUris/webOrigins** — alle self-service + legacy clients gjør identisk: `vaultwarden` (`https://vaultwarden.forteapps.net/*`), gitea, grafana, argocd. Ingen templating finnes i launchpad for dette. Realmen er per-cluster (id.forteapps.net dev / id.fortedigital.com prod), og forte-drop er scoped til upc-dev-overlay. Templating ville vært en ny abstraksjon ingen andre clients bruker.
- **`targetRevision: HEAD` → `main`** (×3) — alle eksisterende apps (mcp10x, argo-mcp, ts-mcp) bruker `HEAD` (6/6). Å endre kun forte-drop = inkonsistent.
### Avvist — false positives
- **"Plain-text Secret" på keycloak-client-mcp** — fila er registrar-input (labeled config Secret med `client.json`), inneholder ingen secret-verdi. `clientAuthenticatorType: client-secret` betyr Keycloak *genererer* secret; den står ikke i Git. Self-service-mønster per DEVELOPER-GUIDE.md.
- **"Truncated comment"** i overlay kustomization — kommentaren er komplett multi-line, leses riktig i rekkefølge.
- **"Remove '# added' comments"** (×10) i sealed secret — `grep "# added"` = ingen treff. Disse kommentarene finnes ikke i fila.
Klar for menneskelig review.
Din AI gjør en feil tolkning med secrets. Du trenger ikke vente på at noe skal opprettes og lage SealedSecret.
Du har allerede definert Keycloak client her apps/base/forte-drop/keycloak-client-forte-drop.yaml
Dette blir synket til keycloak namespace, en CronJob plukker opp og lager klienten og en secret, og dette pushes til ditt namespace som en secret. Så ingen ny SealedSecret skal være nødvendig.
Din AI gjør en feil tolkning med secrets. Du trenger ikke vente på at noe skal opprettes og lage SealedSecret.
Du har allerede definert Keycloak client her `apps/base/forte-drop/keycloak-client-forte-drop.yaml`
Dette blir synket til keycloak namespace, en CronJob plukker opp og lager klienten og en secret, og dette pushes til ditt namespace som en secret. Så ingen ny SealedSecret skal være nødvendig.
Og du vurderer selv om ai-review label er noe som gir deg verdi. Jeg ser at den av og til blir litt chatty med mange meldinger, men dette kan vi justere i instructions og kanskje ha et tak på 5-10 mest kritiske.
Og du vurderer selv om `ai-review` label er noe som gir deg verdi. Jeg ser at den av og til blir litt chatty med mange meldinger, men dette kan vi justere i instructions og kanskje ha et tak på 5-10 mest kritiske.
Det du mangler her er hvor du vil at Secret skal bli laget og med hvilke keys:
"secret": {
"namespace": "myapp", # Where to create credential Secret
"name": "myapp-oidc-credentials", # Name of credential Secret
"keys": {
"clientId": "client-id", # Key name for client ID
"clientSecret": "client-secret" # Key name for client secret
}
}
Det du mangler her er hvor du vil at `Secret` skal bli laget og med hvilke keys:
```
"secret": {
"namespace": "myapp", # Where to create credential Secret
"name": "myapp-oidc-credentials", # Name of credential Secret
"keys": {
"clientId": "client-id", # Key name for client ID
"clientSecret": "client-secret" # Key name for client secret
}
}
```
A developer deploying a new application must create a Config Secret in their application's namespace. This Secret contains the desired Keycloak client configuration.
The Format
Kubernetes Secret YAML:
apiVersion:v1kind:Secretmetadata:name:keycloak-client-<app-name> # Any descriptive namenamespace:<app-namespace> # Your app's namespace (e.g., "myapp")labels:keycloak.forteapps.net/client-config:"true"# REQUIRED - triggers processingannotations:keycloak.forteapps.net/source-namespace:"myapp"# Optional - tracks ownershipstringData:client.json:| # REQUIRED - the client configuration{"clientId": "myapp",# Pre-determined by developer"name": "My Application",# Display name in Keycloak UI"redirectUris": ["https://myapp.forteapps.net/*"],"webOrigins": ["https://myapp.forteapps.net"],"defaultClientScopes": ["openid","email","profile"],"protocolMappers": [],"secret": {"namespace": "myapp",# Where to create credential Secret"name": "myapp-oidc-credentials",# Name of credential Secret"keys": {"clientId": "client-id",# Key name for client ID"clientSecret": "client-secret"# Key name for client secret}}}
How It Works: Client ID vs Client Secret
Client ID (Pre-determined by Developer):
The developer chooses clientId (e.g., "myapp")
This becomes the public identifier for the OIDC client
Used in OAuth flows, login redirects, token requests
Stored in the credential Secret under the specified key (default: client-id)
Client Secret (Generated by Keycloak):
Keycloak auto-generates a cryptographically secure secret
The CronJob fetches it via: GET /admin/realms/forte/clients/{uuid}/client-secret
apiVersion:v1kind:Secretmetadata:name:myapp-oidc-credentialsnamespace:myapplabels:app.kubernetes.io/managed-by:keycloak-client-registrartype:Opaquedata:client-id:bXlhcHA= # base64("myapp") - from client.jsonclient-secret:<base64> # Generated by Keycloak
2. Central Backup Secret (secrets/myapp-oidc-credentials):
Identical content
Always created even if target namespace doesn't exist
Used for external deployments, disaster recovery, auditing
Developer Workflow
Create Config Secret in your Helm chart or Kustomize (in your app's namespace)
Deploy - Kyverno policy clones it to keycloak namespace automatically
Wait - CronJob picks it up within 2 minutes
Reference the generated credential Secret in your Deployment:
The CronJob computes a SHA256 hash of client.json. If unchanged and credential Secret exists, it skips processing. To force re-sync, modify any field in client.json (e.g., add trailing space to name).
Detaljert forklaring, hvis interessant:
### What a Developer Should Push
A developer deploying a new application must create a __Config Secret__ in their application's namespace. This Secret contains the desired Keycloak client configuration.
### The Format
__Kubernetes Secret YAML:__
```yaml
apiVersion: v1
kind: Secret
metadata:
name: keycloak-client-<app-name> # Any descriptive name
namespace: <app-namespace> # Your app's namespace (e.g., "myapp")
labels:
keycloak.forteapps.net/client-config: "true" # REQUIRED - triggers processing
annotations:
keycloak.forteapps.net/source-namespace: "myapp" # Optional - tracks ownership
stringData:
client.json: | # REQUIRED - the client configuration
{
"clientId": "myapp", # Pre-determined by developer
"name": "My Application", # Display name in Keycloak UI
"redirectUris": ["https://myapp.forteapps.net/*"],
"webOrigins": ["https://myapp.forteapps.net"],
"defaultClientScopes": ["openid", "email", "profile"],
"protocolMappers": [],
"secret": {
"namespace": "myapp", # Where to create credential Secret
"name": "myapp-oidc-credentials", # Name of credential Secret
"keys": {
"clientId": "client-id", # Key name for client ID
"clientSecret": "client-secret" # Key name for client secret
}
}
}
```
### How It Works: Client ID vs Client Secret
__Client ID (Pre-determined by Developer):__
- The developer chooses `clientId` (e.g., `"myapp"`)
- This becomes the public identifier for the OIDC client
- Used in OAuth flows, login redirects, token requests
- Stored in the credential Secret under the specified key (default: `client-id`)
__Client Secret (Generated by Keycloak):__
- Keycloak auto-generates a cryptographically secure secret
- The CronJob fetches it via: `GET /admin/realms/forte/clients/{uuid}/client-secret`
- The CronJob then creates/updates __TWO__ Secrets:
__1. Target Namespace Secret__ (`myapp/myapp-oidc-credentials`):
```yaml
apiVersion: v1
kind: Secret
metadata:
name: myapp-oidc-credentials
namespace: myapp
labels:
app.kubernetes.io/managed-by: keycloak-client-registrar
type: Opaque
data:
client-id: bXlhcHA= # base64("myapp") - from client.json
client-secret: <base64> # Generated by Keycloak
```
__2. Central Backup Secret__ (`secrets/myapp-oidc-credentials`):
- Identical content
- Always created even if target namespace doesn't exist
- Used for external deployments, disaster recovery, auditing
### Developer Workflow
1. __Create Config Secret__ in your Helm chart or Kustomize (in your app's namespace)
2. __Deploy__ - Kyverno policy clones it to `keycloak` namespace automatically
3. __Wait__ - CronJob picks it up within 2 minutes
4. __Reference__ the generated credential Secret in your Deployment:
```yaml
env:
- name: OIDC_CLIENT_ID
valueFrom:
secretKeyRef:
name: myapp-oidc-credentials
key: client-id
- name: OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: myapp-oidc-credentials
key: client-secret
```
### Change Detection
The CronJob computes a SHA256 hash of `client.json`. If unchanged and credential Secret exists, it skips processing. To force re-sync, modify any field in `client.json` (e.g., add trailing space to `name`).
Per platform review (danijel):
- keycloak-client-forte-drop: add the secret{} block telling the
registrar where to write the credential Secret + key names
(forte-drop-oidc-credentials, client-id/client-secret). The
forte-helm oidc sidecar consumes that registrar-created Secret —
no manual auth-oidc SealedSecret step (removed that NOTE).
- Delete keycloak-client-forte-drop-mcp: auth.type: mcp auto-registers
the MCP client; no manual config needed.
- Re-seal forte-drop-secrets with all shared env (BASE_DOMAIN, PG*,
S3_*, PASSWORD_GATE_SECRET) so both deployments get identical values
via envSecretName (values extraEnv now carries only APP_MODE).
Slettet keycloak-client-forte-drop-mcp.yaml — auth.type: mcp auto-registrerer mcp-klienten via chart. Ingen manuell config nødvendig.
Fjernet det manuelle auth-oidc SealedSecret-steget — du har rett: registrar lager forte-drop-oidc-credentials automatisk og sidecaren (auth.type: oidc) konsumerer den. Ingen seal-by-hand. Slettet NOTE-en i kustomization.
Re-sealet forte-drop-secrets med all delt env (BASE_DOMAIN, PG*, S3_*, PASSWORD_GATE_SECRET, 12 keys) — begge deployments mounter den via envSecretName, så values extraEnv har nå kun APP_MODE.
Tilhørende: app-en gjort helt auth-uvitende i egen forte_drop PR (slettet JWT/OIDC-kode). Klar for re-review.
## Oppdatert etter platform-review (@danijel.simeunovic, på helm-prod-values #3)
Reviewen kom på #3 men flere punkter gjaldt launchpad-manifestene her. Adressert i `338b4de`:
- **keycloak-client-forte-drop**: la til `secret`-blokken — forteller registrar hvor + med hvilke keys credential-secreten lages:
```json
"secret": {
"namespace": "forte-drop",
"name": "forte-drop-oidc-credentials",
"keys": { "clientId": "client-id", "clientSecret": "client-secret" }
}
```
- **Slettet `keycloak-client-forte-drop-mcp.yaml`** — `auth.type: mcp` auto-registrerer mcp-klienten via chart. Ingen manuell config nødvendig.
- **Fjernet det manuelle auth-oidc SealedSecret-steget** — du har rett: registrar lager `forte-drop-oidc-credentials` automatisk og sidecaren (auth.type: oidc) konsumerer den. Ingen seal-by-hand. Slettet NOTE-en i kustomization.
- **Re-sealet `forte-drop-secrets`** med all delt env (BASE_DOMAIN, PG*, S3_*, PASSWORD_GATE_SECRET, 12 keys) — begge deployments mounter den via `envSecretName`, så values `extraEnv` har nå kun `APP_MODE`.
Tilhørende: app-en gjort helt auth-uvitende i egen forte_drop PR (slettet JWT/OIDC-kode). Klar for re-review.
Gode tilbakemeldinger! Jeg tror jeg forstår litt og litt mer 😄 den ai-reviewen er litt chatty ja!
Jeg har prøvd å justere litt og be om maks 10 kommentarer, men forstår ikke enda hvorfor den ignorerer... :)
> Gode tilbakemeldinger! Jeg tror jeg forstår litt og litt mer 😄 den ai-reviewen er litt chatty ja!
>
Jeg har prøvd å justere litt og be om maks 10 kommentarer, men forstår ikke enda hvorfor den ignorerer... :)
Jeg så for meg at dette skulle plasseres i apps/overlays/upc-dev, ikke i base/.... Jeg innser at det ligger flere ting der som helst skulle flyttes, men det er min feil fordi de ble lagt inn før overlays kom inn i bilde.
Jeg så for meg at dette skulle plasseres i `apps/overlays/upc-dev`, ikke i `base/...`. Jeg innser at det ligger flere ting der som helst skulle flyttes, men det er min feil fordi de ble lagt inn før overlays kom inn i bilde.
Jeg så for meg at dette skulle plasseres i apps/overlays/upc-dev, ikke i base/.... Jeg innser at det ligger flere ting der som helst skulle flyttes, men det er min feil fordi de ble lagt inn før overlays kom inn i bilde.
Skal jeg flytte det dit?
> Jeg så for meg at dette skulle plasseres i `apps/overlays/upc-dev`, ikke i `base/...`. Jeg innser at det ligger flere ting der som helst skulle flyttes, men det er min feil fordi de ble lagt inn før overlays kom inn i bilde.
Skal jeg flytte det dit?
Jeg så for meg at dette skulle plasseres i apps/overlays/upc-dev, ikke i base/.... Jeg innser at det ligger flere ting der som helst skulle flyttes, men det er min feil fordi de ble lagt inn før overlays kom inn i bilde.
Skal jeg flytte det dit?
Ja, gjerne.
> > Jeg så for meg at dette skulle plasseres i `apps/overlays/upc-dev`, ikke i `base/...`. Jeg innser at det ligger flere ting der som helst skulle flyttes, men det er min feil fordi de ble lagt inn før overlays kom inn i bilde.
>
> Skal jeg flytte det dit?
>
Ja, gjerne.
forte-drop, forte-drop-mcp and forte-drop-postgresql lived under apps/base/
but were only ever wired into the upc-dev overlay (never listed in
apps/base/kustomization.yaml). They carry hackathon-domain hardcoded values
and must not sync to upc-prod, so they belong in the overlay alongside
dbunk-demo — per danijel.simeunovic's review on PR #18.
- git mv the three dirs into apps/overlays/upc-dev/ (history preserved)
- rewrite overlay kustomization refs from ../../base/forte-drop* to local
- repoint forte-drop-postgresql Application path
apps/base/... -> apps/overlays/upc-dev/forte-drop-postgresql/resources
Render-verified: kubectl kustomize apps/overlays/upc-dev differs only by the
postgres path line; apps/overlays/upc-prod render byte-identical (forte-drop
never reaches prod).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Som avtalt — forte-drop, forte-drop-mcp og forte-drop-postgresql flyttet fra apps/base/ til apps/overlays/upc-dev/ (ren git mv, historikk bevart). De var aldri listet i apps/base/kustomization.yaml — kun wiret inn via upc-dev-overlayet — så de hører hjemme her sammen med dbunk-demo.
Utover selve flyttingen:
overlay-kustomization: ../../base/forte-drop* → lokale refs
forte-drop-postgresql Application path: apps/base/... → apps/overlays/upc-dev/forte-drop-postgresql/resources (selv-referanse til repoet, måtte følge med)
Verifisert render-nøytralt:
kubectl kustomize apps/overlays/upc-dev skiller seg kun på postgres-path-linja
apps/overlays/upc-prod render byte-identisk (forte-drop når aldri prod)
Review-gate (CLAUDE.md): codex + /code-review begge rene, ingen funn. Lot resten av apps/base/ urørt — de andre appene der deles mellom clustere; de "flere ting" du nevnte kan tas i egen PR.
## Flyttet til `apps/overlays/upc-dev` (`335dd13`)
Som avtalt — `forte-drop`, `forte-drop-mcp` og `forte-drop-postgresql` flyttet fra `apps/base/` til `apps/overlays/upc-dev/` (ren `git mv`, historikk bevart). De var aldri listet i `apps/base/kustomization.yaml` — kun wiret inn via upc-dev-overlayet — så de hører hjemme her sammen med `dbunk-demo`.
Utover selve flyttingen:
- overlay-kustomization: `../../base/forte-drop*` → lokale refs
- `forte-drop-postgresql` Application `path`: `apps/base/...` → `apps/overlays/upc-dev/forte-drop-postgresql/resources` (selv-referanse til repoet, måtte følge med)
Verifisert render-nøytralt:
- `kubectl kustomize apps/overlays/upc-dev` skiller seg kun på postgres-`path`-linja
- `apps/overlays/upc-prod` render byte-identisk (forte-drop når aldri prod)
Review-gate (CLAUDE.md): codex + `/code-review` begge rene, ingen funn. Lot resten av `apps/base/` urørt — de andre appene der deles mellom clustere; de "flere ting" du nevnte kan tas i egen PR.
Klar for re-review @danijel.simeunovic
jorgen.stensrud
requested review from danijel.simeunovic 2026-06-01 10:49:14 +00:00
Two ArgoCD apps from the same forte-drop image:
- forte-drop (web): admin + public drops, sidecar in oidc mode,
ingress drop-k8s.hackathon.forteapps.net.
- forte-drop-mcp (mcp): MCP-over-HTTP, sidecar in mcp mode,
ingress mcp.drop-k8s.hackathon.forteapps.net.
Plus two labeled Keycloak client config Secrets — the registrar
creates the OIDC clients in the forte realm within ~2 min.
Sealed secrets (forte-drop-secrets + auth-oidc) added in a
follow-up commit by the maintainer:
cd /Users/sten/dev/work/forte_k8/launchpad
kubeseal --format=yaml \
--controller-name=sealed-secrets-controller \
--controller-namespace=kube-system \
< private/forte-drop-secrets.yaml \
> apps/base/forte-drop/forte-drop-secrets-sealed.yaml
# auth-oidc: wait for registrar, copy client-secret into private/,
# then seal as apps/base/forte-drop/auth-oidc-sealed.yaml.
# (mcp deployment is sidecar type=mcp — no auth-oidc Secret needed;
# only the web deployment requires it.)
Sealed forte-drop-secrets with the real UpCloud Managed Object Storage
creds (existing drops bucket), PG creds matching the deployed
forte-drop-pg-creds, and PASSWORD_GATE_SECRET. Consumed by both web +
mcp deployments (envSecretName) and the pg-backup CronJob (S3 creds).
Codex review: the apps overlay applies namespaced resources
(keycloak-client Secrets, forte-drop-secrets, PDB) to forte-drop, but
no base created the namespace — first sync on a fresh cluster raced
ahead of the Applications' CreateNamespace and failed with
'namespaces forte-drop not found' until a retry.
Add an explicit Namespace at sync-wave -1 so it exists before the
wave-0 namespaced resources (covers both web + mcp bases via the
shared parent). Prune=false keeps removing a base from cascade-
deleting the namespace + postgres data + the other deployment.
Per reviewer (danijel): forte-drop's DB deployment belongs in apps/,
not infra/. Straight relocation — same structure (Application +
resources/ subdir), source.path updated to apps/base/forte-drop-postgresql/resources,
wired into apps/overlays/upc-dev. Backup CronJob + RESTORE.md + sealed
pg creds move with it.
Consolidates the whole forte-drop deployment (postgres + web + mcp)
under apps/. The infra PR (#17) is now superseded by this.
ai-review: a commented-out resource line reads as GitOps debt. Replace
the '# - auth-oidc-sealed.yaml' line with an explicit NOTE explaining
it's a deliberate post-deploy step (needs the registrar-generated
client-secret), not a disabled resource.
Per platform review (danijel):
- keycloak-client-forte-drop: add the secret{} block telling the
registrar where to write the credential Secret + key names
(forte-drop-oidc-credentials, client-id/client-secret). The
forte-helm oidc sidecar consumes that registrar-created Secret —
no manual auth-oidc SealedSecret step (removed that NOTE).
- Delete keycloak-client-forte-drop-mcp: auth.type: mcp auto-registers
the MCP client; no manual config needed.
- Re-seal forte-drop-secrets with all shared env (BASE_DOMAIN, PG*,
S3_*, PASSWORD_GATE_SECRET) so both deployments get identical values
via envSecretName (values extraEnv now carries only APP_MODE).
forte-drop, forte-drop-mcp and forte-drop-postgresql lived under apps/base/
but were only ever wired into the upc-dev overlay (never listed in
apps/base/kustomization.yaml). They carry hackathon-domain hardcoded values
and must not sync to upc-prod, so they belong in the overlay alongside
dbunk-demo — per danijel.simeunovic's review on PR #18.
- git mv the three dirs into apps/overlays/upc-dev/ (history preserved)
- rewrite overlay kustomization refs from ../../base/forte-drop* to local
- repoint forte-drop-postgresql Application path
apps/base/... -> apps/overlays/upc-dev/forte-drop-postgresql/resources
Render-verified: kubectl kustomize apps/overlays/upc-dev differs only by the
postgres path line; apps/overlays/upc-prod render byte-identical (forte-drop
never reaches prod).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The hackathon-zone host never got DNS records (delegated Azure zone,
no wildcard); the app launches on drop.forteapps.net instead. Without
this the OIDC callback dies on redirect_uri mismatch.
The hackathon-zone host never got DNS; the app launches on
drop.forteapps.net. Also refresh a stale overlay comment that
referenced the hackathon domain.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
ArgoCD Applications + Keycloak clients + sealed secret for forte-drop web + mcp (PROD).
What changed
forte-dropNamespace at sync-wave -1,Prune=false(avoids first-sync race for namespaced resources; doesn't cascade-delete on base removal).forterealm within ~2 min.apps/overlays/upc-dev(NOT base → stays out of upc-prod).Post-merge manual step (one-time)
auth-oidcSealedSecret for the web sidecar is still commented out — it needs theclient-secretthe Keycloak registrar writes toforte-drop-oidc-credentialsafter first sync:Depends on
Review
🤖 Generated with Claude Code
Two ArgoCD apps from the same forte-drop image: - forte-drop (web): admin + public drops, sidecar in oidc mode, ingress drop-k8s.hackathon.forteapps.net. - forte-drop-mcp (mcp): MCP-over-HTTP, sidecar in mcp mode, ingress mcp.drop-k8s.hackathon.forteapps.net. Plus two labeled Keycloak client config Secrets — the registrar creates the OIDC clients in the forte realm within ~2 min. Sealed secrets (forte-drop-secrets + auth-oidc) added in a follow-up commit by the maintainer: cd /Users/sten/dev/work/forte_k8/launchpad kubeseal --format=yaml \ --controller-name=sealed-secrets-controller \ --controller-namespace=kube-system \ < private/forte-drop-secrets.yaml \ > apps/base/forte-drop/forte-drop-secrets-sealed.yaml # auth-oidc: wait for registrar, copy client-secret into private/, # then seal as apps/base/forte-drop/auth-oidc-sealed.yaml. # (mcp deployment is sidecar type=mcp — no auth-oidc Secret needed; # only the web deployment requires it.)Inline review
@@ -0,0 +22,4 @@"directAccessGrantsEnabled": false,"serviceAccountsEnabled": false,"publicClient": false,"redirectUris": ["https://drop-k8s.hackathon.forteapps.net/auth/callback"],Hardcoded URL in redirectUris should be templated or moved to values to support different environments.
#ai-review-inline
@@ -0,0 +23,4 @@"serviceAccountsEnabled": false,"publicClient": false,"redirectUris": ["https://drop-k8s.hackathon.forteapps.net/auth/callback"],"webOrigins": ["https://drop-k8s.hackathon.forteapps.net"],Hardcoded URL in webOrigins should be templated or moved to values to support different environments.
#ai-review-inline
Inline review
@@ -0,0 +22,4 @@"directAccessGrantsEnabled": false,"serviceAccountsEnabled": false,"publicClient": false,"redirectUris": ["https://drop-k8s.hackathon.forteapps.net/auth/callback"],Hardcoded URL in redirectUris should be templated or moved to values to support different environments.
#ai-review-inline
@@ -0,0 +23,4 @@"serviceAccountsEnabled": false,"publicClient": false,"redirectUris": ["https://drop-k8s.hackathon.forteapps.net/auth/callback"],"webOrigins": ["https://drop-k8s.hackathon.forteapps.net"],Hardcoded URL in webOrigins should be templated or moved to values to support different environments.
#ai-review-inline
Inline review
@@ -0,0 +19,4 @@sources:- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.gitpath: forteapptargetRevision: HEADUsing 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
#ai-review-inline
@@ -0,0 +24,4 @@valueFiles:- $values/forte-drop-mcp/values.yaml- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.gittargetRevision: HEADUsing 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
#ai-review-inline
Inline review
@@ -0,0 +19,4 @@sources:- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.gitpath: forteapptargetRevision: HEADUsing 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
#ai-review-inline
@@ -0,0 +24,4 @@valueFiles:- $values/forte-drop-mcp/values.yaml- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.gittargetRevision: HEADUsing 'HEAD' for targetRevision can lead to unpredictable deployments - prefer a specific tag or branch.
#ai-review-inline
Inline review
@@ -0,0 +2,4 @@# Claude Desktop) discover this via /.well-known/oauth-protected-resource and# request tokens with aud=https://mcp.drop-k8s.hackathon.forteapps.net/mcp.apiVersion: v1kind: SecretPlain-text Secret should not be committed to Git - use SealedSecret or the Keycloak client registrar instead.
#ai-review-inline
@@ -0,0 +15,4 @@"name": "Forte Drop (MCP)","enabled": true,"protocol": "openid-connect","clientAuthenticatorType": "client-secret",Client secret authentication requires a secret value which should not be stored in plain-text Git.
#ai-review-inline
@@ -0,0 +19,4 @@sources:- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.gitpath: forteapptargetRevision: HEADUsing 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
#ai-review-inline
Inline review
@@ -0,0 +24,4 @@valueFiles:- $values/forte-drop/values.yaml- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.gittargetRevision: HEADUsing 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
#ai-review-inline
Inline review
@@ -0,0 +24,4 @@valueFiles:- $values/forte-drop/values.yaml- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.gittargetRevision: HEADUsing 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
#ai-review-inline
Inline review
@@ -0,0 +24,4 @@valueFiles:- $values/forte-drop/values.yaml- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.gittargetRevision: HEADUsing 'HEAD' as targetRevision can lead to unstable deployments; prefer a specific tag, branch, or commit hash for better control.
#ai-review-inline
Inline review
@@ -0,0 +6,4 @@- keycloak-client-forte-drop.yaml- forte-drop-pdb.yaml- forte-drop-secrets-sealed.yaml# - auth-oidc-sealed.yaml # added in follow-up commit (after Keycloak registrar creates client_secret)Commented-out resource should be removed or uncommented if needed for proper GitOps hygiene.
#ai-review-inline
Inline review
@@ -6,3 +8,4 @@# No patches needed — base already has "upc-dev" paths# upc-dev is the default/base cluster# forte-drop and forte-drop-mcp are scoped to upc-dev only — they haveLine comment is truncated mid-sentence, making it unclear.
#ai-review-inline
@@ -7,2 +9,4 @@# No patches needed — base already has "upc-dev" paths# upc-dev is the default/base cluster# forte-drop and forte-drop-mcp are scoped to upc-dev only — they have# hackathon-domain hardcoded values and must not sync to upc-prod.Line comment is truncated mid-sentence, making it unclear.
#ai-review-inline
Inline review
@@ -6,3 +8,4 @@# No patches needed — base already has "upc-dev" paths# upc-dev is the default/base cluster# forte-drop and forte-drop-mcp are scoped to upc-dev only — they haveLine comment is truncated mid-sentence, making it unclear.
#ai-review-inline
@@ -7,2 +9,4 @@# No patches needed — base already has "upc-dev" paths# upc-dev is the default/base cluster# forte-drop and forte-drop-mcp are scoped to upc-dev only — they have# hackathon-domain hardcoded values and must not sync to upc-prod.Line comment is truncated mid-sentence, making it unclear.
#ai-review-inline
Inline review
@@ -0,0 +1,18 @@---Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +2,4 @@apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:name: forte-drop-secretsRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +4,4 @@metadata:name: forte-drop-secretsnamespace: forte-dropspec:Remove unnecessary '# added' comment.
#ai-review-inline
Inline review
@@ -0,0 +1,18 @@---Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +2,4 @@apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:name: forte-drop-secretsRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +4,4 @@metadata:name: forte-drop-secretsnamespace: forte-dropspec:Remove unnecessary '# added' comment.
#ai-review-inline
Inline review
@@ -0,0 +1,18 @@---Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +2,4 @@apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:name: forte-drop-secretsRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +4,4 @@metadata:name: forte-drop-secretsnamespace: forte-dropspec:Remove unnecessary '# added' comment.
#ai-review-inline
Inline review
@@ -0,0 +1,18 @@---Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +2,4 @@apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:name: forte-drop-secretsRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +4,4 @@metadata:name: forte-drop-secretsnamespace: forte-dropspec:Remove unnecessary '# added' comment.
#ai-review-inline
Inline review
@@ -0,0 +3,4 @@kind: SealedSecretmetadata:name: forte-drop-secretsnamespace: forte-dropRemove unnecessary '# added' comment.
#ai-review-inline
Inline review
@@ -0,0 +1,18 @@---Remove unnecessary '# added' comments from the SealedSecret file as they add no value and clutter the configuration.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +1,18 @@---apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +2,4 @@apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:name: forte-drop-secretsRemove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +4,4 @@metadata:name: forte-drop-secretsnamespace: forte-dropspec:Remove unnecessary '# added' comment.
#ai-review-inline
Inline review
@@ -0,0 +3,4 @@kind: SealedSecretmetadata:name: forte-drop-secretsnamespace: forte-dropRemove unnecessary '# added' comment.
#ai-review-inline
Inline review
@@ -0,0 +5,4 @@name: forte-drop-secretsnamespace: forte-dropspec:encryptedData:Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +6,4 @@namespace: forte-dropspec:encryptedData:PASSWORD_GATE_SECRET: AgAlZOSURqrQo7dqylFYetr50dWEgWNWTtBEjwgmIp/aFbr2X29xSD0gHpANIF+eXuZ1zGvTX9j2r4YoXgmcb/MjKMd85mYG7FTa0PFdxSxighvKOS3BWQwb7chgNFHMwiZNQAAMNUD6NjlfLZXS0V2SMI+5zz2siYjt8OfgLKfSx5v8+zDFb+pGrCUuUZlMaqFF2ZmOryYNMYYq69iE2EW8UQcP49tmP4aaPx5wIGq6nIo+Qc/c6L4K83nK5ijHEipkgEs0Z0vDTDT4ZBbV0Qyif+Uc1j0eG9+vvIkHBCrGC0WbLOCXiSwmzYF5U2uTRKUbkiPWfohW1Ds2hqveIwg6oSOhK6B+O9s17QagKenYBEER2WAXLq/BLbFpwwijZcGaVnIYsFLUjcheQVPEdaxIyOPh3/qhDjEBX7PevwDzEyOGB6W54TAndx/Go6+Mnvq4aefTOsD+Jy9Iqc3SI3mDoTCSuDMrgnE4QUlImm+Qtk+qPC35n36B9s7yqsHZISbC4zBGAwk7MFfhwTZ3t4z3WXBjevT1zFfs/NeQaRPlcRtO7656C62qroOITty0rT4JAbz93fanqHlqFmiMrYNUIu3wlbr/NGgMlZ1kRVnwIryVup5vljZmvhRtF+TGMwIA+3zbO9U3NasjScnh5sraOauIf7kVsBYTU/2oKb37HvroyILXd8fbpPq+lZ1ejcvVseC+heOI6hvvH/DYztgFn5s9egzcfauicCijWtk1jn0ym1RzOYBotP0VFhXX5bF1HHoGGwQWC32fgqFWwxJ8Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +7,4 @@spec:encryptedData:PASSWORD_GATE_SECRET: AgAlZOSURqrQo7dqylFYetr50dWEgWNWTtBEjwgmIp/aFbr2X29xSD0gHpANIF+eXuZ1zGvTX9j2r4YoXgmcb/MjKMd85mYG7FTa0PFdxSxighvKOS3BWQwb7chgNFHMwiZNQAAMNUD6NjlfLZXS0V2SMI+5zz2siYjt8OfgLKfSx5v8+zDFb+pGrCUuUZlMaqFF2ZmOryYNMYYq69iE2EW8UQcP49tmP4aaPx5wIGq6nIo+Qc/c6L4K83nK5ijHEipkgEs0Z0vDTDT4ZBbV0Qyif+Uc1j0eG9+vvIkHBCrGC0WbLOCXiSwmzYF5U2uTRKUbkiPWfohW1Ds2hqveIwg6oSOhK6B+O9s17QagKenYBEER2WAXLq/BLbFpwwijZcGaVnIYsFLUjcheQVPEdaxIyOPh3/qhDjEBX7PevwDzEyOGB6W54TAndx/Go6+Mnvq4aefTOsD+Jy9Iqc3SI3mDoTCSuDMrgnE4QUlImm+Qtk+qPC35n36B9s7yqsHZISbC4zBGAwk7MFfhwTZ3t4z3WXBjevT1zFfs/NeQaRPlcRtO7656C62qroOITty0rT4JAbz93fanqHlqFmiMrYNUIu3wlbr/NGgMlZ1kRVnwIryVup5vljZmvhRtF+TGMwIA+3zbO9U3NasjScnh5sraOauIf7kVsBYTU/2oKb37HvroyILXd8fbpPq+lZ1ejcvVseC+heOI6hvvH/DYztgFn5s9egzcfauicCijWtk1jn0ym1RzOYBotP0VFhXX5bF1HHoGGwQWC32fgqFWwxJ8PGPASSWORD: AgC5TnoWNEQK13fJHfxM8/ZHRlX85Kd11d8Ig+PgMGcLkxab7fvZJuzg7VX0iksK2UG/c1w1q8fRigMl1WWxmZvW2zM4/BsF45WR99QGt4Z1dhTFHdL5/7OZq2jDMYY5x/7gzCccb2pMAZS7p4rjnJM0EPd7YuMlhXZwIjXcck9Qu8GDpyEu1gg2A1tIfUzjvD+HeTbs6NLy16WHYpMG7Wv4WBNNPO+0k5Z0OwwXmIFSJvSMUHWBg/u2JCJ/1DL0zLyRCdXXOB8VVGok3TFbNscGQqFtFkaaVd0rA4Ao6abrsezcsfZFkcSsfVhATAw+M8ORYRC642BFJjzbhGSbDBsYq7aYyT86MVoqnRJgXK7/K2qzIeT9agM3sJm3ZuRjVCBDGdp/Xo2Rbtely8PH4GwEZI+vRFhTFAj5maduHMt0ZmScusOKuGvr0kFFXKw6XthBT3Arg5Q40upiBtPPrpWhWJYtgT3EfFuXNoc1c1Do7UZ5cmfe51sOBkMZjYk7+8B8a2IejKRflynBcCDQ7r2u76SF18dS5/R7jdOlreyL0yuEiULicKpX8BXPa9dN6Xja8OVPfIHvk0+TwnaYx7YaZDEXlyG0GKv9R3i0wykL1RdDCii6eRSJAp1UFmnCKZJJd9Y6djw7XBAd9G/ux8Vz45XkP+f2Kfgx32HmZsqPq2xaW5DoAeM33uDMfi3Ist+FVRtffuSrTQwBNp76VyhI7YY9MSB5JR1sBUGxGXtAGg==Remove unnecessary '# added' comment.
#ai-review-inline
Inline review
@@ -0,0 +5,4 @@name: forte-drop-secretsnamespace: forte-dropspec:encryptedData:Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +6,4 @@namespace: forte-dropspec:encryptedData:PASSWORD_GATE_SECRET: AgAlZOSURqrQo7dqylFYetr50dWEgWNWTtBEjwgmIp/aFbr2X29xSD0gHpANIF+eXuZ1zGvTX9j2r4YoXgmcb/MjKMd85mYG7FTa0PFdxSxighvKOS3BWQwb7chgNFHMwiZNQAAMNUD6NjlfLZXS0V2SMI+5zz2siYjt8OfgLKfSx5v8+zDFb+pGrCUuUZlMaqFF2ZmOryYNMYYq69iE2EW8UQcP49tmP4aaPx5wIGq6nIo+Qc/c6L4K83nK5ijHEipkgEs0Z0vDTDT4ZBbV0Qyif+Uc1j0eG9+vvIkHBCrGC0WbLOCXiSwmzYF5U2uTRKUbkiPWfohW1Ds2hqveIwg6oSOhK6B+O9s17QagKenYBEER2WAXLq/BLbFpwwijZcGaVnIYsFLUjcheQVPEdaxIyOPh3/qhDjEBX7PevwDzEyOGB6W54TAndx/Go6+Mnvq4aefTOsD+Jy9Iqc3SI3mDoTCSuDMrgnE4QUlImm+Qtk+qPC35n36B9s7yqsHZISbC4zBGAwk7MFfhwTZ3t4z3WXBjevT1zFfs/NeQaRPlcRtO7656C62qroOITty0rT4JAbz93fanqHlqFmiMrYNUIu3wlbr/NGgMlZ1kRVnwIryVup5vljZmvhRtF+TGMwIA+3zbO9U3NasjScnh5sraOauIf7kVsBYTU/2oKb37HvroyILXd8fbpPq+lZ1ejcvVseC+heOI6hvvH/DYztgFn5s9egzcfauicCijWtk1jn0ym1RzOYBotP0VFhXX5bF1HHoGGwQWC32fgqFWwxJ8Remove unnecessary '# added' comment.
#ai-review-inline
@@ -0,0 +7,4 @@spec:encryptedData:PASSWORD_GATE_SECRET: AgAlZOSURqrQo7dqylFYetr50dWEgWNWTtBEjwgmIp/aFbr2X29xSD0gHpANIF+eXuZ1zGvTX9j2r4YoXgmcb/MjKMd85mYG7FTa0PFdxSxighvKOS3BWQwb7chgNFHMwiZNQAAMNUD6NjlfLZXS0V2SMI+5zz2siYjt8OfgLKfSx5v8+zDFb+pGrCUuUZlMaqFF2ZmOryYNMYYq69iE2EW8UQcP49tmP4aaPx5wIGq6nIo+Qc/c6L4K83nK5ijHEipkgEs0Z0vDTDT4ZBbV0Qyif+Uc1j0eG9+vvIkHBCrGC0WbLOCXiSwmzYF5U2uTRKUbkiPWfohW1Ds2hqveIwg6oSOhK6B+O9s17QagKenYBEER2WAXLq/BLbFpwwijZcGaVnIYsFLUjcheQVPEdaxIyOPh3/qhDjEBX7PevwDzEyOGB6W54TAndx/Go6+Mnvq4aefTOsD+Jy9Iqc3SI3mDoTCSuDMrgnE4QUlImm+Qtk+qPC35n36B9s7yqsHZISbC4zBGAwk7MFfhwTZ3t4z3WXBjevT1zFfs/NeQaRPlcRtO7656C62qroOITty0rT4JAbz93fanqHlqFmiMrYNUIu3wlbr/NGgMlZ1kRVnwIryVup5vljZmvhRtF+TGMwIA+3zbO9U3NasjScnh5sraOauIf7kVsBYTU/2oKb37HvroyILXd8fbpPq+lZ1ejcvVseC+heOI6hvvH/DYztgFn5s9egzcfauicCijWtk1jn0ym1RzOYBotP0VFhXX5bF1HHoGGwQWC32fgqFWwxJ8PGPASSWORD: AgC5TnoWNEQK13fJHfxM8/ZHRlX85Kd11d8Ig+PgMGcLkxab7fvZJuzg7VX0iksK2UG/c1w1q8fRigMl1WWxmZvW2zM4/BsF45WR99QGt4Z1dhTFHdL5/7OZq2jDMYY5x/7gzCccb2pMAZS7p4rjnJM0EPd7YuMlhXZwIjXcck9Qu8GDpyEu1gg2A1tIfUzjvD+HeTbs6NLy16WHYpMG7Wv4WBNNPO+0k5Z0OwwXmIFSJvSMUHWBg/u2JCJ/1DL0zLyRCdXXOB8VVGok3TFbNscGQqFtFkaaVd0rA4Ao6abrsezcsfZFkcSsfVhATAw+M8ORYRC642BFJjzbhGSbDBsYq7aYyT86MVoqnRJgXK7/K2qzIeT9agM3sJm3ZuRjVCBDGdp/Xo2Rbtely8PH4GwEZI+vRFhTFAj5maduHMt0ZmScusOKuGvr0kFFXKw6XthBT3Arg5Q40upiBtPPrpWhWJYtgT3EfFuXNoc1c1Do7UZ5cmfe51sOBkMZjYk7+8B8a2IejKRflynBcCDQ7r2u76SF18dS5/R7jdOlreyL0yuEiULicKpX8BXPa9dN6Xja8OVPfIHvk0+TwnaYx7YaZDEXlyG0GKv9R3i0wykL1RdDCii6eRSJAp1UFmnCKZJJd9Y6djw7XBAd9G/ux8Vz45XkP+f2Kfgx32HmZsqPq2xaW5DoAeM33uDMfi3Ist+FVRtffuSrTQwBNp76VyhI7YY9MSB5JR1sBUGxGXtAGg==Remove unnecessary '# added' comment.
#ai-review-inline
Inline review
What changed: Added new ArgoCD Applications for Forte Drop web service and MCP service with supporting Kubernetes resources.
Affected services/namespaces:
forte-dropnamespaceforte-drop(web) andforte-drop-mcpapplicationsupc-devoverlay (excluded from production)Infrastructure impact:
Security notes:
#ai-review-summary
ai-review triage
Gått igjennom alle inline-kommentarene. Én fikset, resten avvist med begrunnelse.
Fikset
auth-oidc-sealed.yamllinje (61a8a2b) — erstattet med en tydelig NOTE som forklarer at det er et bevisst post-deploy steg (krever registrar-generert client-secret), ikke en disabled resource.Avvist — konvensjon
vaultwarden(https://vaultwarden.forteapps.net/*), gitea, grafana, argocd. Ingen templating finnes i launchpad for dette. Realmen er per-cluster (id.forteapps.net dev / id.fortedigital.com prod), og forte-drop er scoped til upc-dev-overlay. Templating ville vært en ny abstraksjon ingen andre clients bruker.targetRevision: HEAD→main(×3) — alle eksisterende apps (mcp10x, argo-mcp, ts-mcp) brukerHEAD(6/6). Å endre kun forte-drop = inkonsistent.Avvist — false positives
client.json), inneholder ingen secret-verdi.clientAuthenticatorType: client-secretbetyr Keycloak genererer secret; den står ikke i Git. Self-service-mønster per DEVELOPER-GUIDE.md.grep "# added"= ingen treff. Disse kommentarene finnes ikke i fila.Klar for menneskelig review.
Din AI gjør en feil tolkning med secrets. Du trenger ikke vente på at noe skal opprettes og lage SealedSecret.
Du har allerede definert Keycloak client her
apps/base/forte-drop/keycloak-client-forte-drop.yamlDette blir synket til keycloak namespace, en CronJob plukker opp og lager klienten og en secret, og dette pushes til ditt namespace som en secret. Så ingen ny SealedSecret skal være nødvendig.
Og du vurderer selv om
ai-reviewlabel er noe som gir deg verdi. Jeg ser at den av og til blir litt chatty med mange meldinger, men dette kan vi justere i instructions og kanskje ha et tak på 5-10 mest kritiske.@@ -0,0 +25,4 @@"redirectUris": ["https://drop-k8s.hackathon.forteapps.net/auth/callback"],"webOrigins": ["https://drop-k8s.hackathon.forteapps.net"],"defaultClientScopes": ["openid","email","profile"]}Det du mangler her er hvor du vil at
Secretskal bli laget og med hvilke keys:Detaljert forklaring, hvis interessant:
What a Developer Should Push
A developer deploying a new application must create a Config Secret in their application's namespace. This Secret contains the desired Keycloak client configuration.
The Format
Kubernetes Secret YAML:
How It Works: Client ID vs Client Secret
Client ID (Pre-determined by Developer):
clientId(e.g.,"myapp")client-id)Client Secret (Generated by Keycloak):
Keycloak auto-generates a cryptographically secure secret
The CronJob fetches it via:
GET /admin/realms/forte/clients/{uuid}/client-secretThe CronJob then creates/updates TWO Secrets:
1. Target Namespace Secret (
myapp/myapp-oidc-credentials):2. Central Backup Secret (
secrets/myapp-oidc-credentials):Developer Workflow
Create Config Secret in your Helm chart or Kustomize (in your app's namespace)
Deploy - Kyverno policy clones it to
keycloaknamespace automaticallyWait - CronJob picks it up within 2 minutes
Reference the generated credential Secret in your Deployment:
Change Detection
The CronJob computes a SHA256 hash of
client.json. If unchanged and credential Secret exists, it skips processing. To force re-sync, modify any field inclient.json(e.g., add trailing space toname).@@ -0,0 +10,4 @@keycloak.forteapps.net/client-config: "true"stringData:client.json: |{Du trenger ikke en egen klient for mcp server. Det lages automatisk når du legger inn
auth.type: mcpi helm values. Så denne kan slettes.Per platform review (danijel): - keycloak-client-forte-drop: add the secret{} block telling the registrar where to write the credential Secret + key names (forte-drop-oidc-credentials, client-id/client-secret). The forte-helm oidc sidecar consumes that registrar-created Secret — no manual auth-oidc SealedSecret step (removed that NOTE). - Delete keycloak-client-forte-drop-mcp: auth.type: mcp auto-registers the MCP client; no manual config needed. - Re-seal forte-drop-secrets with all shared env (BASE_DOMAIN, PG*, S3_*, PASSWORD_GATE_SECRET) so both deployments get identical values via envSecretName (values extraEnv now carries only APP_MODE).Oppdatert etter platform-review (@danijel.simeunovic, på helm-prod-values #3)
Reviewen kom på #3 men flere punkter gjaldt launchpad-manifestene her. Adressert i
338b4de:secret-blokken — forteller registrar hvor + med hvilke keys credential-secreten lages:keycloak-client-forte-drop-mcp.yaml—auth.type: mcpauto-registrerer mcp-klienten via chart. Ingen manuell config nødvendig.forte-drop-oidc-credentialsautomatisk og sidecaren (auth.type: oidc) konsumerer den. Ingen seal-by-hand. Slettet NOTE-en i kustomization.forte-drop-secretsmed all delt env (BASE_DOMAIN, PG*, S3_*, PASSWORD_GATE_SECRET, 12 keys) — begge deployments mounter den viaenvSecretName, så valuesextraEnvhar nå kunAPP_MODE.Tilhørende: app-en gjort helt auth-uvitende i egen forte_drop PR (slettet JWT/OIDC-kode). Klar for re-review.
Gode tilbakemeldinger! Jeg tror jeg forstår litt og litt mer 😄 den ai-reviewen er litt chatty ja!
Jeg har prøvd å justere litt og be om maks 10 kommentarer, men forstår ikke enda hvorfor den ignorerer... :)
Jeg så for meg at dette skulle plasseres i
apps/overlays/upc-dev, ikke ibase/.... Jeg innser at det ligger flere ting der som helst skulle flyttes, men det er min feil fordi de ble lagt inn før overlays kom inn i bilde.Skal jeg flytte det dit?
Ja, gjerne.
Flyttet til
apps/overlays/upc-dev(335dd13)Som avtalt —
forte-drop,forte-drop-mcpogforte-drop-postgresqlflyttet fraapps/base/tilapps/overlays/upc-dev/(rengit mv, historikk bevart). De var aldri listet iapps/base/kustomization.yaml— kun wiret inn via upc-dev-overlayet — så de hører hjemme her sammen meddbunk-demo.Utover selve flyttingen:
../../base/forte-drop*→ lokale refsforte-drop-postgresqlApplicationpath:apps/base/...→apps/overlays/upc-dev/forte-drop-postgresql/resources(selv-referanse til repoet, måtte følge med)Verifisert render-nøytralt:
kubectl kustomize apps/overlays/upc-devskiller seg kun på postgres-path-linjaapps/overlays/upc-prodrender byte-identisk (forte-drop når aldri prod)Review-gate (CLAUDE.md): codex +
/code-reviewbegge rene, ingen funn. Lot resten avapps/base/urørt — de andre appene der deles mellom clustere; de "flere ting" du nevnte kan tas i egen PR.Klar for re-review @danijel.simeunovic
Two ArgoCD apps from the same forte-drop image: - forte-drop (web): admin + public drops, sidecar in oidc mode, ingress drop-k8s.hackathon.forteapps.net. - forte-drop-mcp (mcp): MCP-over-HTTP, sidecar in mcp mode, ingress mcp.drop-k8s.hackathon.forteapps.net. Plus two labeled Keycloak client config Secrets — the registrar creates the OIDC clients in the forte realm within ~2 min. Sealed secrets (forte-drop-secrets + auth-oidc) added in a follow-up commit by the maintainer: cd /Users/sten/dev/work/forte_k8/launchpad kubeseal --format=yaml \ --controller-name=sealed-secrets-controller \ --controller-namespace=kube-system \ < private/forte-drop-secrets.yaml \ > apps/base/forte-drop/forte-drop-secrets-sealed.yaml # auth-oidc: wait for registrar, copy client-secret into private/, # then seal as apps/base/forte-drop/auth-oidc-sealed.yaml. # (mcp deployment is sidecar type=mcp — no auth-oidc Secret needed; # only the web deployment requires it.)Per platform review (danijel): - keycloak-client-forte-drop: add the secret{} block telling the registrar where to write the credential Secret + key names (forte-drop-oidc-credentials, client-id/client-secret). The forte-helm oidc sidecar consumes that registrar-created Secret — no manual auth-oidc SealedSecret step (removed that NOTE). - Delete keycloak-client-forte-drop-mcp: auth.type: mcp auto-registers the MCP client; no manual config needed. - Re-seal forte-drop-secrets with all shared env (BASE_DOMAIN, PG*, S3_*, PASSWORD_GATE_SECRET) so both deployments get identical values via envSecretName (values extraEnv now carries only APP_MODE).Du er utrolig god på detaljerte kommentarer og oppdateringer, veldig imponert! Bra jobba!