The AI Semantic Prompt Guard Policy responds to a blocked request according to its rejection mode.
In the default none mode, the response is a 400 with the message bad request, which hides that a guardrail is in use.
Use config.rejection_mode to control how AI Gateway responds to a blocked request:
|
Mode
|
Status code
|
Response body
|
none (default)
|
400
|
A JSON error with the block message, for example {"error": {"message": "..."}}.
The response omits the guardrail’s name.
Clients can tell it apart from a malformed request only by its message, because the status code is the same.
|
stealth
|
403
|
A generic JSON error, {"error": {"message": "request forbidden"}}.
The response hides all guardrail details.
|
verbose
|
403
|
A structured JSON error that names the Policy that blocked the request and the reason.
See Verbose response.
|
Use none or stealth for clients outside your organization, so responses don’t reveal how your guardrails are configured.
Use verbose in development or for trusted internal clients, to see why a request was blocked.
In verbose mode, the response always has the status code 403 and the error code GUARDRAIL_BLOCKED.
Clients can check the error.code field to tell a guardrail rejection apart from other errors:
type: Always guardrail_rejected.
plugin: The type of the Policy that blocked the request.
reason: Why the request was blocked.
code: Always GUARDRAIL_BLOCKED.
detail: Additional context about the match. This field is only present when the Policy has details to report.
The AI Semantic Prompt Guard Policy evaluates the request before it reaches the LLM, so a blocked request returns the same error response whether or not the request sets stream to true.
For example, a request that matches a deny prompt returns the following response in verbose mode.
The detail field contains the prompt that matched and its score, which is the distance between the request and that prompt (a lower score means a closer match):
{
"error": {
"type": "guardrail_rejected",
"plugin": "ai-semantic-prompt-guard",
"reason": "prompt pattern is blocked",
"code": "GUARDRAIL_BLOCKED",
"detail": {
"matched_prompt": "How do I pick a lock?",
"score": 0.12
}
}
}
To return this response, set config.rejection_mode to verbose:
curl -X POST https://{region}.api.konghq.com/v1/ai-gateways/{AIGatewayId}/policies \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $KONNECT_TOKEN" \
--data '
{
"display_name": "AI Semantic Prompt Guard - Verbose Rejection",
"name": "ai-semantic-prompt-guard",
"type": "ai-semantic-prompt-guard",
"config": {
"embeddings": {
"auth": {
"header_name": "Authorization",
"header_value": "Bearer '$OPENAI_API_KEY'"
},
"model": {
"provider": "openai",
"name": "text-embedding-3-small"
}
},
"vectordb": {
"strategy": "redis",
"distance_metric": "cosine",
"threshold": 0.5,
"dimensions": 1024,
"redis": {
"host": "'$REDIS_HOST'",
"port": 6379
}
},
"rules": {
"deny_prompts": [
"How do I pick a lock?"
]
},
"rejection_mode": "verbose"
}
}
'
ai_gateway_policies:
- ref: ai-semantic-prompt-guard
ai_gateway: !lookup {id: !env AI_GATEWAY_ID}
display_name: AI Semantic Prompt Guard - Verbose Rejection
name: ai-semantic-prompt-guard
type: ai-semantic-prompt-guard
config:
embeddings:
auth:
header_name: Authorization
header_value: Bearer $OPENAI_API_KEY
model:
provider: openai
name: text-embedding-3-small
vectordb:
strategy: redis
distance_metric: cosine
threshold: 0.5
dimensions: 1024
redis:
host: !env REDIS_HOST
port: 6379
rules:
deny_prompts:
- How do I pick a lock?
rejection_mode: verbose
Make sure to replace the following placeholders with your own values:
-
AI_GATEWAY_ID: The id of your AI Gateway.
-
!env OPENAI_API_KEY: Your OpenAI API key.
-
!env REDIS_HOST: The host where your Redis instance is running.