docs: add a Presidio sample for AISIX AI Gateway (#2257)

This commit is contained in:
Yilia Lin
2026-09-16 09:31:25 +00:00
committed by GitHub
parent 2b57747628
commit f251c513e8
3 changed files with 193 additions and 0 deletions
+191
View File
@@ -0,0 +1,191 @@
# Protect LLM requests with Presidio and AISIX AI Gateway
[AISIX](https://github.com/api7/aisix) can call a self-hosted Presidio
Analyzer and Anonymizer as an input guardrail before forwarding a request to
an LLM provider. This sample configures two outcomes:
- email addresses are replaced with an entity placeholder;
- US Social Security numbers are blocked before the provider is called.
```text
Application --> AISIX --> LLM provider
|
+--> Presidio Analyzer --> Presidio Anonymizer
```
## Prerequisites
- Docker
- an OpenAI API key, or an OpenAI-compatible endpoint and matching AISIX
provider configuration
- `curl`
The commands below use AISIX 1.2.0 and Presidio 2.2.364.
## Start Presidio
Create a private Docker network and run both Presidio services:
```bash
docker network create aisix-presidio
docker run -d --name presidio-analyzer --network aisix-presidio \
-p 127.0.0.1:5002:3000 \
ghcr.io/data-privacy-stack/presidio-analyzer:2.2.364
docker run -d --name presidio-anonymizer --network aisix-presidio \
-p 127.0.0.1:5001:3000 \
ghcr.io/data-privacy-stack/presidio-anonymizer:2.2.364
```
These services do not authenticate callers. Keep them on a private network in
production instead of publishing their ports.
Wait for both services to report healthy before continuing:
```bash
until curl -fsS http://127.0.0.1:5002/health >/dev/null; do sleep 5; done
until curl -fsS http://127.0.0.1:5001/health >/dev/null; do sleep 2; done
```
Confirm that the Analyzer detects an email address:
```bash
curl -sS -X POST http://127.0.0.1:5002/analyze \
-H 'Content-Type: application/json' \
-d '{"text":"Contact alice@example.com","language":"en"}'
```
The response includes an `EMAIL_ADDRESS` result with its character offsets
and confidence score.
## Configure AISIX
Create `config.yaml`:
```yaml
resources_file: /etc/aisix/resources.yaml
proxy:
addr: "0.0.0.0:3000"
admin:
enabled: false
```
Create `resources.yaml`:
```yaml
_format_version: "1"
provider_keys:
- display_name: openai-main
provider: openai
api_key: ${OPENAI_API_KEY}
models:
- display_name: presidio-demo
provider: openai
model_name: gpt-4o-mini
provider_key: openai-main
api_keys:
- display_name: local-demo
key_env: CALLER_API_KEY
allowed_models: ["presidio-demo"]
guardrails:
- name: presidio-pii-policy
enabled: true
hook_point: input
enforcement_mode: block
fail_open: false
kind: presidio
analyzer_url: http://presidio-analyzer:3000
anonymizer_url: http://presidio-anonymizer:3000
entities:
- type: EMAIL_ADDRESS
action: mask
- type: US_SSN
action: block
default_action: mask
operator: replace
language: en
guardrail_attachments:
- guardrail_id: presidio-pii-policy
scope_type: env
priority: 100
```
Export credentials and start the gateway on the same Docker network:
```bash
export OPENAI_API_KEY="YOUR_PROVIDER_KEY"
export CALLER_API_KEY="sk-local-presidio-demo"
docker run -d --name aisix-presidio-gateway \
--platform linux/amd64 \
--network aisix-presidio \
-v "$(pwd)/config.yaml:/etc/aisix/config.yaml:ro" \
-v "$(pwd)/resources.yaml:/etc/aisix/resources.yaml:ro" \
-e OPENAI_API_KEY -e CALLER_API_KEY \
-p 127.0.0.1:3000:3000 \
ghcr.io/api7/aisix:1.2.0
```
The guardrail must have an attachment. A configured guardrail with no matching
attachment does not inspect traffic.
## Verify masking and blocking
Send a request containing an email address:
```bash
curl -sS -X POST http://127.0.0.1:3000/v1/chat/completions \
-H "Authorization: Bearer ${CALLER_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"model": "presidio-demo",
"messages": [
{"role": "user", "content": "Contact alice@example.com about the order"}
]
}'
```
AISIX asks the Analyzer to locate the email and the Anonymizer to replace it.
The provider receives `Contact <EMAIL_ADDRESS> about the order`; the model's
response remains provider-dependent.
Now send a value configured with the `block` action:
```bash
curl -sSi -X POST http://127.0.0.1:3000/v1/chat/completions \
-H "Authorization: Bearer ${CALLER_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"model": "presidio-demo",
"messages": [
{"role": "user", "content": "My SSN is 987-65-4321"}
]
}'
```
The request returns `422 Unprocessable Entity` with a `content_filter` error,
and AISIX does not call the model provider.
This example is fail-closed. If the Analyzer is unavailable, AISIX returns a
`422` `guardrail_unavailable` error instead of forwarding uninspected content.
Set `fail_open: true` only when availability is more important than preventing
unscreened text from reaching the provider.
## Clean up
```bash
docker rm -f aisix-presidio-gateway presidio-analyzer presidio-anonymizer
docker network rm aisix-presidio
```
For entity selection, anonymization operators, output guardrails, streaming
behavior, and deployment guidance, see the
[AISIX Presidio guardrail documentation](https://docs.api7.ai/ai-gateway/traffic-controls/guardrails/presidio).
+1
View File
@@ -29,6 +29,7 @@
| Usage | Text | Python file | [Synthetic data generation with OpenAI](python/synth_data_with_openai.ipynb)|
| Usage | Text | Python file | [Keeping some entities from being anonymized](python/keep_entities.ipynb)|
| Usage | Text | LiteLLM Proxy | [PII Masking LLM calls across Anthropic/Gemini/Bedrock/Azure, etc.](docker/litellm.md)|
| Usage | Text | AISIX AI Gateway | [Protect LLM requests with Presidio and AISIX AI Gateway](docker/aisix.md)|
| Usage | Text | Python Notebook | [YAML based no-code configuration](python/no_code_config.ipynb) |
| Usage | Text | Python file | [Using GLiNER within Presidio](python/gliner.md) |
| Usage | | REST API (postman) | [Presidio as a REST endpoint](docker/index.md)|
+1
View File
@@ -127,6 +127,7 @@ nav:
- Add Presidio as an HTTP service to your Azure Data Factory: samples/deployments/data-factory/presidio-data-factory-template-gallery-http.md
- Add Presidio on Databricks to your Azure Data Factory: samples/deployments/data-factory/presidio-data-factory-template-gallery-databricks.md
- PII Masking LLM calls using LiteLLM proxy: samples/docker/litellm.md
- Protect LLM requests with Presidio and AISIX AI Gateway: samples/docker/aisix.md
- Demo app:
- Create a simple demo app using Streamlit: samples/python/streamlit/index.md
not_in_nav : |