Appearance
ARMS Storage
Persist guardrail run data through the ARMS Backend API, with automatic routing to MongoDB, DynamoDB, or ClickHouse depending on your deployment.
Overview
Guardrails can buffer check results, tool authorization events, rate-limit events, and LLM generate metadata, then flush them to the ARMS Backend at the end of each run. The Backend writes to whichever database your ARMS deployment uses — you do not configure a database driver in guardrails YAML.
Key points:
- Guardrails alone (
storage.enabled: false) never writes to a database. - Storage requires ARMS Backend credentials (
API_BASE_URL,ELSAI_ARMS_API_KEY). - The active database type is resolved automatically via
GET /api/v1/db_type. - Run data is posted to
POST /api/v1/guardrails/{db_type}wheredb_typeismongodb,dynamodb, orclickhouse.
Supported Databases
| Database | Backend route | Notes |
|---|---|---|
| MongoDB | /api/v1/guardrails/mongodb | Default for many ARMS deployments |
| DynamoDB | /api/v1/guardrails/dynamodb | AWS-hosted ARMS stacks |
| ClickHouse | /api/v1/guardrails/clickhouse | Analytics-oriented deployments |
The guardrails SDK discovers the active type from the Backend. You do not pass a backend: mongodb setting in policy — direct database clients were removed in v0.1.5.
How It Works
- Enable storage in guardrails policy and provide Backend credentials.
GuardrailsStorageHookbuffers events in memory during a logical run.- Input checks, output checks, generate results, tool auth, and rate-limit events are collected.
- On
end_run()(or whenLLMRails.generate()completes), the hook builds a run document and POSTs it to the Backend. - The Backend persists the document to the configured database using your ARMS project context.
Persisted Run Document
Each flushed run includes correlation ids and check outcomes:
project,project_id,run_id,session_id,trace_iduser_input,final_response,llm_response(optionally redacted)input_check,output_check,pii_input_check,pii_output_checkexfiltration_output_checkrate_limit_check,token_budget_*checkstool_authorization_events,rate_limit_eventsblocked,block_reason,latency_ms,arms_correlated
Set store_raw_text: false to store SHA-256 digests instead of raw prompt/response text.
Configuration
Enable Storage
yaml
guardrails:
storage:
enabled: true
project: my-app
store_raw_text: true
fail_soft: true
unique_run_per_project: false
arms_correlation: trueBackend credentials are read from the same environment variables as ARMS, not duplicated in guardrails YAML:
| Variable | Required | Description |
|---|---|---|
API_BASE_URL | Yes | ARMS Backend base URL |
ELSAI_ARMS_API_KEY | Yes | API key for Backend authentication |
ARMS_MASTER_KEY | No | Optional master key sent as X-MASTER-KEY |
You may override credentials in policy when needed:
yaml
guardrails:
storage:
enabled: true
api_base_url: "https://arms-backend.example.com"
api_key: "your-api-key"
master_key: "optional-master-key"Storage Options
| Option | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable persistence via ARMS Backend |
project | str | "default" | Logical project name stored on run documents |
store_raw_text | bool | true | Store full text; false stores SHA-256 digests |
fail_soft | bool | true | Log warnings on write failure instead of raising |
unique_run_per_project | bool | false | Backend upsert behavior for run ids |
arms_correlation | bool | true | Auto-link run_id / project_id from ARMS env vars |
Environment Overrides
| Variable | Description |
|---|---|
GUARDRAILS_STORAGE_ENABLED | Force storage on/off (true / false) |
GUARDRAILS_ARMS_RUN_ID | ARMS run id for correlation |
GUARDRAILS_ARMS_PROJECT_ID | ARMS project id for correlation |
GUARDRAILS_ARMS_CORRELATION | Enable/disable automatic ARMS correlation |
GUARDRAILS_PROJECT | Default project name |
ARMS Correlation
Storage writes require a project_id. Link guardrails to an active ARMS run using one of these approaches:
1. link_arms() (recommended)
Call immediately after creating both clients, before any guardrail checks:
python
from elsai_guardrails.guardrails import LLMRails
from elsai_arms import ElsaiARMS # optional companion package
arms = ElsaiARMS(project_name="my-app")
rails = LLMRails.from_config("config.yml")
rails.guardrail_system.link_arms(arms)
response = rails.generate(
messages=[{"role": "user", "content": "Hello"}]
)
rails.guardrail_system.end_run()2. link_run_context()
Pass ids explicitly when you manage correlation yourself:
python
rails.guardrail_system.link_run_context(
run_id="abc123",
project_id="proj-456",
project="my-app",
)3. Environment variables
Set before starting the process:
bash
export GUARDRAILS_ARMS_RUN_ID=abc123
export GUARDRAILS_ARMS_PROJECT_ID=proj-456When arms_correlation: true (default), the storage hook picks up these ids automatically.
Usage Patterns
LLMRails (automatic buffering)
LLMRails wires the storage hook when storage is enabled. Each generate() call buffers results; flushing happens according to your run lifecycle:
python
from elsai_guardrails.guardrails import LLMRails
rails = LLMRails.from_config("config.yml")
rails.guardrail_system.link_run_context(
run_id="run-1",
project_id="project-1",
)
with rails.guardrail_system.storage_run_context(session_id="sess-1"):
rails.generate(messages=[{"role": "user", "content": "Hi"}])GuardrailSystem (manual lifecycle)
python
from elsai_guardrails.guardrails import GuardrailSystem, GuardrailConfig
from elsai_guardrails.guardrails.guardrail_policy import GuardrailPolicy
policy = GuardrailPolicy.from_yaml("config.yml")
guardrail = GuardrailSystem(
config=GuardrailConfig(),
guardrail_policy=policy,
)._with_storage_hook()
guardrail.link_run_context(run_id="run-1", project_id="project-1")
guardrail.begin_run()
guardrail.check_input("user message")
guardrail.end_run() # flushes to BackendFail-soft vs fail-hard
With fail_soft: true (default), Backend write failures are logged and the application continues. Set fail_soft: false to raise StorageWriteError when persistence fails.
Database Selection Flow
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| Storage silently disabled | Missing API_BASE_URL or ELSAI_ARMS_API_KEY | Set env vars or policy credentials |
Cannot persist without project_id | No ARMS correlation | Call link_arms() or set env ids |
Legacy backend: mongodb warning | Old direct-DB config | Migrate to Backend storage (see below) |
Unsupported db_type | Backend returned unknown type | Upgrade Backend or contact ARMS admin |
Migration from Direct Database Storage
In v0.1.5, direct guardrails-to-database clients were removed. Policies that set storage.backend: mongodb|dynamodb|clickhouse with connection strings no longer persist data — the SDK logs a warning and storage stays disabled.
Before (removed):
yaml
guardrails:
storage:
backend: mongodb
connection_string: "mongodb://..."After (ARMS Backend):
yaml
guardrails:
storage:
enabled: true
project: my-app
arms_correlation: truebash
export API_BASE_URL=https://your-arms-backend
export ELSAI_ARMS_API_KEY=your-api-key
export GUARDRAILS_ARMS_PROJECT_ID=your-project-idLink each run with link_arms(), link_run_context(), or the correlation environment variables before calling end_run().
Examples
See Basic Examples and Integration Examples for complete code samples.
python
import os
from elsai_guardrails.guardrails import GuardrailConfig, GuardrailSystem
from elsai_guardrails.guardrails.guardrail_policy import GuardrailPolicy
os.environ["API_BASE_URL"] = "https://your-arms-backend"
os.environ["ELSAI_ARMS_API_KEY"] = "your-api-key"
guardrails = GuardrailSystem(
config=GuardrailConfig(),
guardrail_policy=GuardrailPolicy.from_file("config.yaml"),
)._with_storage_hook()
guardrails.link_run_context(
run_id="demo-run-001",
project_id="demo-project-001",
project="demo-app",
)
guardrails.begin_run(session_id="sess-1")
guardrails.check_input("Hello")
guardrails.check_output("Hi there!")
saved_run_id = guardrails.end_run() # POST to BackendNext Steps
- Guardrails Configuration — storage policy reference
- Data Exfiltration Detection — exfiltration results in stored runs
- Tool Authorization — tool auth events persisted per run
- Rate Limiting — rate-limit events persisted per run