> ## Documentation Index
> Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Guardrails Service

> Deploy the optional ML-powered guardrails service for Presidio PII detection and ML-based prompt injection scanning.

The Guardrails Service is an optional Python microservice that provides ML-powered security scanning. When deployed alongside Declaw, it replaces the built-in regex scanners with production-grade models:

* **PII detection**: Microsoft Presidio with Named Entity Recognition (NER) for unstructured PII (person names, locations, passport numbers, driver's licenses)
* **Prompt injection detection**: an ML classifier plus an LLM judge that score content for injection likelihood

If the Guardrails Service is unreachable, the security proxy automatically falls back to the built-in regex scanners. No configuration change is required for this fallback.

## Architecture

```mermaid theme={null}
flowchart LR
    SecProxy["Security Proxy\n(host netns)"] -->|"HTTP POST /api/v1/scan"| GS["Guardrails Service\n:8000"]
    GS --> Presidio["Presidio\nPII NER"]
    GS --> PI["Injection classifier\n+ LLM judge"]
    GS -->|"ScanResponse JSON"| SecProxy
    SecProxy -->|"unreachable"| Fallback["Built-in regex\nfallback"]
```

The security proxy sends scan requests to the Guardrails Service HTTP API at `GUARDRAILS_URL/api/v1/scan`. The service runs scanners in parallel and returns results within the 10-second proxy timeout.

## Deploy on GCP

```bash theme={null}
cd guardrails-service/iac/gcp
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars: set project_id, region
../scripts/deploy-gcp.sh
```

This provisions a GCP VM with the Guardrails Service installed and started via systemd. The service listens on port 8000.

## Connect to Declaw

Set the `GUARDRAILS_URL` environment variable before running the Declaw deploy script, and it will be detected automatically:

```bash theme={null}
export GUARDRAILS_URL=http://<guardrails-vm-ip>:8000
./scripts/deploy-gcp.sh
```

Or set it manually on the Declaw VM after deployment:

```bash theme={null}
# On the Declaw VM
echo "GUARDRAILS_URL=http://<guardrails-vm-ip>:8000" >> /etc/declaw/env
systemctl restart declaw-orchestrator
```

## Manual connection

In the SDK, set `GUARDRAILS_URL` in the environment before creating sandboxes:

```bash theme={null}
export GUARDRAILS_URL=http://<guardrails-vm-ip>:8000
export DECLAW_API_KEY=your-key
export DECLAW_DOMAIN=your-domain:8080
```

The orchestrator reads `GUARDRAILS_URL` at startup and passes it to each sandbox's security proxy.

## Guardrails Service API

The service exposes one scan endpoint and a health check:

```
POST /api/v1/scan
Content-Type: application/json

{
  "prompts": ["User input to scan..."],
  "scanners": [
    { "scanner_type": "pii_scanner" },
    { "scanner_type": "prompt_injection_scanner" }
  ]
}
```

Response:

```json theme={null}
{
  "scanner_responses": [
    {
      "scanner_type": "pii_scanner",
      "pii_scanner_response": {
        "entity_details": [
          { "entity_type": "PERSON", "entity_value": "John Doe", "masked_value": "<PERSON>", "confidence_score": 0.95, "start": 0, "end": 8 }
        ],
        "sanitized_response": "<PERSON> lives at 123 Main St"
      }
    },
    {
      "scanner_type": "prompt_injection_scanner",
      "prompt_injection_scanner_response": {
        "is_injection": false,
        "confidence_score": 0.03,
        "scanned_text": "User input to scan..."
      }
    }
  ]
}
```

Each scanner entry may include per-request overrides (e.g. `"pii_scanner": { "confidence_threshold": 0.8, "entities": ["EMAIL_ADDRESS"] }`) alongside `scanner_type`.

## Supported scanners

| Scanner type               | Model/Library             | Detects                                                                                                                                     |
| -------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `pii_scanner`              | Microsoft Presidio        | Configured entities: PERSON, LOCATION, EMAIL\_ADDRESS, PHONE\_NUMBER, CREDIT\_CARD, US\_SSN, US\_PASSPORT, US\_DRIVER\_LICENSE, IP\_ADDRESS |
| `prompt_injection_scanner` | ML classifier + LLM judge | Prompt injection likelihood score 0.0–1.0                                                                                                   |
| `code_security_scanner`    | Language classifier       | Identifies whether an outbound body is source code (and the language); off by default                                                       |
| `toxicity_scanner`         | ML toxicity model         | Toxic / abusive content score 0.0–1.0                                                                                                       |
| `invisible_text_scanner`   | Pattern-based             | Zero-width and other invisible Unicode characters                                                                                           |

## Invisible text scanner

The Guardrails Service includes a scanner that detects invisible Unicode characters used in prompt injection attacks:

```
\u200b  Zero-width space
\u200c  Zero-width non-joiner
\u200d  Zero-width joiner
\u2060  Word joiner
\ufeff  Byte order mark
\u00ad  Soft hyphen
```

These characters can be embedded in text that appears clean to the human eye but contains hidden instructions to the LLM.

## Model loading and caching

Models are downloaded once at service startup and cached on disk. The orchestrator is designed to load models in a non-blocking background thread so the service accepts requests before all models are ready, with a degraded mode that skips unavailable scanners.

Model files are stored at `/opt/guardrails/models/` on the service VM.

## Local development

Run the Guardrails Service locally with Docker:

```bash theme={null}
cd guardrails-service
docker build -t guardrails-service .
docker run -p 8000:8000 guardrails-service
```

Or with the provided Docker Compose configuration:

```bash theme={null}
cd guardrails-service
docker compose up -d
```

Then point Declaw at it:

```bash theme={null}
export GUARDRAILS_URL=http://localhost:8000
```

## Fallback behavior

If `GUARDRAILS_URL` is set but the service is unreachable:

1. The security proxy logs a warning
2. PII detection falls back to the built-in regex scanner (SSN, credit card, email, phone patterns)
3. Injection detection falls back to the built-in pattern library
4. No error is surfaced to the agent workload

The fallback is automatic and requires no code changes. The proxy checks liveness on each scan request with a 10-second timeout.

<Warning>
  The built-in regex fallback does not support unstructured PII types like `person_name`. If your security policy depends on NER-based detection, monitor the Guardrails Service availability and alert on fallback events in the audit log.
</Warning>
