Drop-in exam proctoring middleware for FastAPI โ violation detection, camera/mic proctoring, credibility scoring
Project description
exam-guardrail ๐ก๏ธ
Drop-in exam proctoring backend by CogniVigil โ detect and terminate AI cheating tools, remote access apps, screen recorders, and cheat browser extensions in real time.
What It Does
exam-guardrail is a Python middleware that plugs into any FastAPI application and provides:
| Layer | What It Catches | Action |
|---|---|---|
| L4 โ Process Scanner | AI agents (Interview Coder, Cluely, ChatGPT, Cursor, Claude), remote access (AnyDesk, TeamViewer, VNC), screen share (Zoom, Discord, Quick Assist), screen recorders (OBS, Loom, Camtasia) | Detect + Kill |
| L3 โ Network Monitor | Active TCP connections to AI APIs (OpenAI, Anthropic, Google Gemini, Groq, DeepSeek, etc.) | Detect + Flag |
| L2 โ Hidden Window Detection | Windows WDA_EXCLUDEFROMCAPTURE flag, macOS kCGWindowSharingNone (used by AI overlays to hide from screen capture) |
Detect + Flag |
| L1 โ Browser Extension Scanner | 26+ cheat extensions across Chrome, Edge, Brave (Monica AI, Brainly, Chegg, ChatGPT for Google, etc.) | Detect + Disable |
All findings are scored on a 0โ100 credibility scale with automatic verdict assignment.
Quick Start (5 Minutes)
1. Install
pip install exam-guardrail
Dependencies installed automatically: fastapi, uvicorn, psutil, supabase, anthropic
2. Minimal Server (Monitoring Only)
Create server.py โ no database or API keys needed:
from fastapi import FastAPI
from exam_guardrail import GuardrailConfig, init_guardrail
app = FastAPI()
config = GuardrailConfig(
monitoring_only=True, # Skip DB-dependent routes
native_agent_block=True, # Kill detected threats (set False to detect-only)
native_agent_interval=3, # Scan every 3 seconds
)
init_guardrail(app, config)
uvicorn server:app --host 0.0.0.0 --port 8001
Note: Run as Administrator/root for full process termination capabilities on protected processes.
That's it. The scanner is now running in the background, terminating threats every 3 seconds.
3. Test It
# Trigger a scan
curl -X POST http://localhost:8001/api/native-agent/scan \
-H "Content-Type: application/json" \
-d '{"session_id": "test", "block": true}'
# Check what's blocked
curl http://localhost:8001/api/native-agent/blocked-list
# Health check
curl http://localhost:8001/health
Full Setup (With Database & AI)
For credibility reports, student management, AI-generated questions, and answer analysis:
1. Environment Variables
Create .env:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-anon-or-service-key
ANTHROPIC_API_KEY=sk-ant-xxxxx
ADMIN_USERNAME=admin
ADMIN_PASSWORD=your-secure-password
2. Full Server
from fastapi import FastAPI
from exam_guardrail import GuardrailConfig, init_guardrail
app = FastAPI()
config = GuardrailConfig(
# Reads from .env automatically, or set explicitly:
supabase_url="https://your-project.supabase.co",
supabase_key="your-key",
anthropic_api_key="sk-ant-xxxxx",
admin_username="admin",
admin_password="secure-pass",
monitoring_only=False, # Enable all routes
native_agent_block=True,
native_agent_interval=3,
)
init_guardrail(app, config)
This mounts 30+ API routes for sessions, events, students, questions, exams, submissions, reports, and native agent scanning.
Direct Scanner Usage (No Server)
Use the scanners as a library without running a server:
from exam_guardrail.services.scanners.ai_agent_detector import (
scan_ai_agents,
scan_ai_network_connections,
scan_hidden_windows,
)
from exam_guardrail.services.scanners.screen_share_detector import scan_screen_sharing
from exam_guardrail.services.scanners.process_blocker import scan_and_block
from exam_guardrail.services.scanners.extension_detector import (
scan_extensions,
restore_extensions,
)
# Detect only
ai_findings = scan_ai_agents()
network_findings = scan_ai_network_connections()
hidden_windows = scan_hidden_windows()
screen_share = scan_screen_sharing()
extensions = scan_extensions(block=False)
# Detect + Kill processes
blocked = scan_and_block()
# Detect + Disable extensions (renames folder to *.blocked)
disabled = scan_extensions(block=True)
# Re-enable extensions after exam
restore_extensions()
CLI Scanner
# Run as standalone scanner (prints findings to console)
python -m exam_guardrail.services.scanners --session-id exam123
# Custom options
python -m exam_guardrail.services.scanners.agent_runner \
--session-id exam123 \
--api-base http://localhost:8001/api \
--interval 3 \
--no-block
API Reference
Always Available Routes
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/events |
Ingest a behavioral event with severity and score delta |
POST |
/api/sessions |
Create a new exam session |
GET |
/api/sessions/{session_id} |
Get session details + all events |
GET |
/api/dashboard/overview |
List all sessions (auto-marks stale ones ABANDONED) |
GET |
/api/sessions/{session_id}/logs |
Detailed event logs |
GET |
/api/sessions/{session_id}/logs/export |
Export logs as Excel (.xlsx) |
POST |
/api/native-agent/scan |
On-demand scan with {"session_id": "...", "block": true} |
GET |
/api/native-agent/status/{session_id} |
Agent connection status + latest findings |
GET |
/api/native-agent/blocked-list |
Full list of blocked process names + extension IDs |
GET |
/api/native-agent/blocked-extensions |
Currently detected cheat extensions |
POST |
/api/native-agent/restore-extensions |
Re-enable all disabled extensions |
GET |
/health |
Health check with version info |
WS |
/ws/{session_id} |
WebSocket for real-time event streaming |
Full Mode Routes (monitoring_only=False)
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/admin-login |
Admin authentication |
POST |
/api/auth/student-login |
Student login (creates session automatically) |
POST |
/api/students |
Create student record |
GET |
/api/students |
List all students |
POST |
/api/questions |
Deploy exam question |
GET |
/api/questions?exam_name=... |
Get questions by exam or subject code |
POST |
/api/exams/generate-questions |
AI-generated MCQ questions (Claude) |
POST |
/api/answers |
Submit answer with AI naturalness scoring |
POST |
/api/student/exam/submit |
Submit full exam |
GET |
/api/reports/{session_id} |
Generate AI credibility report (Claude) |
GET |
/api/reports/{session_id}/export |
Export report as Excel |
GET |
/api/admin/reports |
List all credibility reports |
Configuration Reference
GuardrailConfig Options
| Parameter | Type | Default | Description |
|---|---|---|---|
supabase_url |
str |
"" |
Supabase project URL |
supabase_key |
str |
"" |
Supabase anon/service key |
anthropic_api_key |
str |
"" |
For AI-powered reports & question generation |
admin_username |
str |
"admin" |
Admin login username |
admin_password |
str |
"admin" |
Admin login password |
monitoring_only |
bool |
False |
True = only events/sessions/agent routes; no DB needed |
native_agent_enabled |
bool |
True |
Auto-start background scanner |
native_agent_block |
bool |
True |
True = terminate threats; False = detect only |
native_agent_interval |
int |
3 |
Seconds between scan cycles |
cors_origins |
list |
["*"] |
CORS allowed origins |
session_expiry_hours |
int |
2 |
Mark sessions older than this as ABANDONED |
severity_critical |
int |
-15 |
Score penalty for CRITICAL events |
severity_high |
int |
-10 |
Score penalty for HIGH events |
severity_medium |
int |
-5 |
Score penalty for MEDIUM events |
severity_low |
int |
-2 |
Score penalty for LOW events |
compounding_penalty_window_minutes |
int |
5 |
Time window for compounding violations |
compounding_penalty_threshold |
int |
3 |
Events in window to trigger extra penalty |
compounding_penalty_extra |
int |
10 |
Extra deduction when threshold met |
What Gets Detected
AI Agents & Coding Tools (16 processes)
| Tool | Process Name |
|---|---|
| Interview Coder | interviewcoder.exe |
| Cluely | cluely.exe, cluely_helper.exe |
| ParakeetAI | pmodule.exe |
| LockedIn AI | ghost.exe |
| ChatGPT Desktop | chatgpt.exe |
| Claude Desktop | claude.exe |
| Cursor | cursor.exe |
| GitHub Copilot | copilot.exe |
| Windsurf | windsurf.exe |
| Google Gemini | gemini.exe |
| MS Copilot Proxy | mscopilot_proxy.exe |
| Chegg | chegg.exe |
| Brainly | brainly.exe |
| Photomath | photomath.exe |
| Socratic | socratic.exe |
| Suspicious Electron | electron.exe (flagged as potential AI overlay) |
AI API Network Connections (12 domains)
api.openai.com ยท api.anthropic.com ยท generativelanguage.googleapis.com ยท api.groq.com ยท api.cohere.ai ยท api.mistral.ai ยท api.perplexity.ai ยท api.together.xyz ยท api.replicate.com ยท api.deepseek.com ยท api.fireworks.ai ยท api.x.ai
Command-Line Pattern Detection (13 patterns)
Inspects process command-line arguments for: openai, anthropic, chatgpt, claude, gemini, copilot, codewhisperer, gpt-4, gpt4, llama, --ai-, --model, huggingface
Remote Access Tools (16 processes)
AnyDesk ยท TeamViewer ยท Chrome Remote Desktop ยท VNC Server/Viewer ยท UltraViewer ยท Parsec ยท RustDesk ยท Ammyy Admin ยท Supremo ยท Splashtop ยท LogMeIn ยท BeyondTrust ยท ScreenConnect
Screen Share / Meeting Apps (13 processes)
Zoom ยท Microsoft Teams ยท Slack ยท Skype ยท Discord ยท Cisco Webex ยท GoToMeeting ยท join.me ยท BlueJeans ยท Zhumu ยท Quick Assist ยท Samsung Quick Share ยท Zoom Capture Host
Screen Recorders (15 processes)
OBS Studio (32/64-bit) ยท Streamlabs ยท Camtasia ยท Snagit ยท Bandicam ยท vMix ยท XSplit ยท Screencastify ยท Loom ยท ShareX ยท ScreenPal ยท Screenpresso ยท Kazam ยท SimpleScreenRecorder ยท FFmpeg
Browser Extensions (26 extensions)
AI Assistants: Monica AI ยท ChatGPT for Google ยท UseChatGPT ยท Merlin ยท Sider AI ยท MaxAI ยท Copilot Bing ยท Phind ยท Perplexity AI
Cheating Tools: Brainly ยท Chegg ยท CourseHero ยท Bartleby
Writing AI: Grammarly AI ยท QuillBot ยท Copy AI ยท Jasper AI
Screen Capture: Screencastify ยท Loom ยท GoFullPage ยท Scribe
Remote Access: Chrome Remote Desktop ยท AnyDesk
Scans Chrome, Edge, and Brave (all profiles).
Credibility Scoring
Every event affects the session's credibility score (starts at 100):
| Score Range | Verdict | Meaning |
|---|---|---|
| 90โ100 | CLEAR |
No significant issues |
| 70โ89 | UNDER_REVIEW |
Minor issues detected |
| 50โ69 | SUSPICIOUS |
Multiple violations |
| 0โ49 | FLAGGED |
Strong evidence of cheating |
Event Severity Levels
| Severity | Default Penalty | Example |
|---|---|---|
CRITICAL |
-15 | AI agent detected, remote access, hidden window |
HIGH |
-10 | Tab switch, clipboard, AI cmdline pattern |
MEDIUM |
-5 | Gaze away, loud audio, screen resize |
LOW |
-2 | Right-click attempt |
Compounding penalties apply when 3+ events occur within 5 minutes (configurable).
Architecture Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Frontend (Browser) โ
โ exam-guardrail (npm) โ L1/L2 behavioral detection โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โuseGuardrailโ โ Overlay โ โ GuardrailSDK โ โ
โ โโโโโโโโฌโโโโโโ โโโโโโโโโโโโ โโโโโโโโโฌโโโโโโโโโโ โ
โ โ โ โ
โ โโโโ POST /api/events โโโโโโโโโ โ
โ โโโโ POST /api/native-agent/scan โโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Backend (FastAPI + Python) โ
โ exam-guardrail (pip) โ L3/L4 native detection โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ NativeAgentMiddleware (ASGI) โ โ
โ โ โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ AI Agent โ โ Screen Share โ โ โ
โ โ โ Detector โ โ Detector โ โ โ
โ โ โโโโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโโโโโโโโค โ โ
โ โ โ Network โ โ Extension โ โ โ
โ โ โ Monitor โ โ Detector โ โ โ
โ โ โโโโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโโโโโโโโค โ โ
โ โ โ Hidden Window โ โ Process โ โ โ
โ โ โ Detector โ โ Blocker (SIGKILL) โ โ โ
โ โ โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ Supabase (PostgreSQL) โ
โ Claude AI (Reports) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Using with the npm Frontend Package
The Python backend is designed to work with the exam-guardrail npm package:
# Frontend
npm install exam-guardrail
# Backend
pip install exam-guardrail
// React frontend โ connects to your Python backend
import { useGuardrail } from 'exam-guardrail/react';
function ExamPage() {
const {
violations, mediaState, faceStatus, audioLevel, agentStatus,
requestMedia, startProctoring, triggerAgentScan, stop,
} = useGuardrail({
apiBase: '/api', // Proxy to your Python backend
sessionId: 'exam-123',
userId: 'student-456',
autoStart: true,
});
return (
<div>
<p>Violations: {violations}</p>
<p>Face: {faceStatus}</p>
<p>Agent: {agentStatus}</p>
<button onClick={triggerAgentScan}>Scan for AI Agents</button>
</div>
);
}
Configure your frontend build tool to proxy /api to the Python backend:
// vite.config.js
export default {
server: {
proxy: {
'/api': 'http://localhost:8001',
},
},
};
Platform Support
| Platform | Process Scanning | Network Monitor | Extension Scanner | Process Blocking | Hidden Window Detection |
|---|---|---|---|---|---|
| Windows | โ | โ | โ Chrome/Edge/Brave | โ (Admin recommended) | โ WDA_EXCLUDEFROMCAPTURE |
| macOS | โ | โ | โ Chrome/Edge/Brave | โ (sudo recommended) | โ kCGWindowSharingNone |
| Linux | โ | โ | โ Chrome/Edge/Brave | โ | โ |
Important Notes
- Run as Administrator (Windows) or sudo (macOS/Linux) for full process termination capabilities. Without elevation, killing UWP/Store apps (e.g., Quick Assist) may fail with ACCESS_DENIED.
- The process blocker uses SIGKILL (not SIGTERM) because Electron-based apps intercept SIGTERM.
- Browser extensions are disabled by renaming the extension folder to
*.blocked. They are automatically restored when the middleware shuts down, or manually viaPOST /api/native-agent/restore-extensions. - System-critical processes (explorer.exe, svchost.exe, browsers, python, node, etc.) are on an allowlist and are never terminated.
License
MIT ยฉ CogniVigil
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 exam_guardrail-1.0.1.tar.gz.
File metadata
- Download URL: exam_guardrail-1.0.1.tar.gz
- Upload date:
- Size: 40.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c153b7c6902d1b0c86a540274e357fb1e1b7838ac44064c4d9442f54a1469f1c
|
|
| MD5 |
68fac23dbc97a02b616415712e8909e2
|
|
| BLAKE2b-256 |
6636628c6851391f497fccc22172c01bdfa859e2253eb3b49cac0b8c99a46691
|
File details
Details for the file exam_guardrail-1.0.1-py3-none-any.whl.
File metadata
- Download URL: exam_guardrail-1.0.1-py3-none-any.whl
- Upload date:
- Size: 45.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c87a596ed2acc1f3cb2ee9a59564075b34775572d24969ca98dfe56a40f9b4d
|
|
| MD5 |
8ff8048c8d7ee2cbe3f2160032ea8b68
|
|
| BLAKE2b-256 |
754049b4c2f90e9f47759d436a9feae5fffd212479b6497b3487bc6ae000f0ec
|