Files
homelab/k8s/apps/api/model-auth.yaml
T

50 lines
1.9 KiB
YAML

# 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 <key>` (or `apikey: <key>`). 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 <key>` 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