You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Three guardrail integrations that come up in ~80% of security-conscious procurement conversations, each closing a category where competitors currently lead us:
Revised 2026-07-06 — the original body (written 2026-05-29) predated a large batch of guardrail platform work (#694 pii kind, #719 Bedrock ANONYMIZE, enforcement_mode=monitor, output-side redaction incl. streaming). Every platform prerequisite it listed as blocked is now shipped; the plan below is updated accordingly. Repo pointers refreshed: DP = api7/aisix (renamed from ai-gateway), CP+UI = api7/AISIX-Cloud, user docs = api7/docs under docs/ai-gateway/.
Current shipped state (origin/main, 2026-07-06)
Guardrail kinds are keyword, pii (built-in detectors + custom regex, mask/block, input+output incl. streaming — #694), bedrock (incl. sensitive-info filters with ANONYMIZE mask-and-continue — #719), azure_content_safety (Prompt Shield), azure_content_safety_text_moderation, and aliyun_text_moderation. None of Lakera, Presidio, or OpenAI Moderation exist yet.
Platform capabilities the original plan can now assume instead of building:
Output-side redaction is shipped. The old Rewrite{payload} verdict no longer exists; redaction goes through the Guardrail trait's redact_input_text / redact_output_text (+ SegmentsOutcome for segment moderation), with streaming handled by StreamOutputPolicy::BufferFull hold-back and capture rebuild. Presidio output-redact is therefore in scope for this pass — the follow-up split is obsolete.
Monitor mode is a platform feature.enforcement_mode: monitor|block wraps any kind in a MonitorGuardrail decorator (observes, never blocks/redacts, no stream hold-back). The bespoke flag_only action originally planned for OpenAI Moderation is unnecessary — drop it.
Credential handling: org-scoped encrypted credentials (Bedrock/ACS/Aliyun pattern) — ciphertext at rest in cp-api, plaintext only in the in-memory DP snapshot, blank-on-edit in the UI.
fail_open / output_fail_open, mandatory (fail-closed), per-request applied_guardrails telemetry, and the DP heartbeat supported_kinds gate all exist.
Note on the generic webhook:#61 proposes a universal webhook guardrail kind that can reach any HTTP guardrail vendor with zero per-vendor DP code (LiteLLM baseline: generic_guardrail_api). Lakera and OpenAI Moderation could in principle be driven through it. They are still worth a small bespoke module here because (a) they're the highest-volume procurement asks and deserve first-class UI/validation, and (b) Presidio's two-call analyze→anonymize flow needs native handling the generic webhook does not model. Treat this issue as the "first-class three"; everything else goes through the webhook (#61, deliberately deferred).
Cross-repo scope
Each integration is a Guardrail trait impl in its own module of aisix-guardrails, plus a GuardrailKind variant + regenerated resource schema + CP descriptor + schema-driven UI form + e2e.
CP (api7/AISIX-Cloud): guardrail config descriptors (internal/cpapi/resources/guardrail_schema*.go) for the three kinds — the dashboard renders forms from the served JSON Schema (SchemaForm), so no hand-coded React form per kind. Kind validation + etcd projection + encrypted secrets.
Docs (api7/docs): one page per kind under docs/ai-gateway/traffic-controls/guardrails/, paired PR.
2. Research (verify each schema against the primary source before coding; LiteLLM latest is the behavior baseline — lakera_ai_v2.py, presidio.py, OpenAI moderation hook)
API: POST https://api.lakera.ai/v2/guard, Authorization: Bearer <key>. Returns per-category detections and a top-level flagged boolean. Docs: https://docs.lakera.ai
Microsoft Presidio — open-source, self-hosted PII detection + anonymization (no vendor key; the customer runs the containers).
Two-step: POST {analyzer_url}/analyze → detected entities with type, offsets, score; POST {anonymizer_url}/anonymize → transformed text. Entities are configurable (EMAIL_ADDRESS, PHONE_NUMBER, US_SSN, CREDIT_CARD, PERSON, IP_ADDRESS, …). Source: https://microsoft.github.io/presidio/
Re-scoped value vs. the built-in pii kind: pii already covers rule/regex detection with mask/block on both hooks incl. streaming. Presidio's increment is (a) NER/ML entities regex cannot express (PERSON, LOCATION, NRP, …), (b) self-hosted compliance posture, and (c) anonymize operators — replace, redact, mask, hash — which also close the hash/placeholder action gap tracked in AISIX-Cloud#562.
Can reuse an existing OpenAI credential the tenant already has. Monitor-before-enforce comes from platform enforcement_mode, not a bespoke flag_only.
3. UI design
Schema-driven: each kind ships a CP descriptor so the dashboard SchemaForm renders it (secret fields blank-on-edit = keep stored ciphertext, same as the existing remote kinds):
OpenAI Moderation — input hook (output optional): any enforced category over threshold → Block. Monitor mode via enforcement_mode.
Presidio — input and output: analyze; action=block → Block; action=redact → anonymize and rewrite via redact_input_text / redact_output_text; streaming via BufferFull like pii.
Credential storage: same org-scoped encrypted-credential mechanism as Bedrock/ACS. Presidio is self-hosted and needs no vendor secret.
5. Testing & acceptance
Extend the e2e mock service with mock endpoints (Lakera /v2/guard, Presidio /analyze+/anonymize, OpenAI /v1/moderations); point the DP at them via per-kind endpoint override. Real chain end-to-end; mock the external guardrail service only.
OpenAI Moderation: prompt over category threshold → 422; same guardrail with enforcement_mode=monitor → 200 + monitor observation recorded
Presidio block: prompt with PII + action=block → 422
Presidio input-redact: prompt with PII + action=redact → the request the mock upstream receives is anonymized (assert on the body the upstream saw)
Presidio output-redact: response containing PII is anonymized before reaching the caller, non-streaming and streaming (buffer_full)
Presidio hash/replace operators: operator config honored in the anonymized text
Each kind: schema accepts valid config and rejects missing key / bad endpoint
Dashboard CRUD Playwright for each new kind (schema-driven form)
fail_open honored on mock 5xx for the remote-API kinds (all three)
6. Docs
api7/docsdocs/ai-gateway/traffic-controls/guardrails/: one page per kind (config fields, action semantics, fail-open, monitor-first guidance), wired into sidebars.ai-gateway.js. Paired PR, not in this repo.
Estimate
DP ~1d each = 3d (Presidio closer to 2d with operators + output path), CP 1d, docs 0.5d.
Summary
Three guardrail integrations that come up in ~80% of security-conscious procurement conversations, each closing a category where competitors currently lead us:
POST https://api.lakera.ai/v2/guard, Bearer token).POST {analyzer_url}/analyze+POST {anonymizer_url}/anonymize).POST https://api.openai.com/v1/moderations).Current shipped state (
origin/main, 2026-07-06)Guardrail kinds are
keyword,pii(built-in detectors + custom regex, mask/block, input+output incl. streaming — #694),bedrock(incl. sensitive-info filters with ANONYMIZE mask-and-continue — #719),azure_content_safety(Prompt Shield),azure_content_safety_text_moderation, andaliyun_text_moderation. None of Lakera, Presidio, or OpenAI Moderation exist yet.Platform capabilities the original plan can now assume instead of building:
Rewrite{payload}verdict no longer exists; redaction goes through theGuardrailtrait'sredact_input_text/redact_output_text(+SegmentsOutcomefor segment moderation), with streaming handled byStreamOutputPolicy::BufferFullhold-back and capture rebuild. Presidio output-redact is therefore in scope for this pass — the follow-up split is obsolete.enforcement_mode: monitor|blockwraps any kind in aMonitorGuardraildecorator (observes, never blocks/redacts, no stream hold-back). The bespokeflag_onlyaction originally planned for OpenAI Moderation is unnecessary — drop it.fail_open/output_fail_open,mandatory(fail-closed), per-requestapplied_guardrailstelemetry, and the DP heartbeatsupported_kindsgate all exist.Cross-repo scope
Each integration is a
Guardrailtrait impl in its own module ofaisix-guardrails, plus aGuardrailKindvariant + regenerated resource schema + CP descriptor + schema-driven UI form + e2e.api7/aisix):lakera(input-focused),presidio(input + output, block/redact),openai_moderation(input-focused) modules incrates/aisix-guardrails.api7/AISIX-Cloud): guardrail config descriptors (internal/cpapi/resources/guardrail_schema*.go) for the three kinds — the dashboard renders forms from the served JSON Schema (SchemaForm), so no hand-coded React form per kind. Kind validation + etcd projection + encrypted secrets.api7/docs): one page per kind underdocs/ai-gateway/traffic-controls/guardrails/, paired PR.2. Research (verify each schema against the primary source before coding; LiteLLM latest is the behavior baseline —
lakera_ai_v2.py,presidio.py, OpenAI moderation hook)Lakera Guard — prompt-injection / jailbreak / PII / content detection.
POST https://api.lakera.ai/v2/guard,Authorization: Bearer <key>. Returns per-category detections and a top-levelflaggedboolean. Docs: https://docs.lakera.aiMicrosoft Presidio — open-source, self-hosted PII detection + anonymization (no vendor key; the customer runs the containers).
POST {analyzer_url}/analyze→ detected entities with type, offsets, score;POST {anonymizer_url}/anonymize→ transformed text. Entities are configurable (EMAIL_ADDRESS,PHONE_NUMBER,US_SSN,CREDIT_CARD,PERSON,IP_ADDRESS, …). Source: https://microsoft.github.io/presidio/piikind:piialready covers rule/regex detection with mask/block on both hooks incl. streaming. Presidio's increment is (a) NER/ML entities regex cannot express (PERSON,LOCATION,NRP, …), (b) self-hosted compliance posture, and (c) anonymize operators —replace,redact,mask,hash— which also close the hash/placeholder action gap tracked in AISIX-Cloud#562.OpenAI Moderation — free category-based content moderation.
POST https://api.openai.com/v1/moderations, modelomni-moderation-latest. Returns per-category booleans + scores. Source: https://platform.openai.com/docs/guides/moderationenforcement_mode, not a bespokeflag_only.3. UI design
Schema-driven: each kind ships a CP descriptor so the dashboard
SchemaFormrenders it (secret fields blank-on-edit = keep stored ciphertext, same as the existing remote kinds):api_key(secret),endpoint(defaulthttps://api.lakera.ai/v2/guard), optional project id,fail_open,timeout_ms,hook_point(defaultinput).analyzer_url,anonymizer_url,entities(multi-select), score threshold,language, action =block | redact(+ operator: replace/mask/hash),hook_point(defaultboth),fail_open,timeout_ms, streaming buffer knobs (same aspii).api_key(secret), endpoint override (Azure-compatible / mock),model, categories (multi-select) with per-category threshold,fail_open,timeout_ms,hook_point(defaultinput).4. Implementation approach
Three
Guardrailtrait impls following the existingaisix-guardrailsremote-kind pattern (prompt_shield / text_moderation / aliyun are the templates):/v2/guard;flagged→Block{reason}(reason carries detector categories, never matched content — bug: output guardrail error message echoes the matched forbidden literal back to caller #153).Block. Monitor mode viaenforcement_mode.analyze;action=block→Block;action=redact→anonymizeand rewrite viaredact_input_text/redact_output_text; streaming viaBufferFulllikepii.5. Testing & acceptance
Extend the e2e mock service with mock endpoints (Lakera
/v2/guard, Presidio/analyze+/anonymize, OpenAI/v1/moderations); point the DP at them via per-kind endpoint override. Real chain end-to-end; mock the external guardrail service only.Acceptance criteria:
enforcement_mode=monitor→ 200 + monitor observation recordedaction=block→ 422action=redact→ the request the mock upstream receives is anonymized (assert on the body the upstream saw)fail_openhonored on mock 5xx for the remote-API kinds (all three)6. Docs
api7/docsdocs/ai-gateway/traffic-controls/guardrails/: one page per kind (config fields, action semantics, fail-open, monitor-first guidance), wired intosidebars.ai-gateway.js. Paired PR, not in this repo.Estimate
DP ~1d each = 3d (Presidio closer to 2d with operators + output path), CP 1d, docs 0.5d.