Contact Us 1-800-596-4880

A2A v1 Azure Content Guardrails Policy

Policy Name

A2A v1 Azure Content Guardrails Policy

Summary

Evaluates A2A v1 agent messages against Azure AI Content Safety for harmful content, jailbreak attempts, hallucinations, and copyrighted material

Category

A2A

First Omni Gateway version available

v1.13.0

Release Notes

A2A v1 Azure Content Guardrails Policy

Returned Status Codes

403 - Forbidden: Content violates Azure Content Safety policies

503 - Service Unavailable: Azure API call failed (only when fail-open is disabled)

Summary

The A2A v1 Azure Content Guardrails policy provides comprehensive content moderation for A2A v1.0 agent traffic by evaluating requests and responses against the Azure AI Content Safety service. The policy integrates with Azure AI Content Safety to enforce content safety policies including:

  • Content filters: Detects and blocks harmful content across four categories (Hate, SelfHarm, Sexual, and Violence) with configurable severity thresholds (0, 2, 4, 6).

  • Prompt Shield: Detects jailbreak attempts and indirect prompt-injection attacks using Azure’s advanced detection capabilities.

  • Blocklists: Blocks content matching Azure-managed custom blocklists you define in Azure Content Safety Studio.

  • Groundedness Detection: Evaluates whether agent responses are grounded in provided reference text (hallucination detection for RAG applications).

  • Protected Material Detection: Detects known copyrighted text in agent responses.

The policy operates across three A2A v1.0 transport protocols:

  • JSON-RPC — Moderates SendMessage and SendStreamingMessage on both request and response

  • HTTP+JSON — Moderates POST /message:send and streaming responses

  • gRPC — Pass-through without moderation in v1.0

The policy operates in independent phases:

  • Request phase: Moderates user messages before they reach the upstream agent, preventing harmful or inappropriate messages from being processed.

  • Response phase: Moderates agent responses before they reach the client, ensuring outputs comply with safety policies.

  • Streaming response phase: Best-effort moderation of streaming responses by buffering frame bodies and scanning on configurable thresholds.

When content violates safety policies, the request is rejected with a 403 error code and never reaches the agent (request phase) or the client receives a 403 instead of the agent response (response phase).

This policy is designed for A2A v1.0 traffic only. gRPC traffic passes through without moderation in this version.

Before You Begin

Before configuring this policy, you need:

  1. Azure Account with access to Azure AI Content Safety

  2. Azure Content Safety Resource created in the Azure Portal

  3. Subscription Key from the Azure Portal (Keys and Endpoint section)

  4. Resource Endpoint URL from the Azure Portal configured as a Flex service

Configuring Policy Parameters

Omni Gateway Local Mode

The A2A v1 Azure Content Guardrails policy isn’t supported in Local Mode.

Managed Omni Gateway and Omni Gateway Connected Mode

When you apply the policy from the UI, the following parameters are displayed:

Basic Configuration

Element Required Description

Azure Content Safety Endpoint

Yes

Azure Content Safety endpoint base URL configured as a Flex service, for example, https://<resource>.cognitiveservices.azure.com. The policy appends endpoint paths at runtime.

Azure API Key

Yes

Azure Content Safety subscription key. The key is passed in the Ocp-Apim-Subscription-Key header and marked as sensitive.

Moderate Request

No

When enabled, evaluates the user message against Azure Content Safety before forwarding to the upstream agent. Rejected messages never reach the agent. Default: true.

Moderate Response

No

When enabled, evaluates the agent response against Azure Content Safety before returning to the client. Rejected responses return 403 error code. Default: true.

Moderate Streaming Response

No

When enabled, evaluates streaming responses by buffering frame bodies and scanning on configurable thresholds. When disabled, streaming responses pass through unchanged. Default: true.

Default Severity Threshold

No

Severity threshold applied to all four harm categories (Hate, SelfHarm, Sexual, Violence). Content with severity at or above this value is rejected. Supported values are 0, 2 (default), 4, and 6.

For details, see Severity Thresholds.

Advanced Configuration

Element Required Description

API Version

No

Azure Content Safety API version used for all endpoint calls. Default: 2024-09-01.

To enable Groundedness Detection, override this to a supported preview version, for example, 2024-09-15-preview.

Enable Prompt Shield

No

When enabled, calls text:shieldPrompt alongside text:analyze on the request to detect jailbreak attempts and indirect prompt-injection attacks. Default: true.

Hate Severity Threshold

No

Per-category override for the Hate harm category. Leave as default to inherit Default Severity Threshold. See Severity Thresholds for supported values.

SelfHarm Severity Threshold

No

Per-category override for the SelfHarm harm category. Leave as default to inherit Default Severity Threshold. See Severity Thresholds for supported values.

Sexual Severity Threshold

No

Per-category override for the Sexual harm category. Leave as default to inherit Default Severity Threshold. See Severity Thresholds for supported values.

Violence Severity Threshold

No

Per-category override for the Violence harm category. Leave as default to inherit Default Severity Threshold. See Severity Thresholds for supported values.

Blocklist Names

No

Names of Azure-managed blocklists (created in Azure Content Safety Studio) to evaluate against the input text.

Enable Groundedness Detection

No

When enabled, calls text:detectGroundedness on the agent response to detect hallucinated statements. Requires Moderate Response enabled and Grounding Source Selector to be set. Only available in Azure regions that support the API, and only on preview API versions (for example, 2024-09-15-preview).

Grounding Source Selector

No

DataWeave expression resolving the grounding source text from the canonical A2A request body. Required when Groundedness Detection is enabled. For example: #[payload.params.message.metadata.context].

Enable Protected Material Detection

No

When enabled, calls text:detectProtectedMaterial on the agent response to detect known copyrighted text. Requires Moderate Response enabled.

API Timeout (ms)

No

Per-request timeout for each Azure Content Safety API call in milliseconds. Must be between 1000 and 30000. Default: 5000.

Fail Open

No

Determines behavior when the Azure API call fails or times out:

  • Disabled (default): Rejects the request with HTTP 503

  • Enabled: Allows traffic to proceed without moderation (fail-open mode)

Streaming Min Buffer Chars

No

Minimum number of characters accumulated across consecutive SSE frame bodies before the policy calls Azure for moderation. Must be between 1 and 8192. Default: 256.

Max Payload Bytes

No

Maximum request-or-response body size (in bytes) that the policy will send to Azure. Must be between 1024 and 10000. Default: 10000.

Sampling Rate Percent

No

Percentage of sessions to sample for moderation. 100 (default) moderates every request; 50 moderates half of sessions; 0 disables moderation. Sampling is deterministic per session.

Session Key Selector

No

DataWeave expression resolving the session identifier used by the sampler. Defaults to #[payload.params.message.contextId default payload.params.message.messageId]. Only used when Sampling Rate Percent is less than 100.

How This Policy Works

The A2A v1 Azure Content Guardrails policy integrates with Azure AI Content Safety to evaluate A2A v1.0 agent messages and responses against configurable safety policies.

Supported Methods

The policy runs only on these A2A v1.0 methods:

  • SendMessage

  • SendStreamingMessage

Read-only methods (GetTask, ListTasks, push-notification methods, SubscribeToTask, GetExtendedAgentCard) and the agent-card endpoint pass through untouched. Non-A2A traffic also passes through.

Transport Support

The policy moderates these transports:

  • JSON-RPC — Full moderation on request and response

  • HTTP+JSON — Full moderation on request and response

gRPC pass-through: Requests and responses with content-type: application/grpc or application/grpc+proto skip this policy entirely and pass through unchanged. If you need gRPC moderation, route gRPC clients through an HTTP+JSON transcoder.

Request and Response Moderation

The policy supports independent evaluation for request and response:

  1. Request Phase (when moderateRequest is enabled):

    1. The policy extracts the raw request body.

    2. The policy sends the body to Azure Content Safety APIs in parallel:

      • text:analyze — Evaluates harm categories (Hate, SelfHarm, Sexual, Violence) and checks blocklists

      • text:shieldPrompt — Detects jailbreak attempts and indirect injections (when enablePromptShield is enabled)

    3. If the request violates any policies, the policy blocks the request and returns a 403 error code to the client.

    4. If the request passes, the policy forwards the original request to the upstream agent.

  2. Response Phase — Unary (when moderateResponse is enabled):

    1. The policy intercepts the agent response.

    2. The policy sends the response body to Azure Content Safety APIs in parallel:

      • text:analyze — Evaluates harm categories and checks blocklists

      • text:detectGroundedness — Scores the response against the grounding source (when enabled and grounding source is available)

      • text:detectProtectedMaterial — Detects known copyrighted text (when enabled)

    3. If the response violates any policies, the policy returns a 403 error code to the client.

    4. If the response passes, the policy forwards the original response to the client.

  3. Response Phase — Streaming (when moderateStreamingResponse is enabled):

    1. The policy installs a stream handler that receives decoded SSE frames.

    2. Frame bodies are accumulated in a rolling buffer.

    3. When the buffer reaches streamingMinBufferChars, it drains to text:analyze (and optionally text:detectProtectedMaterial).

    4. If any rule fires, the policy replaces the current frame with a TaskStatusUpdateEvent { state: FAILED } and closes the stream.

    5. On clean decisions, frames forward unchanged and the buffer resets.

Whole-Payload Passing

The policy sends the raw JSON body (as bytes) to Azure as the text value, not extracted text parts. This approach provides:

  • Complete coverage — Adversarial content in any field reaches Azure

  • Simplicity — No per-schema drift when A2A adds new part kinds

  • Consistency — Works uniformly across JSON-RPC and HTTP+JSON

Azure limits inputs at ~10,000 characters. Larger payloads trigger the payload_too_large rule.

Groundedness Detection

Groundedness detection helps detect hallucinations by evaluating whether agent responses are grounded in the provided reference text. This is particularly useful for RAG (Retrieval-Augmented Generation) applications.

To enable groundedness detection:

  1. Enable groundedness detection in Advanced Configuration (enableGroundednessDetection: true).

  2. Configure the Grounding Source Selector to extract the reference text from the request body.

  3. Set the API Version to a preview version that supports the groundedness endpoint (for example, 2024-09-15-preview).

The grounding source selector is a DataWeave expression that extracts the reference text the agent response should be based on (typically documents or context provided in the request).

Example Configuration
advancedConfiguration:
  apiVersion: "2024-09-15-preview"
  enableGroundednessDetection: true
  groundingSourceSelector: "#[payload.params.message.metadata.context]"

Severity Thresholds

Azure AI Content Safety evaluates content across four harm categories and assigns a severity level to each:

  • 0 — Safe (no harmful content detected)

  • 2 — Low severity

  • 4 — Medium severity

  • 6 — High severity

The policy rejects content when the severity level is at or above the configured threshold:

Threshold Value Content Blocked

0

Any flagged content (severity > 0) is blocked. This is the strictest setting.

2

Content with low, medium, or high severity is blocked. This is the recommended default.

4

Content with medium or high severity is blocked. This allows low-severity content.

6

Only high-severity content is blocked. This is the most permissive setting.

You can configure a default threshold that applies to all categories, and optionally override the threshold for specific categories.

Response Headers

Every moderated response includes observability headers:

Header Values Description

x-flex-azure-guardrails-action

allow, reject, skip

Final moderation decision. reject indicates content violated one or more policies. skip indicates the session was sampled out.

x-flex-azure-guardrails-phase

request, response, response_stream

Which phase performed the moderation. Useful for understanding whether the request or response was blocked.

x-flex-azure-guardrails-reason

severity_hate, severity_self_harm, severity_sexual, severity_violence, blocklist, prompt_shield, groundedness, protected_material, payload_too_large, streaming_buffer_overflow, service_unavailable, sampled_out

Why the content was rejected or skipped. Multiple reasons are comma-separated if the content violated multiple policies.

Headers are not emitted on gRPC pass-through traffic.

Response on Reject

When the policy blocks content, it returns a transport-appropriate error response.

JSON-RPC Transport

HTTP 403 with a JSON-RPC 2.0 error response:

{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32600,
    "message": "Request blocked by Azure Content Safety: severity_violence",
    "data": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "domain": "a2a-protocol.org",
        "reason": "FORBIDDEN",
        "metadata": {
          "detail": "severity_violence"
        }
      }
    ]
  }
}

The error code -32600 maps to the A2A v1.0 FORBIDDEN reason code.

HTTP+JSON Transport

HTTP 403 with a Google RPC Status error response:

{
  "error": {
    "code": 403,
    "status": "PERMISSION_DENIED",
    "message": "Request blocked by Azure Content Safety: severity_violence",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "domain": "a2a-protocol.org",
        "reason": "FORBIDDEN",
        "metadata": {
          "detail": "severity_violence"
        }
      }
    ]
  }
}

Streaming Response

When a streaming response trips a rule mid-stream, the policy replaces the offending frame with a failed-status event and closes the stream:

event: status-update
data: {"jsonrpc":"2.0","id":"req-2","result":{"taskId":"task-abc","status":{"state":"FAILED","message":{"role":"agent","parts":[{"kind":"text","text":"Response blocked by Azure Content Safety: severity_hate,protected_material"}]}},"isFinal":true}}

No further frames are emitted.

Error Handling

The policy provides two error handling modes to control behavior when Azure API calls fail or timeout.

Fail Closed (Default)

When Fail Open is disabled, any Azure API error or timeout results in rejection with HTTP 503 and a transport-appropriate error response.

  • JSON-RPC Transport:

    {
      "jsonrpc": "2.0",
      "id": null,
      "error": {
        "code": -32603,
        "message": "Azure Content Safety service unavailable",
        "data": [
          {
            "@type": "type.googleapis.com/google.rpc.ErrorInfo",
            "domain": "a2a-protocol.org",
            "reason": "UNAVAILABLE",
            "metadata": {
              "detail": "service_unavailable"
            }
          }
        ]
      }
    }

    The error code -32603 maps to the A2A v1.0 UNAVAILABLE reason code.

  • HTTP+JSON Transport:

    {
      "error": {
        "code": 503,
        "status": "UNAVAILABLE",
        "message": "Azure Content Safety service unavailable",
        "details": [
          {
            "@type": "type.googleapis.com/google.rpc.ErrorInfo",
            "domain": "a2a-protocol.org",
            "reason": "UNAVAILABLE",
            "metadata": {
              "detail": "service_unavailable"
            }
          }
        ]
      }
    }

    The x-flex-azure-guardrails-reason header is set to service_unavailable for both transports.

Fail Open

When Fail Open is enabled, Azure API errors are logged but traffic continues without moderation. The x-flex-azure-guardrails-reason header is still set to service_unavailable for observability, allowing you to detect partial-coverage moderation in monitoring systems.

Example Configurations

The following examples demonstrate common configuration patterns for the A2A v1 Azure Content Guardrails policy.

Minimal Configuration — Request and Response Moderation

- policyRef:
    name: a2a-v1-azure-guardrails-policy-v1-0-impl
    namespace: default
  config:
    azureEndpoint: https://llmproxy-azure-cs.cognitiveservices.azure.com
    azureApiKey: "${AZURE_CONTENT_SAFETY_KEY}"

50% Sampling for Cost Control

- policyRef:
    name: a2a-v1-azure-guardrails-policy-v1-0-impl
    namespace: default
  config:
    azureEndpoint: https://llmproxy-azure-cs.cognitiveservices.azure.com
    azureApiKey: "${AZURE_CONTENT_SAFETY_KEY}"
    advancedConfiguration:
      samplingRatePercent: 50

Half the sessions (bucketed deterministically by contextId) are moderated; the other half pass through with the sampled_out observability header.

Strict Threshold with Blocklists

This example blocks any flagged content and applies custom blocklists:

- policyRef:
    name: a2a-v1-azure-guardrails-policy-v1-0-impl
    namespace: default
  config:
    azureEndpoint: https://llmproxy-azure-cs.cognitiveservices.azure.com
    azureApiKey: "${AZURE_CONTENT_SAFETY_KEY}"
    moderateStreamingResponse: false
    defaultSeverityThreshold: 0
    advancedConfiguration:
      blocklistNames:
        - competitor-names
        - internal-codenames

Per-Category Thresholds

This example applies different thresholds to different harm categories:

- policyRef:
    name: a2a-v1-azure-guardrails-policy-v1-0-impl
    namespace: default
  config:
    azureEndpoint: https://llmproxy-azure-cs.cognitiveservices.azure.com
    azureApiKey: "${AZURE_CONTENT_SAFETY_KEY}"
    defaultSeverityThreshold: 2
    advancedConfiguration:
      selfHarmSeverityThreshold: "4"    # Allow low-severity SelfHarm discussion
      violenceSeverityThreshold: "0"    # Block any flagged Violence

With Groundedness Detection (Hallucination Detection)

- policyRef:
    name: a2a-v1-azure-guardrails-policy-v1-0-impl
    namespace: default
  config:
    azureEndpoint: https://llmproxy-azure-cs-eastus.cognitiveservices.azure.com
    azureApiKey: "${AZURE_CONTENT_SAFETY_KEY}"
    defaultSeverityThreshold: 4
    advancedConfiguration:
      apiVersion: "2024-09-15-preview"
      enableGroundednessDetection: true
      groundingSourceSelector: "#[payload.params.message.metadata.context]"
      enableProtectedMaterialDetection: true
      blocklistNames:
        - my-blocklist
      apiTimeoutMs: 10000
      streamingMinBufferChars: 512
      failOpen: false
      samplingRatePercent: 25
      sessionKeySelector: "#[payload.params.message.metadata.userId]"