# API auth layer — Kong key-auth on the model routes. # # The model API (api.riotpiao.com/v1/...) requires a static API key, presented # OpenAI-style as `Authorization: Bearer ` (or `apikey: `). The key # lives in the ksops-managed Secret model-invoke-apikey (labelled # konghq.com/credential: key-auth) and is bound to the KongConsumer below. # # Issue the key to rock; use it as the OpenAI SDK api_key. Rotate by updating the # ksops secret. This is self-contained in Kong — the invoke path does not depend # on an Authentik token (Authentik still fronts every *human* dashboard SSO). --- apiVersion: configuration.konghq.com/v1 kind: KongConsumer metadata: name: model-invoker namespace: api annotations: kubernetes.io/ingress.class: kong username: model-invoker credentials: - model-invoke-apikey --- # key-auth: require the API key on the model routes. key_in_header accepts the # `apikey` header; key_in_bearer accepts `Authorization: Bearer ` so any # OpenAI-compatible SDK (api_key=..., base_url=https://api.riotpiao.com/v1) works # unchanged. # # Namespace `llm-serving`, not `api`: the ingress controller resolves a # `konghq.com/plugins` annotation against the annotated object's OWN namespace, # and all five model routes in llm-routes.yaml live in llm-serving. While this # sat in `api` the reference dangled, the plugin never bound, and every model # route served traffic with no key at all — verified: an unauthenticated # /v1/models and /v1/ornith/chat/completions both returned 200. A dangling # plugin reference is silent; it fails open, so re-test without a key after any # move rather than trusting that the object exists. apiVersion: configuration.konghq.com/v1 kind: KongPlugin metadata: name: model-key-auth namespace: llm-serving plugin: key-auth config: key_names: - apikey - authorization key_in_header: true key_in_query: false key_in_body: false hide_credentials: true