Highflame Rust SDK
Async Rust client for the Highflame guardrails service — the AI safety layer that detects threats and enforces Cedar policies on your LLM calls, tool executions, and model responses.
Contents
- Requirements
- Installation
- Authentication
- Quick Start
- Client API
- Agentic Context
- Error Handling
- Enforcement Modes
- Session Tracking
- Multi-Project Support
- Client Options
Requirements
- Rust 1.75+
- Tokio async runtime
Installation
Add to your Cargo.toml:
[]
= "0.2"
= { = "1", = ["full"] }
For streaming, also add:
= "0.3"
Authentication
Create a client with your service key:
use ;
let client = new;
The API key can also be read from an environment variable:
let client = new;
For self-hosted deployments, override the service endpoints:
let client = new;
Highflame is cheap to clone — all clones share the same connection pool and token cache.
Quick Start
use ;
async
Client API
guard()
Full detection and Cedar policy evaluation. Accepts a GuardRequest and returns a GuardResponse.
use ;
let resp = client.guard.evaluate.await?;
if resp.denied else if resp.alerted.unwrap_or else
GuardRequest fields:
| Field | Type | Description |
|---|---|---|
content |
String |
Text to evaluate |
content_type |
ContentType |
Prompt, Response, ToolCall, or File |
action |
String |
"process_prompt", "call_tool", "read_file", "write_file", or "connect_server" |
mode |
Option<Mode> |
Enforce (default), Monitor, or Alert |
session_id |
Option<String> |
Session ID for cross-turn tracking |
tool |
Option<ToolContext> |
Tool call context |
model |
Option<ModelContext> |
LLM metadata |
file |
Option<FileContext> |
File operation context |
mcp |
Option<MCPContext> |
MCP server context |
GuardResponse fields:
| Field | Type | Description |
|---|---|---|
decision |
Decision |
Allow or Deny |
request_id |
String |
Request trace ID |
timestamp |
String |
Response timestamp (RFC 3339) |
latency_ms |
i64 |
Total evaluation latency in milliseconds |
signals |
Vec<Signal> |
Taxonomy-aligned detection signals, sorted by severity |
determining_policies |
Option<Vec<DeterminingPolicy>> |
Policies that determined the decision |
policy_reason |
Option<String> |
Human-readable policy decision reasoning |
actual_decision |
Option<String> |
Cedar decision before mode override |
alerted |
Option<bool> |
True when an alert-mode policy fired |
session_delta |
Option<SessionDelta> |
Session state changes after evaluation |
projected_context |
Option<HashMap<String, Value>> |
Cedar-normalized context (when explain=true) |
eval_latency_ms |
Option<i64> |
Cedar evaluation latency (when explain=true) |
explanation |
Option<ExplainedDecision> |
Structured policy explanation (when explain=true) |
root_causes |
Option<Vec<RootCause>> |
Root cause analysis (when explain=true) |
tiers_evaluated |
Option<Vec<String>> |
Detector tiers that ran (when explain=true) |
tiers_skipped |
Option<Vec<String>> |
Tiers skipped due to early exit (when explain=true) |
detectors |
Option<Vec<DetectorResult>> |
Per-detector results (when debug=true) |
context |
Option<HashMap<String, Value>> |
Raw merged detector output (when debug=true) |
debug_info |
Option<DebugInfo> |
Cedar evaluation inputs (when debug=true) |
Helper methods on GuardResponse:
resp.allowed // true when decision == Allow
resp.denied // true when decision == Deny
guard_prompt()
Shorthand for evaluating a user prompt.
// evaluate_prompt(content, mode, session_id)
let resp = client.guard
.evaluate_prompt
.await?;
// Omit optional fields with None
let resp = client.guard
.evaluate_prompt
.await?;
guard_tool_call()
Shorthand for evaluating a tool call by name and argument map.
use HashMap;
use json;
let mut args = new;
args.insert;
let resp = client.guard
.evaluate_tool_call
.await?;
if resp.denied
Streaming
stream() returns an impl Stream<Item = Result<SseEvent, HighflameError>>. Use pin_mut! before iterating.
use ;
use ;
let req = GuardRequest ;
let stream = client.guard.stream.await?;
pin_mut!;
while let Some = stream.next.await
ev.r#type |
Description |
|---|---|
"detector_result" |
A detector completed — payload is a DetectorResult |
"decision" |
Final allow/deny decision — payload is a GuardResponse |
"error" |
Stream error |
Agentic Context
Pass typed context structs to provide richer signal to detectors and Cedar policies.
ToolContext
use ;
use HashMap;
use json;
let resp = client.guard.evaluate.await?;
| Field | Type | Description |
|---|---|---|
name |
String |
Tool name |
arguments |
Option<HashMap<String, Value>> |
Tool arguments |
server_id |
Option<String> |
MCP server that registered this tool |
is_builtin |
Option<bool> |
Whether the tool is a first-party built-in |
description |
Option<String> |
Tool description |
ModelContext
use ;
let resp = client.guard.evaluate.await?;
MCPContext and FileContext
use ;
// MCP server connection
let resp = client.guard.evaluate.await?;
// File write
let resp = client.guard.evaluate.await?;
Error Handling
All client methods return Result<_, HighflameError>. Match on the enum variants to handle specific cases:
use HighflameError;
match client.guard.evaluate.await
| Variant | When returned | Fields |
|---|---|---|
HighflameError::Authentication |
401 Unauthorized | status: u16, title: String, detail: String |
HighflameError::RateLimit |
429 Too Many Requests | status: u16, title: String, detail: String |
HighflameError::Api |
Other non-2xx HTTP response | status: u16, title: String, detail: String |
HighflameError::ApiConnection |
Timeout or network failure | String message |
HighflameError::Deserialisation |
Response body could not be parsed | wraps serde_json::Error |
Helper methods:
err.status // Option<u16> — Some for API variants, None otherwise
err.is_api_error // true for Api variant
err.is_authentication_error // true for Authentication variant
err.is_rate_limit_error // true for RateLimit variant
err.is_connection_error // true for ApiConnection variant
Unlike the Python and JavaScript SDKs, there is no
BlockedErrorin Rust. A deny decision is a successful response — inspectresp.denied()on the returnedGuardResponse.
Enforcement Modes
| Mode | Behavior | resp.denied() |
resp.alerted |
|---|---|---|---|
"enforce" |
Block on deny | true on deny |
None |
"monitor" |
Allow + log silently | false |
None |
"alert" |
Allow + trigger alerting pipeline | false |
Some(true) if violated |
use ;
// Monitor — observe without blocking
let resp = client.guard.evaluate.await?;
if resp.actual_decision.as_deref == Some
// Alert — allow but signal the alerting pipeline
let resp = client.guard.evaluate.await?;
if resp.alerted.unwrap_or
// Enforce — block violations (default)
let resp = client.guard.evaluate.await?;
if resp.denied
Session Tracking
Pass the same session_id across all turns of a conversation to enable cumulative risk tracking. The service maintains action history across turns, which Cedar policies can reference.
let session_id = format!;
let resp = client.guard.evaluate.await?;
if let Some = &resp.session_delta
Multi-Project Support
Pass account_id and project_id to scope all requests to a specific project:
let client = new;
Client Options
HighflameOptions uses a builder pattern. All methods after new() are optional.
use Duration;
let opts = new
.base_url
.token_url
.timeout
.max_retries
.account_id
.project_id;
let client = new;
| Method | Default | Description |
|---|---|---|
new(api_key) |
— | Service key (hf_sk_...) or raw JWT |
.base_url(url) |
Highflame SaaS | Guard service URL |
.token_url(url) |
Highflame SaaS | Token exchange URL |
.timeout(duration) |
30s | Per-request timeout |
.max_retries(n) |
2 |
Retries on transient errors |
.account_id(id) |
— | Override tenant account ID |
.project_id(id) |
— | Override tenant project ID |
.default_headers(map) |
— | Custom headers sent with every request |
Internal Usage (Sentry, Overwatch, MCP Gateway)
Internal services that call Shield for non-guardrails products must set the X-Product header so Shield routes the request to the correct Cedar evaluator and policy set.
use HashMap;
// Sentry product
let sentry_client = new;
// Overwatch product (IDE integrations)
let overwatch_client = new;
// MCP Gateway product
let mcp_client = new;
When X-Product is not set, Shield defaults to "guardrails". External customers should never need to set this header.