Skip to content

bssingh/vera-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vera SDK

Rust SDK, demos, and guides for building apps on the Vera Secure AI Wasm Gateway.

Quick start

1. Add the SDK to your app

# Cargo.toml
[dependencies]
vera-client = { git = "https://github.com/bssingh/vera-sdk.git", path = "sdk" }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

2. Get a token

On the Vera hub host:

vera-hub keys --keystore ~/vera/data/keystore.redb create --principal my-app
# Prints: ef2cbfdd...56c  ← this is your VERA_TOKEN (shown once, store it now)

The operator must also authorize your principal in the policy:

# policy-global.toml on the hub
[principals.my-app]
connectors = ["echo", "bedrock-claude", "llm-local", "moonshine"]

3. Connect and call

use vera_client::VeraClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = VeraClient::builder()
        .url("https://18.190.188.99:8443")     // Vera hub Elastic IP
        .bearer_from_env("VERA_TOKEN")
        .danger_accept_invalid_certs(true)      // self-signed certs in dev
        .build()?;

    // Call Claude via Bedrock
    let resp = client.infer("bedrock-claude",
        b"What is Rust? Answer in one sentence.").await?;
    println!("{}", String::from_utf8_lossy(&resp.body));

    Ok(())
}

4. Run it

export VERA_URL="https://18.190.188.99:8443"
export VERA_TOKEN="ef2cbfdde0d1b0cb55d0610fea24754531436a761a35db942e5414cab9f9656c"
export VERA_INSECURE=1  # only for self-signed certs in dev
cargo run

Authentication

Every request to Vera requires a bearer token. The token maps to a principal — an identity with a policy (which connectors it can access, rate limits, vault rules).

Step Who How
1. Create key Operator vera-hub keys create --principal <name>
2. Authorize Operator Add principal to policy-global.toml
3. Use token App Authorization: Bearer <token> header

The SDK handles the header automatically via .bearer() or .bearer_from_env().

Default test credentials (dev only)

The deployed Vera hub at 18.190.188.99:8443 has a test principal:

export VERA_URL="https://18.190.188.99:8443"
export VERA_TOKEN="ef2cbfdde0d1b0cb55d0610fea24754531436a761a35db942e5414cab9f9656c"

This principal (test) has access to: echo, llm-local, bedrock-claude, llm-fallback.

Available connectors

Connector Type Default What it does
bedrock-claude Proxy Yes Claude models via AWS Bedrock (Haiku 4.5, Sonnet 4.6, Opus)
llm-local Proxy Qwen 3 0.6B via local Ollama
echo Wasm Returns input unchanged (testing)
moonshine Wasm Audio → transcript via Moonshine ONNX
llm-fallback Fallback chain Tries bedrock-claude, falls back to llm-local

Model aliases

Operators can define aliases so apps don't hardcode connector names:

# vera.toml
[[models]]
name = "claude"
connector = "bedrock-claude"

[[models]]
name = "default-llm"
connector = "llm-local"
// App calls the alias — operator controls which backend it maps to
let resp = client.infer("claude", b"Hello").await?;

Fallback chains

Operator-declared retry paths — if the primary connector fails, Vera tries the next:

# vera.toml
[[fallback_chains]]
name = "llm-fallback"
connectors = ["bedrock-claude", "llm-local"]
// App calls the chain name — Vera handles failover transparently
let resp = client.infer("llm-fallback", b"Hello").await?;

Three transport modes

Mode 1 — Request/Response (HTTP POST)

// Text prompt → LLM → complete response
let resp = client.infer("bedrock-claude", b"What is Rust?").await?;
println!("{}", String::from_utf8_lossy(&resp.body));

Mode 2 — Streaming response (chunked HTTP)

For LLM token streaming — tokens arrive as they generate:

let resp = client.infer("bedrock-claude", prompt_json).await?;
// resp.body contains the full streamed response collected by the SDK

Mode 3 — WebSocket bidirectional (real-time voice)

For real-time streaming — send audio chunks, receive text chunks:

let ws_url = client.ws_url("moonshine");
// Connect with tokio-tungstenite, send audio, receive transcripts

Discovery

Auto-discover available models and their capabilities:

let models = client.discover().await?;
for m in &models {
    println!("{}: {} ({}) — {:?}",
        m.id, m.display_name, m.provider, m.capabilities.modalities);
}

Smart dispatch uses discovery to pick the best transport:

// Discovers models, picks transport, dispatches
let resp = client.call("bedrock-claude", b"Hello").await?;

Agents

Run hosted agents that use LLMs + tools in a loop:

// Run the admin agent
let result = client.run_agent("admin", "show me all API keys").await?;
println!("{}", String::from_utf8_lossy(&result.body));

// Agent streaming via WebSocket
let ws_url = client.agent_ws_url("admin");
// Connect, send prompt as first message, receive AgentStep JSON objects

Available agents

Agent Brain Tools What it does
assistant llm-local echo, llm-local General assistant (sample)
admin llm-local admin-api Manage Vera via natural language

SDK reference

VeraClient::builder()

Method Required Description
.url("https://...") Yes Hub base URL
.bearer("vk_...") Yes Bearer token
.bearer_from_env("VERA_TOKEN") Alt Read token from env var
.session_id("session-123") No Multi-turn session correlation
.max_retries(3) No Max 429 retries (default 3)
.connect_timeout(Duration) No TCP connect timeout (default 10s)
.danger_accept_invalid_certs(true) No Dev only — self-signed TLS

Methods

Method Description
client.infer(connector, body) Call a connector (Mode 1 POST)
client.call(model, body) Smart dispatch with auto-negotiation
client.discover() Fetch + cache available models
client.plugin(plugin_id, body) Call a plugin
client.run_agent(agent_id, prompt) Run a hosted agent
client.ws_url(connector) Build WebSocket URL (Mode 3)
client.agent_ws_url(agent_id) Build agent streaming WebSocket URL
client.with_session(id) Clone with session id

Error handling

use vera_client::VeraError;

match client.infer("bedrock-claude", prompt).await {
    Ok(resp) => println!("{}", String::from_utf8_lossy(&resp.body)),
    Err(VeraError::Unauthorized) => eprintln!("Bad token"),
    Err(VeraError::Forbidden) => eprintln!("Not authorized for this connector"),
    Err(VeraError::Throttled { retry_after_secs, .. }) => {
        eprintln!("Rate limited — retry in {retry_after_secs}s")
    }
    Err(VeraError::VaultBlocked { rules, .. }) => {
        eprintln!("PII detected: {rules:?}")
    }
    Err(VeraError::Server { status, message }) => {
        eprintln!("Server error {status}: {message}")
    }
    Err(VeraError::Transport(e)) => eprintln!("Network: {e}"),
    Err(VeraError::Config(msg)) => eprintln!("Config: {msg}"),
}

What Vera handles server-side

Your app doesn't implement any of these — the gateway enforces them on every call:

  • Authentication — token → principal resolution
  • Policy — which connectors each principal can call (Lean 4 proven monotonicity)
  • Content rules — PII detection with observe/block/mask actions (Lean 4 proven non-bypass)
  • Rate limiting — 7-dimension QoS (principal, connector, group, agent, upstream, pairs, cooldown)
  • Fallback chains — automatic retry across connector chains on failure
  • Audit chain — BLAKE3 hash-chained, Ed25519-signed sealed segments
  • Egress control — connectors can only reach allow-listed hosts
  • Metrics — Prometheus scrape endpoint

Demo apps

demos/echo/

cd demos/echo
export VERA_URL="https://18.190.188.99:8443"
export VERA_TOKEN="ef2cbfdde0d1b0cb55d0610fea24754531436a761a35db942e5414cab9f9656c"
export VERA_INSECURE=1
cargo run -- "Hello, Vera!"

Deployment Profiles

Vera ships three deployment profiles. Your SDK code doesn't change — only the server-side config differs.

Profile Installer Use case Models
Local ./deploy/install-local.sh On-device AI, no cloud. Data never leaves the machine. Ollama (Qwen, Llama, etc.), Moonshine STT
Network ./deploy/install.sh Full deployment. Local + cloud models, forward proxy, all features. Everything — Ollama + Bedrock + Anthropic + OpenAI
Policy Only ./deploy/install-policy.sh Security layer for cloud AI. No local inference. PII scanning, audit, compliance. Bedrock Claude, Anthropic (proxy), OpenAI (proxy)

Local Mode

# On-device — no cloud, no data leaves the machine
./deploy/install-local.sh
# App connects to http://127.0.0.1:8443

Network Mode (full)

# All features — local models + cloud + proxy + forward proxy
./deploy/install.sh
# Edit vera.env with AWS creds
sudo systemctl start vera-hub

Policy Only Mode

# Security/compliance layer for cloud AI
./deploy/install-policy.sh
# Edit vera.env with AWS creds
sudo systemctl start vera-hub
# Apps use:
#   HTTPS_PROXY=http://vera:8080 (transparent, no code changes)
#   ANTHROPIC_BASE_URL=https://vera:8443/anthropic (reverse proxy)
#   https://vera:8443/v1/infer/bedrock-claude (Vera API)

What all profiles share

  • Pipeline: auth → policy → QoS → vault → dispatch → audit
  • Vault PII scanning (SSN + credit card with Luhn validation)
  • BLAKE3 hash-chained audit (EU AI Act Art. 12 compliant)
  • Lean 4 formal proofs (policy monotonicity, ingress non-bypass)
  • Wasm sandboxed connectors
  • Admin agent + chat UI
  • Same SDK — your app code doesn't change between profiles

Links

About

Rust SDK, demos, and sample apps for the Vera Secure AI Wasm Gateway

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages