Shadow → Enforce Rollout
Safely roll out NjiraAI from observe-only to active enforcement.
Overview
NjiraAI supports a shadow mode that logs verdicts without blocking traffic. This lets you validate policies against real traffic before turning on enforcement.
Recommended rollout: Shadow (observe) → Review traces → Enable enforcement → Monitor
Step 1 — Start in shadow mode
Set the environment variable before starting the Gateway:
# In your .env or docker-compose override:
SHADOW_MODE=true
FAIL_CLOSED=true
Or via docker-compose.yml:
services:
gateway:
environment:
- SHADOW_MODE=true
- FAIL_CLOSED=true
Restart the Gateway:
make up-all
What happens in shadow mode
- All requests are forwarded regardless of verdict
- Verdicts are logged to the audit trail
- Response headers include shadow verdict info:
X-Njira-Shadow-Verdict: BLOCKX-Njira-Shadow-Reason: PII_DETECTED
Step 2 — Review traces
Open the NjiraAI Console at http://localhost:3100/traces to review:
- Which requests would have been blocked
- Reason codes and confidence scores
- Policy pack and rule that triggered
# Or query via API:
curl -s http://localhost:8081/v1/traces \
-H "Authorization: Bearer nj_live_dev_key_12345" | jq '.traces[] | {action, reason_code, tool_name}'
Expected output
{
"action": "BLOCK",
"reason_code": "PII_DETECTED",
"tool_name": "chat_interface"
}
Look for:
- False positives — safe requests marked BLOCK (tune policies)
- Missed risks — unsafe requests marked ALLOW (add rules)
Step 3 — Enable enforcement
Once satisfied with shadow results, switch to enforce mode:
# In your .env or docker-compose override:
SHADOW_MODE=false
FAIL_CLOSED=true # recommended: deny when Intelligence is unavailable
Restart the Gateway:
make up-all
Verify enforcement is active
# This should now return 403 (not 200 with shadow headers):
curl -s -w "\nHTTP %{http_code}\n" \
http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer nj_live_dev_key_12345" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o","messages":[{"role":"user","content":"My SSN is 123-45-6789"}]}'
Expected output
{"blocked":true,"reason":"SSN pattern (XXX-XX-XXXX) detected","reason_code":"PII_DETECTED",...}
HTTP 403
Step 4 — Rollback (if needed)
To revert to shadow mode:
SHADOW_MODE=true
Restart the Gateway. No data is lost — all previous traces remain in the audit log.
Configuration reference
| Variable | Values | Default | Description |
|---|---|---|---|
SHADOW_MODE |
true/false |
false |
Log verdicts without enforcing |
FAIL_CLOSED |
true/false |
true |
Deny when Intelligence/Redis unavailable |
Success criteria
| Check | Expected |
|---|---|
Shadow mode: PII request returns 200 with X-Njira-Shadow-Verdict: BLOCK |
✅ |
| Enforce mode: PII request returns 403 | ✅ |
Traces appear in Console at /traces |
✅ |
| Rollback to shadow mode restores 200 for all requests | ✅ |
Next steps
- Policy packs — customize what gets blocked
- Troubleshooting — common issues