AI-first runtime security framework for AI agents โ 14 guards, 5 framework adapters, structured SLM prompts, sub-ms rule checks
Project description
Overview
Qise (pronounced "Cheese" ๐ง) is an open-source runtime security framework that protects AI agents from both directions:
- World โ Agent: Stops prompt injection, tool poisoning, memory/KB tampering, and supply chain attacks
- Agent โ World: Stops dangerous commands, path traversal, SSRF, data exfiltration, and policy violations
Unlike rule-only solutions that are easily bypassed, Qise uses layered AI models (SLM fast-screen + LLM deep analysis) to understand attack intent, with deterministic rules as fast-path and fallback โ never fail-open.
System Architecture
Agent (Claude Code / Codex / Gemini CLI / Custom)
โ
โ API Request (OpenAI-compatible format)
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Tauri 2 Desktop App โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ System Tray โ Guard Dashboard โ Config Editor โ โ
โ โ Agent Panel โ Event Log (WS) โ Stats Bar โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Rust Proxy (axum, port 8822) โ
โ โข Request/Response interception โ
โ โข SSE streaming passthrough โ
โ โข Guard pipeline integration โ
โ โข Proxy Takeover (env + config file) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Python Bridge (aiohttp, port 8823) โ
โ โข Guard Pipeline execution โ
โ โข SLM/LLM inference (httpx) โ
โ โข WebSocket event push (/v1/bridge/events/stream) โ
โ โข 7 HTTP endpoints + 1 WS endpoint โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Guard Pipeline (14 Guards) โ
โ Ingress: Prompt โ ToolSanity โ Context โ SupplyChain โ
โ Egress: Command โ FS โ Network โ Exfil โ Resource โ
โ Output: Credential โ Audit โ Output โ
โ Soft: SecurityContextProvider + ReasoningGuard โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Model Layer โ
โ SLM: Ollama qwen3:4b (local, <2s) โ
โ LLM: Cloud API (Claude/GPT/Qwen, <5s) โ
โ Rules: Deterministic fallback (<1ms) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Forwarded Request
โผ
Upstream LLM API
Quick Start
1. Install Python Engine
# Clone and install
git clone https://github.com/morinop/qise.git
cd qise
pip install -e ".[dev]"
2. One-Command Setup
# Generate default config
qise init
# Check a tool call
qise check bash '{"command": "rm -rf /"}'
# โ {"verdict": "block", "blocked_by": "command", ...}
qise check bash '{"command": "ls"}'
# โ {"verdict": "pass", "blocked_by": null, "warnings": []}
# List all guards and their modes
qise guards
3. Setup Local SLM (Recommended)
Qise works out-of-the-box with rules only, but AI-first guards need an SLM. Local Ollama gives <2s latency:
# One-click: install Ollama + pull qwen3:4b (~2.4GB)
chmod +x scripts/setup_slm.sh
./scripts/setup_slm.sh
Or manually:
curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen3:4b
ollama serve
Then configure shield.yaml:
models:
slm:
base_url: "http://localhost:11434/v1"
model: "qwen3:4b"
timeout_ms: 5000
4. Zero-Code: Proxy Mode
Start a local HTTP proxy that intercepts all AgentโLLM traffic:
# Start proxy server
qise proxy start --port 8822 --upstream https://api.openai.com
# Point your agent at the proxy
export OPENAI_API_BASE="http://localhost:8822/v1"
The proxy intercepts requests/responses in real-time, running all 14 guards on tool calls, injection attempts, and output leaks โ with SSE streaming support for zero-latency text passthrough.
5. Desktop App (One-Click Security)
The Qise desktop app provides a one-click security toggle with real-time monitoring:
# Prerequisites: Node.js + Rust
cd src-tauri && cargo tauri dev
Features:
- System Tray: One-click protection toggle, status indicator, menu text auto-switches
- Guard Dashboard: Real-time guard events, mode switching (observe/enforce/off)
- Config Editor: Visual shield.yaml editing (SLM, LLM, Guards, Integration)
- Agent Panel: Detect installed agents, one-click proxy takeover with crash recovery
- Event Log: WebSocket real-time push, filter by All/Blocked/Warnings
- Stats Bar: Blocked/warning counts, SLM status (local/cloud/unavailable), latency
Proxy Takeover: Click "Take Over" to redirect your agent's API endpoint to the Qise proxy. Original config is backed up and auto-restored on exit or crash.
| Agent | Method | Redirect Target |
|---|---|---|
| Generic OpenAI | OPENAI_API_BASE env var |
http://localhost:8822/v1 |
| Claude Code | ANTHROPIC_BASE_URL env var + ~/.claude/settings.json |
http://localhost:8822/v1 |
6. Zero-Code: MCP Mode
Add to your agent's MCP configuration:
{
"mcpServers": {
"qise": {
"command": "python",
"args": ["-m", "qise.mcp_server"]
}
}
}
7. SDK Mode: Framework Adapters
Nanobot:
from qise import Shield
from qise.adapters.nanobot import QiseNanobotHook
shield = Shield.from_config()
hook = QiseNanobotHook(shield)
loop = AgentLoop(hooks=[hook])
LangGraph:
from qise import Shield
from qise.adapters.langgraph import QiseLangGraphWrapper
shield = Shield.from_config()
wrapper = QiseLangGraphWrapper(shield)
safe_tools = [wrapper.wrap_tool_call(tool) for tool in my_tools]
NexAU:
from qise import Shield
from qise.adapters.nexau import QiseNexauMiddleware
shield = Shield.from_config()
middleware = QiseNexauMiddleware(shield)
agent = NexAUAgent(middlewares=[middleware])
OpenAI Agents SDK:
from qise import Shield
from qise.adapters.openai_agents import QiseOpenAIAgentsGuardrails
shield = Shield.from_config()
guardrails = QiseOpenAIAgentsGuardrails(shield)
agent = Agent(guardrails=[guardrails.input_guardrail, guardrails.output_guardrail])
Hermes:
from qise import Shield
from qise.adapters.hermes import QiseHermesPlugin
shield = Shield.from_config()
plugin = QiseHermesPlugin(shield)
plugin.register(ctx)
Why Qise
| Problem | Qise's Approach |
|---|---|
| Keyword rules easily bypassed | AI understands attack semantics, not just pattern matching |
| Single model bottleneck | Layered models: SLM <50ms fast-screen + LLM deep analysis |
| Fail-open on model errors | Rule fallback โ never fail-open |
| No exfiltration detection | ExfilGuard: AI-first data exfiltration detection |
| No tool poisoning detection | ToolSanityGuard: hash baseline + AI semantic analysis |
| Static safety instructions | Dynamic SecurityContextProvider + Guard enforcement |
| Requires code changes | Proxy mode / MCP mode: zero-code integration |
| Cloud SLM latency 14-30s | Local Ollama qwen3:4b: <2s per call |
Three-Layer Decision Flow
Every guard uses the same decision flow โ rules first for speed, AI for semantics, rules last for safety:
โโโโโโโโโโโโโโโโโโโโ
โ Rule Fast-Path โ <1ms โ deterministic BLOCK or PASS
โ (regex, hash, โ e.g., "rm -rf /" โ BLOCK
โ patterns) โ For AI-first guards, only BLOCK short-circuits
โโโโโโโโโโฌโโโโโโโโโโ (rule PASS flows to SLM for final say)
โ uncertain or PASS (AI-first guards)
โผ
โโโโโโโโโโโโโโโโโโโโ
โ SLM Fast-Screen โ <2s (local Ollama) โ semantic classification
โ (โค4B model) โ e.g., obfuscated command โ BLOCK
โโโโโโโโโโฌโโโโโโโโโโ e.g., paraphrased injection โ ESCALATE
โ SLM can override low-confidence rule WARNs (<0.65)
โ but not high-confidence ones (โฅ0.65)
โผ
โโโโโโโโโโโโโโโโโโโโ
โ LLM Deep Analysisโ <2s โ full trajectory reasoning
โ (8B-70B model) โ e.g., multi-turn attack chain โ BLOCK
โโโโโโโโโโฌโโโโโโโโโโ
โ model unavailable
โผ
โโโโโโโโโโโโโโโโโโโโ
โ Rule Fallback โ <1ms โ conservative defaults
โ (never fail-open)โ e.g., WARN on uncertain + network tool
โโโโโโโโโโโโโโโโโโโโ
Defense in Depth
Layer 0: SecurityContextProvider โ Agent follows voluntarily (~80%)
Layer 1: ReasoningGuard โ Chain-of-thought monitoring + threshold adjustment
Layer 2: Guard Pipeline (14) โ Rule โ SLM โ LLM โ Rule fallback
Layer 3: OutputGuard + CredentialGuard โ Data leak detection
14 Guards at a Glance
Ingress Pipeline (World โ Agent)
| Guard | Strategy | Detects |
|---|---|---|
| PromptGuard | AI-first (80/20) | Indirect injection, multi-turn attacks, context poisoning |
| ToolSanityGuard | AI-first (80/20) | Tool description poisoning, rug pulls, name shadowing |
| ContextGuard | AI+hash (70/30) | Memory/KB poisoning, data tampering, hash integrity |
| SupplyChainGuard | AI+rules (60/40) | Malicious Skills, MCP tampering, source verification |
Egress Pipeline (Agent โ World)
| Guard | Strategy | Detects |
|---|---|---|
| ReasoningGuard * | AI-only (100/0) | Manipulation traces in chain-of-thought, threshold adjustment |
| CommandGuard | Rules+AI (70/30) | Shell injection, dangerous commands, privilege escalation |
| FilesystemGuard | Rules (90/10) | Path traversal, workspace violations, system dir access |
| NetworkGuard | Rules (90/10) | SSRF, forbidden domains, internal network scanning |
| ExfilGuard | AI-first (80/20) | Data exfiltration, covert channels, DNS exfil |
| ResourceGuard | Rules+AI (60/40) | Infinite loops, budget overruns, circuit breaker |
| ToolPolicyGuard | Rules (100/0) | Unauthorized tool access, deny/approval/owner-only |
Output Pipeline (Audit)
| Guard | Strategy | Detects |
|---|---|---|
| CredentialGuard | Rules (100/0) | API keys, secrets, tokens in output |
| AuditGuard | AI+rules (50/50) | Attack chain reconstruction, session risk scoring |
| OutputGuard | AI+rules (70/30) | PII exposure, KB content leaks, credential leaks |
* ReasoningGuard is cross-cutting โ detects manipulation in chain-of-thought and adjusts thresholds of other guards.
5 Framework Adapters
| Framework | Ingress | Egress | Output | SecContext |
|---|---|---|---|---|
| Nanobot | โ | โ | โ | โ |
| Hermes | โ | โ | โ | โ |
| NexAU | โ | โ | โ | โ |
| LangGraph | โ | โ | โ | โ |
| OpenAI Agents | โ | โ | โ | โ |
All adapters use IngressCheckMixin + EgressCheckMixin โ no monkey-patching, only official Hook/Plugin/Middleware APIs.
Configuration (shield.yaml)
version: "1.0"
integration:
mode: proxy # proxy | mcp | sdk
proxy:
port: 8822
auto_takeover: true
crash_recovery: true
models:
slm:
base_url: "http://localhost:11434/v1" # Ollama
model: "qwen3:4b"
timeout_ms: 5000
llm:
base_url: "https://api.anthropic.com"
model: "claude-sonnet-4-5"
timeout_ms: 5000
guards:
enabled: [prompt, command, credential, reasoning, filesystem, network,
exfil, resource, audit, tool_sanity, context, output, tool_policy, supply_chain]
config:
prompt:
mode: observe # observe | enforce | off
slm_confidence_threshold: 0.7
skip_slm_on_rule_pass: false
command:
mode: enforce
exfil:
mode: observe
skip_slm_on_rule_pass: true
slm_override_rule_warn_threshold: 0.8
Environment variable overrides: QISE_SLM_BASE_URL, QISE_SLM_MODEL, QISE_SLM_API_KEY, QISE_LLM_BASE_URL, QISE_PROXY_PORT, QISE_MODE.
Performance
| Operation | Target | Measured (p95) |
|---|---|---|
| Rule fast-path (single guard) | <1ms | ~0.02ms |
| Full egress pipeline (6 guards) | <10ms | ~0.02ms |
| Local SLM (Ollama qwen3:4b) | <2s | ~500ms-2s (M1+) |
| Full pipeline + local SLM | <3s | ~1-2s |
Scripts
| Script | Description |
|---|---|
scripts/setup_slm.sh |
Install Ollama + pull qwen3:4b (one-click local SLM) |
scripts/benchmark_slm.py |
Compare local Ollama vs cloud SLM latency |
scripts/e2e_tauri_test.py |
End-to-end verification: Proxy โ Bridge โ Guard โ API |
Development
pip install -e ".[dev]" # Install with dev dependencies
pytest tests/ -v # Run 461+ tests
ruff check . # Lint
ruff format . # Format
mypy src/qise # Type check
cd src-tauri && cargo tauri dev # Run desktop app
cd src-tauri && cargo tauri build # Build desktop app
Evaluation Results
R12-tuned evaluation (SLM + rules pipeline vs rules-only baseline):
| Metric | Rules-Only | SLM + Rules | Delta |
|---|---|---|---|
| Precision | 0.643 | 1.000 | +0.357 |
| Recall | 0.973 | 1.000 | +0.027 |
| F1 | 0.774 | 1.000 | +0.226 |
| FPR | 0.400 | 0.000 | +0.400 (lower=better) |
Architecture
qise/
โโโ src/qise/
โ โโโ core/ # GuardContext, AIGuardBase, Pipeline, Shield, Config
โ โโโ guards/ # 14 Guard implementations
โ โโโ models/ # ModelRouter (httpx-based OpenAI-compatible client)
โ โโโ data/ # ThreatPatternLoader + BaselineManager + SQLite
โ โโโ providers/ # SecurityContextProvider (DSL template rendering)
โ โโโ adapters/ # 5 Framework adapters
โ โโโ proxy/ # HTTP proxy server (aiohttp + SSE)
โ โโโ bridge/ # Python Bridge (7 HTTP + 1 WS endpoint)
โ โโโ mcp_server.py # MCP Server (4 security check tools)
โโโ src-tauri/ # Desktop App (Tauri 2 + React)
โ โโโ src/ # Rust backend (proxy, bridge, takeover, 12 IPC commands)
โ โโโ icons/ # App icons
โโโ src-ui/ # React frontend (Raycast-style dark UI)
โ โโโ src/components/ # StatusIndicator, ProxyToggle, GuardList, EventLog,
โ # AgentPanel, ConfigPanel
โโโ scripts/ # setup_slm.sh, benchmark_slm.py, e2e_tauri_test.py
โโโ data/ # threat_patterns/, security_contexts/, prompts/
โโโ tests/ # 461+ tests
โโโ eval/ # Evaluation datasets and results
โโโ docs/ # Architecture, Guards, Threat Model, Integration
CLI Reference
qise check bash '{"command": "rm -rf /"}' # Single security check
qise serve # Start MCP Server
qise proxy start --port 8822 # Start Rust HTTP proxy
qise bridge start --port 8823 # Start Python Bridge
qise init # Generate shield.yaml
qise guards # List registered guards
qise adapters # List framework adapters
qise context bash # Get security context
qise version # Print version
Integration Modes
| Mode | Code Required | Defense Depth | Best For |
|---|---|---|---|
| Proxy Mode | 0 lines | Full (4 layers) | Desktop users, non-developers |
| MCP Mode | 0 lines | Hard defense (14 guards) | MCP ecosystem users |
| SDK Mode | 1-5 lines | Full (4 layers) + lowest latency | Agent developers |
Status
| Component | Status |
|---|---|
| Core engine (AIGuardBase, Pipeline, Shield) | โ Complete |
| 14 Guards (Ingress + Egress + Output) | โ Complete |
| ModelRouter (httpx-based SLM/LLM client) | โ Complete |
| Ollama SLM integration (qwen3:4b, <2s) | โ Complete |
| Rust Proxy (axum + hyper + rustls, SSE streaming) | โ Complete |
| Python Bridge (aiohttp, 7 HTTP + 1 WS endpoint) | โ Complete |
| Desktop App (Tauri 2, System Tray, Config Editor) | โ Complete |
| Proxy Takeover (env + config file + crash recovery) | โ Complete |
| Real-time Frontend (GuardList, EventLog, AgentPanel, ConfigPanel) | โ Complete |
| 5 Framework Adapters (Nanobot, Hermes, NexAU, LangGraph, OpenAI Agents) | โ Complete |
| MCP Server (4 security check tools) | โ Complete |
| SecurityContextProvider (DSL template rendering) | โ Complete |
| BaselineManager (SHA-256 hash + SQLite) | โ Complete |
| 461+ unit + integration + performance tests | โ Complete |
| OpenAI Agents SDK E2E Test (10/10 passed) | โ Complete |
License
CC BY-NC-SA 4.0 โ Free for personal, academic, and non-commercial use. Commercial use requires separate permission.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qise-0.2.0.tar.gz.
File metadata
- Download URL: qise-0.2.0.tar.gz
- Upload date:
- Size: 873.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69a8df51dc89af7d2dc2866b004556ba7143d14921bcd24e4791dd345c55a5a3
|
|
| MD5 |
a9781fbe3e74868de936c351842e9548
|
|
| BLAKE2b-256 |
baac49ee4921d24e4ad1be5cc1434df98c019d3b7ff688b511568733eb6a896e
|
Provenance
The following attestation bundles were made for qise-0.2.0.tar.gz:
Publisher:
workflow.yml on WhitzardAgent/qise
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qise-0.2.0.tar.gz -
Subject digest:
69a8df51dc89af7d2dc2866b004556ba7143d14921bcd24e4791dd345c55a5a3 - Sigstore transparency entry: 1408931765
- Sigstore integration time:
-
Permalink:
WhitzardAgent/qise@895f7ec1acd6b38ed4864632629fd3c8bfd73a95 -
Branch / Tag:
refs/tags/v0.18.0 - Owner: https://github.com/WhitzardAgent
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@895f7ec1acd6b38ed4864632629fd3c8bfd73a95 -
Trigger Event:
release
-
Statement type:
File details
Details for the file qise-0.2.0-py3-none-any.whl.
File metadata
- Download URL: qise-0.2.0-py3-none-any.whl
- Upload date:
- Size: 138.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15bed8b0213a2e20fe1f6424f569f36ae983d21f70a9edfb26a22fca9d499590
|
|
| MD5 |
939c638d7e6ea804c010929cd5065328
|
|
| BLAKE2b-256 |
52f855040fbc62bbc0f59c09b47801b7b6220bcbd835806f7311f07aa78ed169
|
Provenance
The following attestation bundles were made for qise-0.2.0-py3-none-any.whl:
Publisher:
workflow.yml on WhitzardAgent/qise
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qise-0.2.0-py3-none-any.whl -
Subject digest:
15bed8b0213a2e20fe1f6424f569f36ae983d21f70a9edfb26a22fca9d499590 - Sigstore transparency entry: 1408931818
- Sigstore integration time:
-
Permalink:
WhitzardAgent/qise@895f7ec1acd6b38ed4864632629fd3c8bfd73a95 -
Branch / Tag:
refs/tags/v0.18.0 - Owner: https://github.com/WhitzardAgent
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@895f7ec1acd6b38ed4864632629fd3c8bfd73a95 -
Trigger Event:
release
-
Statement type: