Skip to content
102 changes: 102 additions & 0 deletions docs/my-website/docs/proxy/guardrails/noma_security.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,108 @@ import TabItem from '@theme/TabItem';

Use [Noma Security](https://noma.security/) to protect your LLM applications with comprehensive AI content moderation and safety guardrails.

:::warning Deprecated: `guardrail: noma` (Legacy)
`guardrail: noma` is deprecated and users should migrate to `guardrail: noma_v2`.
The legacy `guardrail: noma` API will no longer be supported after March 31, 2026.

For easier migration of existing integrations, keep `guardrail: noma` and set `use_v2: true`.
With `use_v2: true`, requests route to `noma_v2`; `monitor_mode` and `block_failures` still apply, while `anonymize_input` is ignored.
:::

## Noma v2 guardrails (Recommended)

### Quick Start

```yaml showLineNumbers title="litellm config.yaml"
guardrails:
- guardrail_name: "noma-v2-guard"
litellm_params:
guardrail: noma_v2
mode: "pre_call"
api_key: os.environ/NOMA_API_KEY
api_base: os.environ/NOMA_API_BASE
```

If you want to migrate gradually without changing guardrail names yet:

```yaml showLineNumbers title="litellm config.yaml"
guardrails:
- guardrail_name: "noma-guard"
litellm_params:
guardrail: noma
use_v2: true
mode: "pre_call"
api_key: os.environ/NOMA_API_KEY
api_base: os.environ/NOMA_API_BASE
```

### Supported Params

- **`guardrail`**: Use `noma_v2` (recommended), or `noma` with `use_v2: true` for migration
- **`mode`**: `pre_call`, `post_call`, `during_call`, `pre_mcp_call`, `during_mcp_call`
- **`api_key`**: Noma API key (required for Noma SaaS, optional for self-managed deployments)
- **`api_base`**: Noma API base URL (defaults to `https://api.noma.security/`)
- **`application_id`**: Application identifier. If omitted, v2 checks dynamic `extra_body.application_id`, then configured/env `application_id`; otherwise it is omitted.
- **`monitor_mode`**: If `true`, runs in monitor-only mode without blocking (defaults to `false`)
- **`block_failures`**: If `true`, fail-closed on guardrail technical failures (defaults to `true`)
- **`use_v2`**: Migration toggle when `guardrail: noma` is used

### Environment Variables

```shell
export NOMA_API_KEY="your-api-key-here"
export NOMA_API_BASE="https://api.noma.security/" # Optional
export NOMA_APPLICATION_ID="my-app" # Optional
export NOMA_MONITOR_MODE="false" # Optional
export NOMA_BLOCK_FAILURES="true" # Optional
```

### Multiple Guardrails

Apply different v2 configurations for input and output:

```yaml showLineNumbers title="litellm config.yaml"
guardrails:
- guardrail_name: "noma-v2-input"
litellm_params:
guardrail: noma_v2
mode: "pre_call"
api_key: os.environ/NOMA_API_KEY

- guardrail_name: "noma-v2-output"
litellm_params:
guardrail: noma_v2
mode: "post_call"
api_key: os.environ/NOMA_API_KEY
```

### Pass Additional Parameters

This is supported in v2 via `extra_body`.
Currently, `noma_v2` consumes dynamic `application_id`.

```shell showLineNumbers title="Curl Request"
curl 'http://0.0.0.0:4000/v1/chat/completions' \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Hello, how are you?"
}
],
"guardrails": {
"noma-v2-guard": {
"extra_body": {
"application_id": "my-specific-app-id"
}
}
}
}'
```
## Noma guardrails (Legacy)

## Quick Start
Comment on lines +109 to 111
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken heading hierarchy for legacy section

The new ## Noma guardrails (Legacy) header on line 16 is immediately followed by the pre-existing ## Quick Start on line 18. Since both are ## headings, the rendered docs sidebar will show "Quick Start" as a sibling of "Noma guardrails (Legacy)" rather than a child. All legacy subsections (Quick Start, Supported Params, Environment Variables, etc.) should be demoted by one level so they nest under the legacy header.

Suggested change
## Noma guardrails (Legacy)
## Quick Start
## Noma guardrails (Legacy)
### Quick Start


### 1. Define Guardrails on your LiteLLM config.yaml
Expand Down
29 changes: 29 additions & 0 deletions litellm/proxy/guardrails/guardrail_hooks/noma/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@
from litellm.types.guardrails import SupportedGuardrailIntegrations

from .noma import NomaGuardrail
from .noma_v2 import NomaV2Guardrail

if TYPE_CHECKING:
from litellm.types.guardrails import Guardrail, LitellmParams


def initialize_guardrail(litellm_params: "LitellmParams", guardrail: "Guardrail"):
use_v2 = getattr(litellm_params, "use_v2", False)
if isinstance(use_v2, str):
use_v2 = use_v2.lower() == "true"
if use_v2:
return initialize_guardrail_v2(
litellm_params=litellm_params, guardrail=guardrail
)

import litellm

_noma_callback = NomaGuardrail(
Expand All @@ -27,11 +36,31 @@ def initialize_guardrail(litellm_params: "LitellmParams", guardrail: "Guardrail"
return _noma_callback


def initialize_guardrail_v2(litellm_params: "LitellmParams", guardrail: "Guardrail"):
import litellm

_noma_v2_callback = NomaV2Guardrail(
guardrail_name=guardrail.get("guardrail_name", ""),
api_key=litellm_params.api_key,
api_base=litellm_params.api_base,
application_id=litellm_params.application_id,
monitor_mode=litellm_params.monitor_mode,
block_failures=litellm_params.block_failures,
event_hook=litellm_params.mode,
default_on=litellm_params.default_on,
)
litellm.logging_callback_manager.add_litellm_callback(_noma_v2_callback)

return _noma_v2_callback


guardrail_initializer_registry = {
SupportedGuardrailIntegrations.NOMA.value: initialize_guardrail,
SupportedGuardrailIntegrations.NOMA_V2.value: initialize_guardrail_v2,
}


guardrail_class_registry = {
SupportedGuardrailIntegrations.NOMA.value: NomaGuardrail,
SupportedGuardrailIntegrations.NOMA_V2.value: NomaV2Guardrail,
}
13 changes: 13 additions & 0 deletions litellm/proxy/guardrails/guardrail_hooks/noma/noma.py
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why change the name, instead of just rewriting the noma.py?

this adds additional code to maintain

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import asyncio
import json
import os
import warnings
from datetime import datetime
from typing import (
TYPE_CHECKING,
Expand Down Expand Up @@ -58,6 +59,7 @@
# Type aliases
MessageRole = Literal["user", "assistant"]
LLMResponse = Union[Any, ModelResponse, EmbeddingResponse, ImageResponse]
_LEGACY_NOMA_DEPRECATION_WARNED = False

if TYPE_CHECKING:
from litellm.types.proxy.guardrails.guardrail_hooks.base import GuardrailConfigModel
Expand Down Expand Up @@ -112,6 +114,17 @@ def __init__(
anonymize_input: Optional[bool] = None,
**kwargs,
):
global _LEGACY_NOMA_DEPRECATION_WARNED
if not _LEGACY_NOMA_DEPRECATION_WARNED:
warnings.warn(
"Guardrail provider 'noma' is deprecated. "
"Please migrate to 'noma_v2'. "
"The legacy 'noma' API will no longer be supported after March 31, 2026.",
DeprecationWarning,
stacklevel=2,
)
_LEGACY_NOMA_DEPRECATION_WARNED = True

self.async_handler = get_async_httpx_client(
llm_provider=httpxSpecialProvider.GuardrailCallback
)
Expand Down
Loading
Loading