SentryQ — How I Built a Local-AI Powered Security Scanner

medium.com · Gaurav Jha · 4 days ago · tutorial
quality 7/10 · good
0 net
Tags
SentryQ — How I Built a Local-AI Powered Security Scanner | by Gaurav Jha - Freedium Milestone: 20GB Reached We’ve reached 20GB of stored data — thank you for helping us grow! Patreon Ko-fi Liberapay Close < Go to the original SentryQ — How I Built a Local-AI Powered Security Scanner TL;DR: SentryQ is an open-source security platform written in Go that fuses 12,400+ static rules across 67+ languages, Tree-Sitter AST… Gaurav Jha Follow ~17 min read · April 5, 2026 (Updated: April 5, 2026) · Free: Yes TL;DR: SentryQ is an open-source security platform written in Go that fuses 12,400+ static rules across 67+ languages, Tree-Sitter AST analysis, inter-procedural taint-flow tracking, Shannon-entropy secret detection, SCA/OSV dependency auditing, Dockerfile & Kubernetes linting, and MITRE ATT&CK enrichment — then validates every finding through a local Chain-of-Thought AI Judge running on Ollama. Zero cloud dependencies. Your code never leaves localhost . 1. The Problem — Why Traditional SAST Fails If you've ever run a SAST tool on a production codebase, you know the drill: 1. You trigger a scan. 2. You grab a coffee. 3. You come back to 500 "CRITICAL" alerts. 4. You spend three days triaging them. 5. You discover 490 were false positives. This is Alert Fatigue — and it's destroying DevSecOps adoption. ### Why does this happen? Traditional scanners rely on regex pattern matching. If a rule says *"Flag any string that looks like a JWT token,"* it will happily flag: - Unit test mock tokens - Documentation examples - Comment blocks explaining JWT flow - Environment variable *references* (not values) - Base64-encoded config that looks high-entropy The scanner has zero understanding of context. It can't tell the difference between S ECRET_KEY = "hunter2" in production code and SECRET_KEY = process.env.SECRET_KEY which is perfectly safe. ### The numbers tell the story Traditional SAST tools average a 60–80% false positive rate , requiring 3–5 days of manual triage per scan. SentryQ targets 8–15% false positives with 30–60 minutes of triage, using AST + Taint + AI context awareness across 67+ languages — all with zero cloud dependency. ### The cloud privacy problem Some teams try to fix Alert Fatigue by sending code to cloud-hosted LLMs. But most enterprise compliance frameworks — SOC 2, HIPAA, PCI DSS, ISO 27001 — strictly forbid sending source code to third-party AI providers. We needed the speed of Go, the strictness of static rules, and the reasoning of an AI — all running entirely on localhost. 2. The Solution — SentryQ's Multi-Tier Architecture SentryQ is not a single scanner. It's a pipeline of seven independent analysis engines whose results converge through an AI-powered validation and deduplication layer. Every engine runs independently. The AI layer is entirely optional — SentryQ produces useful results with pure static analysis alone. When AI is enabled, it acts as a filter, not a crutch. 3. Engine #1 — Pattern Matching (12,400+ Rules) The pattern engine is the workhorse. It ships with 67 YAML rule files covering languages from Assembly to Zig, plus framework-specific rulesets. Supported languages (67+): Python, JavaScript, TypeScript, Go, Java, Kotlin, C, C++, C#, Rust, Ruby, PHP, Swift, Dart, Elixir, Erlang, Haskell, Scala, Clojure, Lua, Perl, R, Julia, MATLAB, Nim, OCaml, F#, Crystal, Groovy, COBOL, VHDL, Zig, Move, Cairo, Vyper, Solidity, Objective-C, Bash, PowerShell, SQL, HTML, GraphQL, gRPC, Protobuf, and more. Infrastructure coverage: Terraform, Kubernetes, Helm, Docker, Ansible, Chef, Puppet, CloudFormation, Bicep, Serverless, Nginx, Apache, OpenAPI, Azure, GCP — plus specialized rulesets for insecure randomness, race conditions, and supply chain attacks. ### How rules work Each rule is a YAML definition with regex patterns, severity, CWE/OWASP mappings, and remediation guidance: # rules/javascript.yaml - id: js-eval-injection languages: [javascript, typescript] patterns: - regex: '\beval\s*\(' severity: high description: "Use of eval() can execute arbitrary code" remediation: "Use JSON.parse() for data parsing or safer alternatives" cwe: "CWE-94" owasp: "A03:2021" ### Writing custom rules Drop any `.yaml` file into the `rules/` directory and SentryQ automatically loads it: # rules/my-company-rules.yaml - id: acme-hardcoded-jwt languages: [javascript, typescript, python, go] patterns: - regex: '(?i)(jwt_secret|jwt_key|secret_key)\s*=\s*["\'][a-zA-Z0–9_\-\.]{10,}["\']' severity: critical description: "Detected a hardcoded JWT secret" remediation: "Use environment variables (e.g., process.env.JWT_SECRET)" cwe: "CWE-798" owasp: "A07:2021" ### Language-aware rule loading SentryQ doesn't load all 12,400+ rules for every scan. It first walks the target directory to detect which languages are present, then loads only the relevant rule files — dramatically reducing memory usage and startup time: // config/rule_loader.go rules, err := config.LoadRulesForLanguages(rulesDir, detectedLangs) 4. Engine — Tree-Sitter AST Analysis Pattern matching catches syntactic patterns. AST analysis catches semantic vulnerabilities — dangerous function calls, insecure assignments, and structural code flaws that regex can't express. SentryQ uses the Tree-Sitter parsing library to build full Abstract Syntax Trees for Python, JavaScript/TypeScript, Java, and Kotlin. What the AST engine catches: Python: eval() / exec() / compile() arbitrary code execution (CWE-94), SQL injection via string formatting in cursor.execute() (CWE-89), command injection via os.system() with user input (CWE-78), SSTI via render_template_string() , hardcoded secrets with entropy analysis, and PII logging. JavaScript/TypeScript: eval() / Function() constructor (CWE-94), XSS via innerHTML assignment (CWE-79), hardcoded secrets with high-entropy detection. Java: SQL injection via Statement.executeQuery() with string concatenation, command injection via Runtime.getRuntime().exec() (CWE-78), insecure deserialization via ObjectInputStream.readObject() (CWE-502), XSS via getWriter().print(getParameter()) , weak cipher usage (ECB mode, DES) (CWE-327). Kotlin/Android: Insecure WebView with javaScriptEnabled = true , SQL injection via rawQuery() with string interpolation, sensitive data in Log.* statements, implicit Intents interceptable by malicious apps, world-readable S haredPreferences . ### Reachability cache The AST engine also builds a global index of every identifier and string literal in the codebase. This cache powers the SCA reachability analysis that determines whether a vulnerable dependency is actually *used* in your code: // scanner/ast-analyzer.go func (aa *ASTAnalyzer) IsFunctionReachable(targetDir, functionOrLibName string) bool { aa.BuildReachabilityCache(targetDir) return aa.reachabilityCache[strings.ToLower(functionOrLibName)] } ## 5. Engine #3 — Taint-Flow Dataflow Tracking This is where SentryQ differentiates itself from naive scanners. The taint analyzer performs inter-procedural dataflow analysis — tracking user-controlled input from sources (where data enters) through propagation (aliases, concatenation, method chains, string interpolation) to sinks (dangerous functions). ### How taint tracking works Step 1 — Identify Sources (user input entry points): The engine recognizes taint sources across 11 languages: - Python: request.args , request.form , input() , sys.argv - JavaScript: req.params , req.query , document.cookie , window.location - PHP: $_GET, $_POST, $_REQUEST, $_COOKIE - Java: request.getParameter(), request.getHeader(), Scanner(System.in) - Go: r.URL.Query(), r.FormValue(), os.Args, chi.URLParam() - Ruby: params[] , request.env , ENV[] - And more for C#, Swift, Dart… Step 2 — Track Propagation across four vectors: Direct alias: userInput = req.query.name Method chain: cleaned = userInput.trim() String concatenation: query = "SELECT * FROM " + userInput String interpolation: query = f"SELECT * FROM {userInput}" Each propagation hop is tracked with full path metadata, up to a configurable maximum of 10 hops (preventing infinite loops from circular aliases like a=b; b=a ). Step 3 — Check Sinks (dangerous operations): The engine maintains sink definitions for each language — SQL execution, shell commands, eval, innerHTML, deserialize, SSRF-triggering HTTP calls, etc. Step 4 — Apply Sanitizer Awareness: Before flagging a taint flow, the engine checks for sanitizers: escaping functions ( escape() , htmlspecialchars() , encodeURIComponent() ), parameterized queries (`?` placeholders, $1 , bindParam() ), type casting ( parseInt() , Number() , strconv.Atoi() ), ORM methods ( .where(?) , .filter() ), template auto-escaping ( html/template , markupsafe.escape() ), and validation guards. Step 5 — Graduated Confidence Scoring: - Source-to-sink distance > 100 lines: −15% confidence - More than 3 alias hops: −10% confidence - Guard clause detected between source and sink: confidence drops to 25% (effectively suppressed) ### Example: A real taint flow finding Taint Flow: SQL Injection File: app/routes/users.py Line: 47 Severity: critical Confidence: 0.90 User input 'username' (tainted on line 12, 2 hops) flows to SQL on line 47 without sanitization. Exploit Path: Line 12: Source 'username' initialized (request.form['username']) Line 23: Propagated to 'clean_name' (method chain — .strip()) Line 47: Reaches sink 'cursor.execute()' Remediation: Use parameterized queries or prepared statements. Never concatenate user input into SQL queries. 6. Engine — Entropy-Based Secret Detection Pattern matching alone catches known secret formats (AWS keys start with AKIA , GitHub tokens with ghp_ ). But what about custom secrets — internal API keys, database passwords, or JWT signing secrets that don't follow any known format? SentryQ's secret detector combines 14+ regex patterns with Shannon entropy analysis to catch both known and unknown secrets. Known patterns detected: - AWS Access Key ( AKIA[0–9A-Z]{16} ) — e.g., AKIAIOSFODNN7EXAMPLE - GitHub PAT ( ghp_[a-zA-Z0–9]{36} ) - Stripe Key ( sk_live_[a-zA-Z0–9]{24,} ) - Private Keys ( — — -BEGIN.*PRIVATE KEY — — - ) — RSA/EC/OPENSSH - JWT Token — three-segment Base64 ( eyJ…eyJ… ) - Google API Key ( AIza[0–9A-Za-z_-]{35} ) - Slack Token ( xox[baprs]-… ) - Generic hardcoded password ( password\s*=\s*"…" ) ### Entropy analysis For strings that don't match known patterns, SentryQ calculates Shannon entropy — a measure of randomness. Real secrets tend to have entropy > 4.5 bits/character, while English text averages ~3.5: // scanner/secret_detector.go func calculateEntropy(s string) float64 { freq := make(map[rune]int) for _, c := range s { freq[c]++ } entropy := 0.0 length := float64(len(s)) for _, count := range freq { p := float64(count) / length entropy -= p * math.Log2(p) } return entropy } ### Base64/Hex decoding SentryQ also attempts to decode Base64 and hex-encoded strings before analysis. This catches secrets that have been obfuscated through encoding: // Try base64 decode, then check entropy of decoded content if decoded, err := base64.StdEncoding.DecodeString(s); err == nil { if hasHighEntropy(string(decoded)) { // Flag as encoded secret } } ### Smart exclusions The detector automatically skips files larger than 2 MB (avoids RAM spikes on minified bundles), test files ( _test.go, .spec.js, __tests__/ ), binary files, and common non-source directories ( node_modules , vendor , .git , __pycache__ ). 7. Engine — Supply-Chain & Dependency Auditing SentryQ scans your dependency manifests against the OSV (Open Source Vulnerabilities) database — Google's comprehensive vulnerability database covering npm, PyPI, Go, Maven, RubyGems, Packagist, and more. ### Two-tier approach Tier 1 — osv-scanner CLI (preferred): If Google's official osv-scanner binary is in your PATH, SentryQ delegates to it for the most accurate results with full lockfile support. Tier 2 — Built-in parser + OSV API (fallback): If osv-scanner isn't installed, SentryQ's built-in parsers extract dependencies from all major manifest formats: - package.json (npm) — JSON dependencies + devDependencies - yarn.lock (npm) — line-by-line v1 parser - pnpm-lock.yaml (npm) — regex-based extraction - requirements.txt (PyPI) — `==`, `>=`, `<=` version specifiers - go.mod (Go) — require block parser - pom.xml (Maven) — XML regex extraction - build.gradle (Maven) — ` mplementation / api declaration parser - composer.json (Packagist) — JSON parser - Gemfile.lock (RubyGems) — Specs section parser Each dependency is then queried against the OSV API with exponential backoff (1s → 2s → 4s + jitter) for rate-limit resilience. ### Reachability-aware SCA Here's what makes SentryQ's SCA different: after identifying a vulnerable dependency, it checks whether your code actually uses that dependency by querying the AST reachability cache: isReachable := analyzer.IsFunctionReachable(targetDir, dep.Name) if !isReachable { issueName = "[UNREACHABLE] " + issueName severity = "low" description += "\nREACHABILITY: The AST Analyzer could not find any active invocations of this library. It may be an unused transitive dependency." } An unreachable CVE in an unused transitive dependency is not the same risk as an actively-exploited library in your hot path. SentryQ makes this distinction automatically. 8. Engine — Container & Kubernetes Security ### Dockerfile linting SentryQ parses `Dockerfile` and `*.dockerfile` files and checks for: - `:latest` tag (Medium) — unpredictable builds - `USER root` / `USER 0` (High) — running as root violates least privilege - Missing `USER` directive (High) — container defaults to root - Missing `HEALTHCHECK` (Low) — orchestrator can't monitor health - Secrets in `ENV`/`ARG` (Critical) — secrets baked into image layers - Sensitive port exposure (22, 3389, 23) (High) — SSH/RDP/Telnet in containers Kubernetes manifest auditing For YAML files containing apiVersion: and kind: , SentryQ checks for privileged: true (container with full host capabilities — Critical) and allowPrivilegeEscalation: true (container can gain more privileges — High). Trivy integration When Trivy is installed, SentryQ automatically runs `trivy image` against base images extracted from Dockerfiles, with a 2-minute timeout per image to prevent hanging on unreachable registries. 9. The AI Layer — Chain-of-Thought Validation This is the core innovation. Every finding from the static engines passes through an AI validator that acts as a Senior Security Code Reviewer. How validation works For each finding, SentryQ sends the AI: 1. The vulnerability details (issue name, severity, CWE, description) 2. The full file content (for files ≤ 500 lines) or ±150 lines of context 3. A test-file indicator (if the file matches test patterns) 4. Cross-file context (related imports, callers) The AI is prompted to perform structured analysis: VALIDATION STEPS: 1. TAINT ANALYSIS: Map from Source to Sink. Is there an unvalidated path? 2. CONFIGURATION & SECRETS: Hardcoded secrets DON'T require user input. 3. CONFIGURATION FILE RULE: .env, .yaml, .properties files with secrets are ALWAYS true positives. 4. FILTER ANALYSIS: Is sanitization present? Could it be insufficient? 5. ENVIRONMENT CHECK: Dev-only tool or real production vulnerability? 6. IMPACT ESTIMATION: What is the worst-case scenario? The AI returns a structured JSON verdict: { "is_true_positive": true, "confidence": 0.92, "explanation": "User input from request.form flows directly to cursor.execute() without parameterization.", "suggested_fix": "Use parameterized queries with ? placeholders.", "fixed_code_snippet": "cursor.execute('SELECT * FROM users WHERE id = ?', (user_id,))", "exploit_poc": "curl -X POST /login -d 'username=admin%27%20OR%201=1 - '", "severity_adjustment": "critical" } ### AI Discovery — Finding what rules miss Beyond validation, SentryQ has a separate AI Discovery Engine that reads source files through a sliding window (2000 lines per chunk, 50-line overlap) and asks the AI to find vulnerabilities that no static rule would catch: - Business logic flaws - IDOR (Insecure Direct Object Reference) - Race conditions - Prototype pollution - SSRF via internal network access - Missing authorization checks The discovery engine includes language-specific prompting — Go-specific checks for unsafe pointer usage and concurrent map access, Python-specific checks for pickle deserialization, Java-specific checks for XXE and Log4Shell patterns. ### Agentic search loop When the AI identifies a vulnerability but needs more context, it can request related files. SentryQ implements a 2-iteration agentic loop: 1. AI analyzes file A, returns "needs_context": ["utils/auth.go"] 2. SentryQ fetches utils/auth.go and re-prompts with the additional context 3. AI provides final analysis with cross-file understanding Path traversal protection ensures the AI can only request files within the scan directory. 10. The Judge Engine — Multi-Report Consensus When running in Ensemble Mode, SentryQ produces two independent reports: - Report A: Static analysis findings (pattern + AST + taint + secrets) - Report B: AI discovery findings The Judge Engine acts as a Supreme Security Auditor that merges these reports using five rules: 1. Findings on the same file ± 5 lines with the same vulnerability type → Deduplicate (keep the richer description) 2. Test files, comments, dead code → Drop as false positives 3. Safe patterns (parameterized queries, textContent , secure RNGs) → Drop 4. Unique to one scanner and valid → Keep 5. Combined evidence suggests severity change → Adjust The Judge processes findings in batches of 5 to prevent LLM timeouts, with a 15-minute timeout per batch. 11. False Positive Suppression — The 5-Layer Defense SentryQ has five independent layers to eliminate false positives: Layer 1: Static FP Suppressor — Code-context pattern matching that recognizes safe patterns. Examples: weak random suppressed when crypto.randomBytes or secrets.token_hex is used; SQL injection suppressed when parameterized queries (`?`, `$1`, `.prepare()`) are present; hardcoded secret suppressed when the value comes from process.env.* or os.getenv() . Layer 2: Taint Sanitizer Awareness — The taint engine tracks 9 categories of sanitizers (escaping, parameterized queries, type casting, ORM methods, template auto-escaping, safe output functions, validation guards) and clears taint state when sanitization is detected. Layer 3: AI Chain-of-Thought Validation — Each finding is individually reviewed by the local LLM with full code context. Layer 4: Confidence Calibrator — A learning system that tracks historical AI accuracy per severity level. After 5+ validations it calibrates future confidence scores: calibrated = (rawConfidence × 0.70) + (historicalAccuracy × 0.30) Stats persist across scans in ~/.sentryq/.scanner-ai-stats.json . Layer 5: ML FP Reducer — A similarity-based historical filter that learns from past scan feedback. If a specific rule ID + file extension + severity combination was historically flagged as false positive ≥ 80% of the time, future identical matches are automatically dropped. 12. Reachability Analysis & Call Graph SentryQ builds a simplified call graph of your entire codebase by: 1. Scanning for function definitions across Go, Python, JS, Java, Kotlin, C# 2. Tracking function calls within each function body 3. Identifying entry points (main, init, HTTP handlers, route decorators, export default) 4. Performing DFS reachability from entry points to vulnerable functions Findings in unreachable code (dead functions never called from any entry point) are downgraded to info severity, marked as [UNREACHABLE] in the description, and have their confidence reduced by 70%. 13. MITRE ATT&CK Threat Intelligence Every finding is automatically enriched with MITRE ATT&CK technique mappings — entirely offline, no API calls: - SQL Injection → T1190 (Exploit Public-Facing Application) — Initial Access - Command Injection → T1059 (Command and Scripting Interpreter) — Execution - XSS → T1189 (Drive-by Compromise) — Initial Access - Hardcoded Credentials → T1078 (Valid Accounts) — Persistence, Privilege Escalation - Path Traversal → T1083 (File and Directory Discovery) — Discovery - SSRF → T1190 (Exploit Public-Facing Application) — Initial Access - Deserialization → T1190 (Exploit Public-Facing Application) — Initial Access 14. Risk Scoring & Priority Matrix ### Aggregate Risk Score (0–100) SentryQ calculates a weighted risk score: - Critical finding: +10 points - High finding: +5 points - Medium finding: +2 points - Low finding: +0.5 points Score ≥ 75 = Critical Risk | ≥ 50 = High Risk | ≥ 25 = Medium Risk | < 25 = Low Risk ### Multi-Engine Trust Score Each finding gets a trust score combining the base confidence from the detecting engine (0–100), plus +15 points per additional confirming engine, and +10 points for AI validation confirmation (capped at 100). ### Priority Matrix - P0 — Critical + AI confirmed → Fix immediately - P1 — Critical (unvalidated) or High + AI confirmed → Fix this sprint - P2 — High (unvalidated) or Medium + AI confirmed → Fix next sprint - P3 — Everything else → Fix when possible 15. Reporting — SARIF, HTML, CSV, PDF Every scan generates four report formats simultaneously: HTML Report — Standalone, self-contained report with embedded CSS. Includes severity breakdown charts, finding cards with code snippets, and remediation guidance. SARIF — Static Analysis Results Interchange Format. Native integration with GitHub Security Tab, GitLab SAST, and Azure DevOps. Includes CWE IDs, OWASP categories, and rule metadata. CSV — For spreadsheet-based triage workflows or importing into ticketing systems. PDF — Professional report with risk score summary, priority matrix, and detailed findings. Suitable for executive reviews and compliance documentation. 16. Installation & Quick Start ### Prerequisites Linux: Go 1.24+, Node.js 18+, Ollama (optional, for AI) macOS: brew install go nodejs ollama Windows: Go 1.24+, Node.js 18+, Ollama 5-Minute Setup # 1. Clone git clone https://github.com/Gauravjha68535/sentryQ.git cd sentryQ # 2. Build (Linux/macOS) chmod +x build.sh && ./build.sh # 3. Pull the default AI model (optional) ollama pull qwen2.5-coder:7b # 4. Run ./sentryq # Open http://localhost:5336 Windows: REM build.bat handles everything automatically .\build.bat .\sentryq.exe Zero-CGO binary SentryQ is built with CGO_ENABLED=0 — the binary has zero C dependencies. No GCC, no MinGW, no compilation headaches. It runs natively on any platform without external libraries. 17. Usage Examples — Real-World Workflows ### Interactive Web Dashboard # Start with defaults ./sentryq # Custom port ./sentryq --port 8080 # Remote Ollama server ./sentryq --ollama-host 192.168.1.10:11434 Navigate to http://localhost:5336 , click New Scan, choose Upload / Git Clone / Local Path, and watch findings stream in via WebSocket. Headless CLI Scan # Quick scan - static only, no AI ./sentryq /path/to/my-project # Full scan with AI validation ./sentryq /path/to/my-project -model qwen2.5-coder:7b Scanning a Git Repository From the web dashboard, paste any Git URL (HTTPS or SSH) and SentryQ will: 1. Clone with ` — depth 1` (5-minute timeout) 2. Run the full analysis pipeline 3. Auto-cleanup the cloned directory after scan REST API # Upload files for scanning curl -X POST http://localhost:5336/api/scan/upload \ -F "@app.py">[email protected]" \ -F "config={\"enableAI\": true, \"aiModel\": \"qwen2.5-coder:7b\"}" # Clone and scan a repo curl -X POST http://localhost:5336/api/scan/git \ -H "Content-Type: application/json" \ -d '{"url": "https://github.com/example/app"}' # Get findings curl http://localhost:5336/api/scan/{scanID}/findings # Download SARIF report curl -O http://localhost:5336/api/scan/{scanID}/report/sarif 18. CI/CD Integration — GitHub Actions SentryQ generates SARIF natively, so CI/CD integration is straightforward: # .github/workflows/sentryq-scan.yml name: "SentryQ Security Scan" on: push: branches: ["main"] pull_request: branches: ["main"] jobs: sentryq: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.24' - name: Build SentryQ run: | git clone https://github.com/Gauravjha68535/sentryQ.git /tmp/sentryQ cd /tmp/sentryQ && sh build.sh - name: Run SentryQ Headless Scan run: /tmp/sentryQ/sentryq ./ - name: Upload SARIF to GitHub Security uses: github/codeql-action/upload-sarif@v3 with: sarif_file: report.sarif if: always() 19. Configuration Deep Dive Settings are stored at ~/.sentryq/settings.json (owner-only, mode 0600). You can configure via the Settings page in the UI or environment variables. Key settings: - ollama_host — Ollama server host:port (default: `localhost:11434`) - default_model — LLM for Chain-of-Thought validation (auto-detected from installed models) - ai_provider — ollama for local, openai for any OpenAI-compatible endpoint, custom for vLLM/LM Studio - `custom_api_url` — Custom endpoint URL - `custom_api_key` — API key for custom provider Environment variables: - PORT — Override default port 5336 - OLLAMA_HOST — Remote Ollama host:port (e.g., OLLAMA_HOST=10.0.0.5:11434 ) - SENTRYQ_CUSTOM_API_KEY — Inject API key without writing to disk - AI_DEBUG — Print raw AI output for debugging Recommended Models - qwen2.5-coder:7b (~4 GB VRAM, fast) — General purpose, recommended default - qwen2.5-coder:14b (~8 GB VRAM, medium) — Complex codebases - deepseek-coder:6.7b (~4 GB VRAM, fast) — Alternative to Qwen - llama3.1:8b (~5 GB VRAM, medium) — General reasoning 20. Architecture Decisions & Engineering Trade-offs Why Go? Go gives us a compiled binary with no runtime dependencies, goroutines for concurrent file walking and analysis, seamless cross-platform builds for Linux/macOS/Windows from a single source tree, and `CGO_ENABLED=0` for a pure-Go binary with zero native library dependencies. Why sequential AI validation? We initially ran AI validation concurrently. On consumer GPUs (≤ 8 GB VRAM), this caused immediate VRAM thrashing — LLM context windows competed for memory and the system froze. We settled on sequential validation with a circuit breaker (3 consecutive errors → skip remaining validations). Why not use Semgrep for everything? Semgrep is excellent and SentryQ integrates with it as an optional deep-scan engine. But it requires Python, adds installation complexity, and its rule format differs from our YAML schema. SentryQ's built-in pattern engine + AST + taint analysis covers the vast majority of cases without external dependencies. Why SQLite for scan storage? We use modernc.org/sqlite — a pure-Go SQLite implementation. No CGO needed. Scan history, findings, and triage status persist across restarts. Auto-cleanup removes reports older than 48 hours. 21. Performance Benchmarks - Pattern scan speed (10K files): ~8 seconds - AST analysis (1K source files): ~3 seconds - Taint analysis (1K source files): ~5 seconds - Secret detection (10K files): ~4 seconds - AI validation per finding: 10–60 seconds (model-dependent) - Full ensemble scan (medium project): 10–30 minutes - Binary size: ~25 MB - Memory usage (static only): ~100 MB 22. SentryQ vs. Traditional Tools Local AI validation: SentryQ ✅ | SonarQube ❌ | Snyk ❌ | Semgrep ❌ | Bandit ❌ Zero cloud dependency: SentryQ ✅ | SonarQube ❌ | Snyk ❌ | Semgrep ✅ | Bandit ✅ FP reduction: SentryQ ~90% | SonarQube ~30% | Snyk ~40% | Semgrep ~35% | Bandit ~20% Languages supported: SentryQ 67+ | SonarQube 30+ | Snyk 10+ | Semgrep 30+ | Bandit Python only Taint analysis: SentryQ ✅ (11 languages) | SonarQube ✅ | Snyk ❌ | Semgrep ✅ | Bandit ❌ SCA (dependency auditing): SentryQ ✅ (OSV) | SonarQube ✅ | Snyk ✅ | Semgrep ❌ | Bandit ❌ Container scanning: SentryQ ✅ | SonarQube ❌ | Snyk ✅ | Semgrep ❌ | Bandit ❌ MITRE ATT&CK mapping: SentryQ ✅ | SonarQube ❌ | Snyk ❌ | Semgrep ❌ | Bandit ❌ Single binary, no install: SentryQ ✅ | SonarQube ❌ | Snyk ❌ | Semgrep ❌ | Bandit ❌ 23. FAQ Does SentryQ work without Ollama / without AI? Yes. All static engines (pattern, AST, taint, secrets, SCA, container) run independently. AI is an optional enhancement layer for false positive reduction and deep discovery. Is my source code sent to the cloud? No. When using Ollama (default), everything runs on localhost. If you configure an external OpenAI-compatible endpoint, code context is sent to that endpoint — SentryQ makes this explicit in settings. What are the minimum system requirements? Static-only scanning: 4 GB RAM, any CPU. With AI: 8 GB+ RAM, GPU with 4 GB+ VRAM recommended. Storage: ~5 GB for models. Can I use SentryQ with cloud LLMs like GPT-4 or Claude? Yes. Set ai_provider to openai or custom and provide your API URL and key. SentryQ supports any OpenAI-compatible chat/completions endpoint. How do I add support for a new language? Create a YAML rule file in the `rules/` directory. SentryQ automatically discovers and loads it on the next scan — no code changes needed. Does SentryQ support monorepos? Yes. The file walker handles arbitrary directory depth and size. Language-aware rule loading ensures only relevant rules are loaded for the detected languages. 24. Conclusion The era of manually triaging 500-page false-positive reports is over. SentryQ combines the speed of Go-powered concurrent static analysis, the precision of AST and taint-flow tracking, the breadth of 12,400+ rules across 67+ languages, and the intelligence of local Chain-of-Thought AI — all in a single binary that never sends your code to the cloud. git clone https://github.com/Gauravjha68535/sentryQ.git cd sentryQ && ./build.sh && ./sentryq Star SentryQ on GitHub → https://github.com/Gauravjha68535/SentryQ #open-source #bug-bounty #cybersecurity #artificial-intelligence #ai Reporting a Problem Sometimes we have problems displaying some Medium posts. If you have a problem that some images aren't loading - try using VPN. Probably you have problem with access to Medium CDN (or fucking Cloudflare's bot detection algorithms are blocking you).