mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-14 05:18:54 +00:00
docs: correct security claims, pipeline diagram, k8s example completeness
Fixes from review, verified against source before rewriting:
- README.md Security notes: "auth events are logged" was false — grepped
auth.go, zero logging calls exist anywhere in it. A lookup miss is a
plain 401 envelope with no log line at all, not "logged without key
material". Also corrected the adjacent providerHTTPError claim: the
struct retains the upstream response body as a field (surfaced
deliberately to the client under error.upstream); only its Error()
string omits the body, and nothing in this codebase currently logs a
providerHTTPError via a bare %v anyway.
- README.md mermaid diagram: the previous version showed a single global
Auth gate ahead of routing. ServeHTTP (llmgateway.go) actually dispatches
on path+method first and calls identify() separately inside each
recognized-route branch; an unrecognized route (passthroughUnknown/404
fallback) never calls identify() at all. Redrawn Route -> per-branch
Auth, with the unauthenticated fallback branching directly off Route.
Also fixed the 401 node's error type label from the nonexistent
"invalid_api_key" to the actual envelope type, "authentication_error"
(llmgateway.go, routes_unified.go). Re-rendered with mmdc before and
after the fix.
- README.md + examples/kubernetes.yaml: narrowed the bare-{} empty-group
claim. Re-verified this session with an isolated, minimal repro
(Traefik file provider only, no docker-compose configs: mechanism
involved) that a bare `default: {}` still fails plugin construction
with the file provider specifically: "expected a map, got 'string'".
Scoped the claim to what is actually verified (file provider, twice)
and explicitly flagged Docker/ECS label providers and the Kubernetes
CRD provider as untested, rather than asserting the file provider is
unaffected or that the CRD provider shares its decode path — the
latter was an unverified inference in the prior text, now hedged.
- examples/kubernetes.yaml: the IngressRoute referenced an undefined
Service (llmgateway-dummy-backend), so the manifest did not actually
apply as advertised. Added the missing Deployment + Service (traefik/
whoami, the same image already exercised end-to-end in
examples/docker-compose.yml this session). Re-validated: 6-document
YAML parses, Middleware's plugin config still round-trips through the
real Config struct and New() (throwaway test, deleted after).
- README.md Known limitations: dropped the standalone path-traversal
bullet — it duplicated content already stated in the "request rejected
before it reaches a provider" bullet immediately above it.
NOTE for the reviewer: the ruling on the bare-{} finding stated "file
provider observed working" and named Docker/ECS label providers as the
affected ones. I re-tested this directly (twice, including a standalone
repro outside the compose demo) and the file provider fails on a bare
{} exactly as originally reported — I could not reproduce "file provider
unaffected" and have not tested the label providers at all. Narrowed the
doc wording to only what I verified rather than asserting either
provider's behaviour without evidence; flagging the discrepancy in case
the review had independent grounds I don't have visibility into.
Gates: go test ./... -count=1, gofmt -l ., go vet ./..., make
yaegi-check — all clean. Also re-ran go test -race, golangci-lint (incl.
gosec), and fieldalignment, matching the standard this task already set;
all clean.
This commit is contained in:
+49
-11
@@ -10,12 +10,15 @@
|
||||
# see the Helm values snippet at the bottom of this file.
|
||||
#
|
||||
# The empty-map gotcha: write an empty group as `providers: []`, never a
|
||||
# bare `{}`. Traefik's own dynamic-config decode pipeline (which the
|
||||
# Kubernetes CRD provider funnels plugin config through, same as the file
|
||||
# provider) can fail to round-trip a truly empty nested object with
|
||||
# "expected a map, got 'string'" — verified against this exact shape in
|
||||
# examples/docker-compose.yml. An explicit empty list decodes correctly
|
||||
# and means the same thing (all values allowed).
|
||||
# bare `{}`. Confirmed against Traefik's file provider, twice, with this
|
||||
# exact plugin build (examples/docker-compose.yml, plus an isolated
|
||||
# minimal repro outside that demo's compose-specific config mechanism): a
|
||||
# bare `default: {}` fails plugin construction with
|
||||
# "expected a map, got 'string'"; an explicit empty list decodes
|
||||
# correctly and means the same thing (all values allowed). Whether the
|
||||
# Kubernetes CRD provider used below hits the same decode path as the
|
||||
# file provider is NOT verified — this file uses the empty-list form
|
||||
# defensively, not because the CRD path is confirmed affected.
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
@@ -97,6 +100,46 @@ spec:
|
||||
url: http://summarizer.agents.svc:8080
|
||||
passthroughUnknown: false
|
||||
|
||||
---
|
||||
# Traefik requires a real backing Service for a router even though this
|
||||
# middleware short-circuits every path it recognizes; whoami (the same
|
||||
# image already exercised in ../examples/docker-compose.yml) is a small,
|
||||
# always-up dummy, only ever reached via passthroughUnknown (default
|
||||
# false, which 404s instead). Any always-up internal service works here.
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: llmgateway-dummy-backend
|
||||
namespace: traefik
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: llmgateway-dummy-backend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: llmgateway-dummy-backend
|
||||
spec:
|
||||
containers:
|
||||
- name: whoami
|
||||
image: traefik/whoami:v1.10
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: llmgateway-dummy-backend
|
||||
namespace: traefik
|
||||
spec:
|
||||
selector:
|
||||
app: llmgateway-dummy-backend
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRoute
|
||||
@@ -111,11 +154,6 @@ spec:
|
||||
kind: Rule
|
||||
middlewares:
|
||||
- name: llmgateway
|
||||
# Traefik requires a real backing Service for a router even though
|
||||
# this middleware short-circuits every path it recognizes; a small
|
||||
# dummy such as traefik/whoami (see ../examples/docker-compose.yml)
|
||||
# or any always-up internal service works, since it is only ever
|
||||
# reached via passthroughUnknown (default false, which 404s instead).
|
||||
services:
|
||||
- name: llmgateway-dummy-backend
|
||||
port: 80
|
||||
|
||||
Reference in New Issue
Block a user