Guardrail
Ambito: namespaced · Modalità: catalog (motore incluso) · external (HTTP proprio) · Con licenza: guardrail (Enterprise)
Un Guardrail definisce un guardrail sul percorso dei dati — moderazione dei contenuti / gestione dei dati personali (PII) eseguita all'interno del percorso delle richieste di un Gateway. Fai riferimento a esso da un Gateway tramite spec.guardrailRefs; l'operatore emette per te il collegamento LiteLLMGuardrail upstream.
Entrambe le modalità richiedono la funzionalità con licenza guardrail ed entrambe passano attraverso un piccolo proxy di controllo della licenza (license-gate proxy) che l'operatore inserisce davanti al guardrail. Il proxy verifica la licenza firmata e fallisce in modo chiuso (fail closed): se la licenza decade (scaduta, revocata o rimossa), ogni richiesta riceve un verdetto di blocco del guardrail invece di essere inoltrata — il guardrail smette di fornire valore nel momento in cui non sei più in possesso della licenza. Sui cluster senza licenza il Guardrail risulta Refused e non viene collegato nulla.
Spec
| Campo | Tipo | Descrizione |
|---|---|---|
mode | enum catalog | external (obbligatorio) | Motore incluso oppure il tuo endpoint HTTP |
catalog | string | Chiave del motore incluso (mode=catalog), ad es. pseudonymizer |
external | object | Il tuo guardrail HTTP (mode=external) |
guardrailName | string | Sostituisce il guardrail_name di LiteLLM (per default la chiave del catalogo o il nome della CR) |
modes | []enum pre_call | post_call | during_call | logging_only | Modalità di esecuzione; viene emesso un LiteLLMGuardrail per ciascuna modalità. Per default le modalità del motore (il pseudonymizer esegue pre_call+post_call) oppure [pre_call] per external |
defaultOn | bool | Esegue su ogni richiesta anche senza un opt-in esplicito di key/team. I motori del catalogo sono attivi per default; external è disattivato per default |
params | object (JSON arbitrario) | Parametri del provider inoltrati a LiteLLM in additional_provider_specific_params (uniti sopra i valori predefiniti del motore) |
logLevel | enum debug | info | warn | error | Livello di dettaglio dei log del proxy di controllo della licenza. debug registra un record per ogni richiesta al guardrail — vedi Diagnostica. Modificarlo riavvia il pod del proxy |
blockedReason | string | Messaggio che il proxy restituisce quando blocca una richiesta perché la funzionalità non è coperta da licenza. Rendilo riconoscibile per individuare un blocco del controllo licenza nei log del gateway |
external
| Campo | Descrizione |
|---|---|
apiBase | Il tuo endpoint HTTP del guardrail (generic_guardrail_api di LiteLLM; esegue POST verso {apiBase}/beta/litellm_basic_guardrail_api) |
apiKeySecretRef | Secret nello stesso namespace il cui valore il proxy inoltra al tuo endpoint come x-api-key |
unreachableFallback | fail_closed (predefinito) o fail_open — il comportamento di LiteLLM se il guardrail non è raggiungibile |
Modalità
catalog— l'operatore distribuisce il motore incluso come un'unica release condivisa e con conteggio dei riferimenti per il cluster (innavique-guardrail-system) e vi antepone un proxy di controllo della licenza per ciascun Guardrail. Il primo motore èpseudonymizer(pseudonimizzazione dei PII: maschera i nomi di persone/organizzazioni prima che il modello li veda e li ripristina nella risposta). Dalla versione 0.4.0 serve anche il protocollo guardrail di Wäg su un secondo endpoint, sullo stesso archivio di mappature.external— l'operatore distribuisce solo il proxy di controllo della licenza, puntato verso il tuoapiBase. È comunque soggetto a licenza e passa dal proxy (a differenza dei server MCP esterni, i guardrail propri non sono gratuiti).
Come si collega a un Gateway
Aggiungi il Guardrail ai guardrailRefs di un Gateway. Quando il Guardrail è Ready, il Gateway emette un LiteLLMGuardrail per ciascuna modalità, il cui apiBase è il proxy di controllo della licenza del Guardrail (status.endpoint) — mai il motore diretto. Rimuovere il riferimento (o eliminare il Guardrail) elimina il collegamento emesso.
Esempio — pseudonymizer PII incluso
apiVersion: core.navique.com/v1alpha1
kind: Guardrail
metadata:
name: pii-pseudonymizer
namespace: forge
spec:
mode: catalog
catalog: pseudonymizer
---
apiVersion: core.navique.com/v1alpha1
kind: Gateway
metadata:
name: forge-gw
namespace: forge
spec:
# … database/instance/secrets …
guardrailRefs:
- { name: pii-pseudonymizer }Esempio — il tuo guardrail HTTP
apiVersion: core.navique.com/v1alpha1
kind: Guardrail
metadata:
name: my-moderation
namespace: forge
spec:
mode: external
modes: [pre_call]
external:
apiBase: https://guardrail.example.com
unreachableFallback: fail_closed
apiKeySecretRef: { name: my-guardrail-key, key: apiKey }Diagnostica di una chiamata al guardrail non riuscita
Un blocco del guardrail è volutamente indistinguibile per il chiamante, il che lascia tre possibili cause di errore che appaiono identiche dal gateway:
- il gateway non ha mai chiamato il guardrail e ha fatto fallire la richiesta per un altro motivo,
- l'ha bloccata il proxy di controllo della licenza (senza licenza / scaduta / revocata),
- l'ha bloccata il motore, oppure il motore non era raggiungibile.
Il proxy è l'unico componente che vede tutti e tre i casi, quindi li riporta in due modi.
Contatori (sempre attivi)
Ogni proxy espone contatori Prometheus sulla porta 9090, separata dalla porta dati (8080), così non possono oscurare un percorso del tuo motore guardrail:
kubectl port-forward -n forge svc/pii-pseudonymizer-guardrail-proxy 9090:9090
curl -s localhost:9090/metrics| Metrica | Risponde a |
|---|---|
navique_guardrail_proxy_requests_total{decision="forwarded"} | il gateway ha mai chiamato il guardrail? Un contatore fermo significa che non l'ha mai fatto |
…{decision="blocked_unlicensed"} | l'ha bloccata il controllo della licenza? |
…{decision="upstream_error"} | il motore era irraggiungibile? |
navique_guardrail_proxy_upstream_verdicts_total{action="…"} | cosa ha deciso il motore — NONE, GUARDRAIL_INTERVENED o BLOCKED? |
navique_guardrail_proxy_upstream_duration_seconds_{sum,count} | quanto sono lente le chiamate al motore? |
navique_guardrail_proxy_license_valid | la licenza montata soddisfa attualmente guardrail? |
Log per richiesta
Imposta spec.logLevel: debug sul Guardrail (questo riavvia il pod del proxy) per ottenere un record strutturato per ogni richiesta:
{"level":"DEBUG","msg":"guardrail request","request_id":"9f2c…","method":"POST",
"path":"/beta/litellm_basic_guardrail_api","decision":"forwarded","status":200,
"duration_ms":37,"upstream_action":"BLOCKED","upstream_blocked_reason":"…"}decision è ciò che ha fatto il proxy; upstream_action è il verdetto del motore stesso, riletto dalla risposta senza alterarla. L'header X-Request-Id viene riutilizzato dal chiamante se presente, altrimenti generato, inoltrato al motore e restituito nella risposta — così un unico id collega i log di gateway, proxy e motore.
WARNING
upstream_blocked_reason è il messaggio del motore stesso e può citare il contenuto su cui ha trovato una corrispondenza. Alza logLevel durante l'indagine, poi riabbassalo.
Due cose che il proxy volutamente non nasconde
- Un motore irraggiungibile restituisce HTTP 502, non un blocco. "Il motore è giù" non equivale a "il motore ti ha bloccato": LiteLLM applica
unreachableFallback(fail_closed/fail_open) a un errore di trasporto, e sintetizzare un blocco annullerebbe silenziosamente una sceltafail_open. Questi errori vengono registrati a livelloerrorindipendentemente dalogLevel. - I blocchi del controllo della licenza vengono registrati quando cambiano stato. Il proxy registra un warning nel momento in cui la licenza smette di soddisfare
guardrail(e una riga info quando torna a soddisfarla), così una decadenza è visibile senza i log di debug. Nota che/healthze/readyzrestano a200anche mentre il proxy fallisce in modo chiuso — il pod è sano, l'applicazione avviene per singola richiesta, quindi non basarti sulla readiness del pod per lo stato della licenza; usanavique_guardrail_proxy_license_valid.
Note
- Un operatore determinato potrebbe scrivere a mano un
LiteLLMGuardrailupstream grezzo per aggirare il controllo della licenza; la piattaforma evita gli admission webhook, quindi il controllo interno è best-effort — solo il percorso supportato e gestito è soggetto al controllo. - Il proxy di controllo della licenza è un'immagine separata e closed-source (
ghcr.io/scigility/navique-guardrail-proxy); sostituiscila con--guardrail-proxy-imageo con il mirror host del registry di PlatformConfig.
Status
{ phase, endpoint (the proxy URL the Gateway wires), guardrailNames, unreachableFallback, conditions, observedGeneration }. Nome breve gr.