
SAILLENTBook a DemoTechnical reference for deploying, configuring, integrating, and operating the SAILLENT runtime enforcement engine.
Documentation Version: This documentation describes runtime behavior, policy schema, API behavior, and security controls as implemented in SAILLENT v0.1.0. Updates to runtime behavior will trigger deliberate documentation revisions.
SAILLENT is a runtime enforcement layer for autonomous AI agents that controls requests traversing a configured enforcement path to downstream tools, APIs, and services.
SAILLENT intercepts requests, evaluates them against a GitOps-driven policy engine, and enforces a decision before the action executes.
The enforcement model is: Intercept → Inspect → Enforce
For each intercepted request, SAILLENT determines whether the action is permitted by the active policy set. Policy evaluation produces one of two decisions:
Separately, the inspection layer can apply Redact — modifying protected content (e.g., PII) before forwarding — when configured PII controls match. Redact is an inspection-layer action; it is not a policy decision and is not selectable through allowed_actions.
Upstream service: the external API, tool, or service to which SAILLENT forwards an admitted request.
Each enforcement decision is written to the local audit store together with the Git commit associated with the policy bundle currently loaded by the runtime.
The runtime engine is deployed as a native Linux binary within the customer's infrastructure. It handles traffic locally before it reaches the configured upstream service. Policy state is synchronized from a Git repository every 60 seconds.
sudo privilegeslicense.saillent.com (enrollment and heartbeat)SAILLENT deploys as a compiled Rust binary. No container runtime is required.
curl -fsSL https://get.saillent.com | sudo bash -s -- <YOUR_ENROLLMENT_TOKEN># Check service status
sudo systemctl status saillent
# View real-time enforcement logs
sudo journalctl -u saillent -f
# Inspect the local audit database
sudo sqlite3 /opt/saillent/saillent.db "SELECT decision, reason FROM audits ORDER BY id DESC LIMIT 5;"Policies are managed via Git. Create a file in your policy repository:
id: "analyst-postgres-001"
version: "1.0.0"
description: "Allow data analysts to read from postgres, block destructive actions"
agent_role: "data_analyst"
tool_id: "postgres_db"
allowed_actions:
- Read
conditions:
- MaxRiskScore: 50
- PayloadRegexDeny: "(?i)(DROP|DELETE|TRUNCATE)"
priority: 100
is_active: trueNote: The runtime engine polls the Git repository every 60 seconds. Once committed, the policy is validated by PolicyEngine::validate_policies and hot-swapped into memory without requiring a service restart. If validation fails, the update is rejected and the last-known-good policy remains active.
Every request traversing the configured SAILLENT enforcement path passes through the following sequential pipeline:
| Stage | Input | Processing | Output | Failure Behavior |
|---|---|---|---|---|
| 1. Receive | Raw HTTP request | Accept connection, check concurrency semaphore | Request admitted or 429 | If semaphore exhausted: immediate 429 |
| 2. Parse | HTTP body | Strict JSON deserialization via serde_json | Structured payload | Malformed JSON: immediate 400 |
| 3. Normalize | Raw text content | URL decode, recursive Base64/Gzip decode (5 iterations), NFKC normalize, strip zero-width chars, map homoglyphs | Canonical text | Decode failure: treat as opaque, continue |
| 4. Inspect | Normalized text | Scan against compiled regex patterns (PII, jailbreak, SSRF, path traversal) | Inspection flags | Regex cache bounded at 1000 entries |
| 5. Evaluate | Flags + context | Match against active policy set in priority order | Policy decision (Allow/Deny) | No matching policy: default Deny |
| 6. Enforce | Decision + inspection flags | Execute: forward (applying redaction if PII controls matched), or reject | HTTP response | Upstream error: pass through to caller |
| 7. Audit | Decision + context | Write to local SQLite with git_commit hash | Persisted record | DB unavailable: log warning, do not block enforcement |
Before security inspection, SAILLENT applies the following transformations to detect and reduce representation-based evasion. These are applied in order:
| Transformation | Purpose | Implementation |
|---|---|---|
| URL Decoding | Decode percent-encoded payloads | Standard URL decode |
| Recursive Base64/Gzip Decode | Unwrap layered encoding (up to 5 iterations) | BASE64_RE detection + decode loop |
| Unicode NFKC Normalization | Convert fullwidth, compatibility characters to canonical forms | unicode_normalization::nfkc() |
| Zero-Width Character Stripping | Remove invisible characters used to split keywords | Filter ranges: U+200B-U+200F, U+202A-U+202E, U+2060-U+206F, U+FEFF |
| Combining Diacritic Stripping | Remove combining marks used to alter character appearance | Filter range: U+0300-U+036F |
| Cyrillic Homoglyph Mapping | Map visually identical Cyrillic characters to Latin equivalents | Explicit mapping table |
Boundary: These transformations address known representation-based bypass techniques. They are not a guarantee against all possible encoding evasion. The normalization pipeline is versioned and updated as new techniques are identified.
Policies are YAML documents validated by the Rust PolicyEngine before loading. The following fields are defined in saillent-core/src/policy.rs:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique policy identifier |
version | string | Yes | Version string for the policy |
description | string | Yes | Human-readable explanation of intent |
agent_role | string | Yes | Role of the agent this policy applies to |
tool_id | string | Yes | Tool or API endpoint targeted |
allowed_actions | array | Yes | Permitted actions: Read, Write, Execute, Delete |
conditions | array | No | Additional enforcement constraints (see below) |
priority | integer (u32) | Yes | Evaluation order. Higher = evaluated first |
is_active | boolean | Yes | Whether the policy is currently enforced |
owner_team | string | No | Enterprise governance: owning team |
approved_by | string | No | Enterprise governance: approver |
compliance_frameworks | array | No | Enterprise governance: applicable frameworks |
risk_level | string | No | Enterprise governance: risk classification |
| Condition | Type | Description |
|---|---|---|
MaxRiskScore | u8 | Deny if the agent's calculated risk score exceeds this value |
AllowedHours | {start, end} | Restrict enforcement window to specific hours (u8, 0-23) |
DataClassificationNot | string | Deny if the data classification matches the specified level |
RequireMFA | bool | Require multi-factor authentication context for the action |
RequiresApproval | bool | Require explicit human approval before execution |
PayloadRegexDeny | string | Rust-compatible regex. If the normalized payload matches, deny the action |
Policies sorted by priority descending
↓
Evaluate highest priority policy
↓
Match?
├── No → next policy
└── Yes
↓
Policy decision (Allow/Deny)
↓
STOP (first match determines outcome)
Enforcement outcomes combine the policy decision (Allow or Deny) with any inspection-layer redaction applied to admitted requests.
The request is forwarded to the configured upstream service without modification. The decision is logged to the audit store.
Redact is an inspection-layer action triggered by configured PII controls. It is not one of the values in allowed_actions. A YAML policy cannot select Redact: policy evaluation yields only Allow or Deny. An allowed request may still have PII redacted before forwarding.
When the inspection layer detects matched PII patterns in the payload, those patterns are replaced with redaction tokens before forwarding:
[REDACTED_EMAIL][REDACTED_SSN][REDACTED_CC]The request is not forwarded. The caller receives a JSON error response with the decision code and reason. The specific HTTP status depends on the denial cause (e.g., 403 for policy violation, 413 for oversized payload, 429 for concurrency limit).
SAILLENT can inspect and enforce policies on the following traffic types:
| Interface | Supported | Enforcement Model |
|---|---|---|
| OpenAI API | Yes | Request interception |
| Anthropic API | Yes | Request interception |
| MCP (Model Context Protocol) | Yes | Tool/action interception |
| HTTP/JSON traffic | Yes | Request interception |
| Database protocols | No | Not currently supported |
Boundary: SAILLENT can govern an AI agent's HTTP/API request that ultimately targets a database, but it does not currently act as a native database protocol proxy. SAILLENT enforces policies on traffic routed through the enforcement path. It does not inspect all actions an agent could theoretically take outside the configured interception boundary.
| Limit | Value | Enforcement Point | Behavior on Exceed |
|---|---|---|---|
| Request body size | 1 MB (1,048,576 bytes) | HTTP layer (tower_http::LimitRequestBodyLayer) | Immediate 413 Payload Too Large |
| Concurrent requests | 100 per instance | Runtime (tokio::sync::Semaphore) | Immediate 429 Too Many Requests (non-blocking backpressure) |
| Text content length | 50,000 characters | Payload inspection phase | Rejected during normalization |
| Regex cache size | 1,000 entries | Regex compilation layer | LRU eviction of oldest entries |
SAILLENT uses fail-closed behavior for policy enforcement decisions. Auxiliary subsystem failures are handled according to the failure behavior documented below.
| Failure Scenario | System Behavior | Security Posture |
|---|---|---|
| Audit SQLite unavailable | Engine logs a non-fatal warning and continues enforcing policies | Enforcement continues; audit gap noted |
| Policy Git repo unreachable | Background sync fails gracefully. Last validated policy bundle retained | Last-known-good policy remains active |
| Invalid/malformed policy pushed | PolicyEngine::validate_policies rejects the update. Previous state retained | Update rejected |
| Control plane / heartbeat lost | Local enforcement continues. Reconnection attempted every ~10 seconds | Local enforcement continues |
| License revoked | License revocation is detected during the next successful heartbeat cycle. The current heartbeat interval is approximately 10 seconds. Upon receiving the revoked state, the runtime initiates its shutdown behavior and returns 503 Service Unavailable while transitioning out of service. | Shutdown behavior initiated after revocation detection |
| Payload exceeds 1 MB | Rejected at HTTP layer with 413 Payload Too Large | Resource protection |
| Concurrent requests exceed 100 | Excess rejected with 429 Too Many Requests | Backpressure |
Each enforcement decision is written to the local SQLite audit store. Each record contains:
| Field | Description |
|---|---|
audit_id | Unique identifier for the decision |
timestamp | ISO 8601 timestamp of the decision |
agent_id | Identifier of the agent that initiated the action |
tool_id | Target tool or API endpoint |
decision | Outcome recorded for the request: Allow, Deny, or Redact (Redact indicates the inspection layer modified the payload before forwarding) |
reason | Human-readable explanation of why the decision was made |
protocol | Protocol used (e.g., openai, anthropic, mcp) |
git_commit | The Git commit associated with the policy bundle currently loaded by the runtime |
Traceability: Each persisted enforcement decision records the Git commit associated with the active policy bundle, allowing the policy repository state used during enforcement to be identified. This supports customer governance, risk-management, and compliance processes.
SAILLENT trusts:
license.saillent.com) used for enrollment token validation and heartbeatAssumption: SAILLENT assumes the runtime host and its operating-system security boundary have not been compromised.
| Property | Behavior | Verification |
|---|---|---|
| Policy source | Git repository, polled every 60 seconds | Integration test |
| Policy validation | Schema + regex compilation validation before loading | Unit/integration tests |
| Policy update | Runtime hot-swap, no restart required | Integration test |
| Invalid policy handling | Rejected; last-known-good retained | Integration test |
| Request body limit | 1 MB (HTTP layer) | Automated test |
| Concurrency limit | 100 simultaneous requests per instance | Automated test |
| Audit persistence | Enforcement decisions written to SQLite | Integration test |
| Audit failure behavior | Enforcement continues if audit write fails | Failure test |
| Policy attribution | Git commit recorded in audit event | Integration test |
| Runtime language | Rust | Build verification |
| Deployment | Native Linux binary, systemd service | Deployment verification |
| Default unmatched action | Deny (fail-closed) | Integration test |
| CI enforcement | Compilation, tests, and linting gates. Builds with warnings denied (-D warnings) | CI pipeline |
SAILLENT produces the cryptographic, exportable evidence regulated teams need — across the US, Canada, and Europe. Explore compliance tooling →
Capability claims only — formal certifications & attestations in progress · Technical evidence available under NDA
Request a Technical Briefing →