catalog-agent was one rename too aggressive: 'catalogue' is accepted, and the
Keycloak client, its audience scope and the Vault key that names it were never
renamed to match — leaving an inconsistency between what Kubernetes and
Keycloak call the same agent. Keycloak carries more weight to move, so this
side moves back.
k8s/namespace.yaml is out of this Kustomization's inventory. It was in
2026-08-31 when renaming the Kustomization pruned the old one — which owned
the namespace three agents share — and took all three down. A namespace shared
across repos should not be owned by any one of them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nothing outside the cluster could talk to it: every conversation went through
kubectl run curl, which makes an agent that works and nobody can use.
The same authentication subrequest that guards the n8n endpoints guards this
one. The agent forwards and exchanges the caller's token, so a forged one
fails at the realm — but failing downstream is not refusing, and an
unauthenticated caller could still make it do inference.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two-stage Dockerfile: the runtime image carries neither uv nor a build
toolchain, runs as uid 10001, drops every capability and needs no writable
filesystem (verified with --read-only and no tmpfs).
k8s/ is what runs, dev/ is the Flux plumbing that applies it, self-managing
after three manual applies — the same shape every kong-* repo settled on.
Three choices worth naming:
- One namespace for the estate. What isolates an agent is its Keycloak client
and the audiences it may request, not a namespace boundary.
- The GitRepository uses anonymous HTTPS rather than SSH with a Vault-held
deploy key. The repo is already anonymously readable on gitea, so a key would
guard nothing while adding two objects to create by hand before anything
deploys. If the repos ever go private this becomes the kong-* SSH pattern.
- The lab CA certificate is committed. It is a certificate, never a key, and
checking it in means the deployment has no hidden prerequisite.
replicas: 1 is a constraint, not a default — conversation history lives in the
process, so a second replica would route a user's "yes" to a pod that never saw
the question.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>