Skip to main content

External Moderation

The external-moderation policy sends content to a third-party moderation provider and blocks when the provider flags the content. The gateway currently supports nine providers:

  • openai-moderation
  • azure-content-safety
  • bedrock-apply-guardrail
  • embedding-endpoint
  • webhook
  • presidio
  • guardrails-ai
  • dynamo-ai
  • lakera

By default the policy runs in the input phase. You can attach it to a response stage with conditional chain metadata when needed.

Configuration

pack:
name: external-moderation-example
version: 1.0.0
enabled: true

policies:
chain:
- external-moderation

policy:
external-moderation:
provider: openai-moderation
secret_key_ref:
env: KEEPTRUSTS_OPENAI_API_KEY
categories:
- violence
- self-harm
threshold: 0.5
timeout_ms: 3000
fail_closed: true

Fields

PropertyTypeDefaultDescription
providerenumwebhookOne of the nine provider values listed above.
secret_key_refobjectSecret reference in object form, typically secret_key_ref.env.
endpointstringProvider endpoint URL when the provider needs one.
categoriesstring[][]Optional provider-specific category filters.
thresholdnumber0.5Score threshold used by the provider adapter.
timeout_msinteger3000Provider timeout in milliseconds.
fail_closedbooleanfalseBlock on provider failure instead of allowing through.
webhook_headersobject{}Extra headers for provider: webhook.
aws_regionstringBedrock region.
aws_access_key_envstringOptional Bedrock access-key env var name.
aws_secret_key_envstringOptional Bedrock secret-key env var name.
aws_session_token_envstringOptional Bedrock session-token env var name.
guardrail_idstringBedrock guardrail identifier.
guardrail_versionstringBedrock guardrail version.
embedding_modelstringModel name for provider: embedding-endpoint.
reference_textsstring[][]Reference texts for provider: embedding-endpoint.
presidio_languagestringen at runtime when omittedOptional language hint for provider: presidio.
presidio_entitiesstring[][]Optional Presidio entity filter list.
guard_namestringGuard name for provider: guardrails-ai.
policy_idstringPolicy identifier for provider: dynamo-ai.
lakera_categoriesstring[][]Optional Lakera category filters.

Provider notes

ProviderWhat you must supply
openai-moderationsecret_key_ref.env; endpoint is optional
azure-content-safetysecret_key_ref.env and endpoint
bedrock-apply-guardrailaws_region, guardrail_id, guardrail_version, and credentials if your runtime does not already have them
embedding-endpointendpoint and reference_texts; optionally embedding_model and secret_key_ref
webhookendpoint; optionally secret_key_ref and webhook_headers
presidioendpoint; presidio_language is optional because the adapter defaults to en
guardrails-aiendpoint and guard_name
dynamo-aiendpoint and policy_id
lakerasecret_key_ref.env; endpoint is optional

Webhook verdict mapping

Webhook providers can return either:

  • flagged: true|false
  • or a textual verdict / action

Keeptrusts treats these webhook verdicts as blocking: deny, block, blocked, reject, rejected, flagged, and review.

It treats these as allow: allow, none, or flagged: false.

{
"verdict": "deny",
"reason": "prompt injection candidate",
"scores": {
"prompt_injection": 0.97
}
}

How It Works

  1. The gateway joins the current message content.
  2. It dispatches the content to the selected provider adapter.
  3. The adapter normalizes the provider response into flagged, scores, and reason.
  4. If flagged is true, the policy blocks with reason_code: external-moderation.flagged.
  5. If the provider errors or times out, fail_closed decides whether the request is blocked or allowed.

Best Practices

  • Use secret_key_ref.env instead of inline secrets in YAML.
  • Start with a single provider, then layer providers only if you need the extra operational complexity.
  • Use fail_closed: true only after you understand provider reliability and timeout behavior.
  • Scope categories only when the provider adapter supports the category names you want.

Next steps