Skip to main content

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.

PyPI License: MIT Python 3.9+


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 via POST /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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

exam_guardrail-1.0.1.tar.gz (40.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

exam_guardrail-1.0.1-py3-none-any.whl (45.5 kB view details)

Uploaded Python 3

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

Hashes for exam_guardrail-1.0.1.tar.gz
Algorithm Hash digest
SHA256 c153b7c6902d1b0c86a540274e357fb1e1b7838ac44064c4d9442f54a1469f1c
MD5 68fac23dbc97a02b616415712e8909e2
BLAKE2b-256 6636628c6851391f497fccc22172c01bdfa859e2253eb3b49cac0b8c99a46691

See more details on using hashes here.

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

Hashes for exam_guardrail-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5c87a596ed2acc1f3cb2ee9a59564075b34775572d24969ca98dfe56a40f9b4d
MD5 8ff8048c8d7ee2cbe3f2160032ea8b68
BLAKE2b-256 754049b4c2f90e9f47759d436a9feae5fffd212479b6497b3487bc6ae000f0ec

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page