Trending-skills ai-scanner-garak
AI model safety scanner built on NVIDIA garak for testing LLMs against 179 security probes across 35 vulnerability families
git clone https://github.com/Aradotso/trending-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/Aradotso/trending-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/ai-scanner-garak" ~/.claude/skills/aradotso-trending-skills-ai-scanner-garak && rm -rf "$T"
skills/ai-scanner-garak/SKILL.mdAI Scanner (0din-ai/ai-scanner)
Skill by ara.so — Daily 2026 Skills collection.
AI Scanner is an open-source Ruby on Rails web application for AI model security assessments, wrapping NVIDIA garak with a multi-tenant UI, scheduling, PDF reports, and SIEM integration. It runs 179 community probes across 35 vulnerability families aligned with the OWASP LLM Top 10.
Installation
Quick Install (Docker)
curl -sL https://raw.githubusercontent.com/0din-ai/ai-scanner/main/scripts/install.sh | bash
Manual Install
curl -O https://raw.githubusercontent.com/0din-ai/ai-scanner/main/dist/docker-compose.yml curl -O https://raw.githubusercontent.com/0din-ai/ai-scanner/main/.env.example cp .env.example .env
Edit
.env with required values:
# Generate a secure key openssl rand -hex 64 # .env minimum required values SECRET_KEY_BASE=<output_of_above_command> POSTGRES_PASSWORD=<your_secure_db_password>
docker compose up -d
Access at
http://localhost — default credentials: admin@example.com / password.Change the default password immediately after first login.
Configuration (.env)
# Required SECRET_KEY_BASE=<64-byte-hex> POSTGRES_PASSWORD=<strong-password> # Optional: custom port PORT=8080 # Optional: SIEM integration SPLUNK_HEC_URL=https://splunk.example.com:8088/services/collector SPLUNK_HEC_TOKEN=$SPLUNK_HEC_TOKEN RSYSLOG_HOST=syslog.example.com RSYSLOG_PORT=514 # Optional: email SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USERNAME=$SMTP_USERNAME SMTP_PASSWORD=$SMTP_PASSWORD
Core Concepts
| Concept | Description |
|---|---|
| Target | An AI system to test — API-based LLM or browser-based chat UI |
| Probe | A single attack test (e.g., prompt injection, data leakage) |
| Scan | A run of selected probes against a target |
| ASR | Attack Success Rate — percentage of probes that succeeded |
| Organization | Tenant boundary; users and scans are scoped per org |
Setting Up a Target
Targets define what you're scanning. Two types:
API-based LLM Target (e.g., OpenAI-compatible endpoint):
# In Rails console or via UI — representative model target = Target.create!( name: "Production GPT-4", target_type: "api", api_endpoint: "https://api.openai.com/v1/chat/completions", api_key: ENV["OPENAI_API_KEY"], model_name: "gpt-4", organization: current_organization )
Browser-based Chat UI Target:
target = Target.create!( name: "Internal Chatbot UI", target_type: "browser", url: "https://chatbot.internal.example.com", organization: current_organization )
Running a Scan
Via UI
- Navigate to Targets → select your target
- Click New Scan
- Select probe families or individual probes
- Click Run Scan
Via Rails Console
# On-demand scan with specific probe families scan = Scan.create!( target: target, probe_families: ["prompt_injection", "data_leakage", "insecure_output"], organization: current_organization ) ScanJob.perform_later(scan.id)
Scheduled Recurring Scan
# Weekly scan every Monday at 2am scheduled_scan = ScheduledScan.create!( target: target, probe_families: ["prompt_injection", "jailbreak"], cron_expression: "0 2 * * 1", organization: current_organization )
Probe Families (35 total, aligned to OWASP LLM Top 10)
Key probe families available:
# List all available probe families Garak::ProbeRegistry.families # => ["prompt_injection", "jailbreak", "data_leakage", "insecure_output", # "supply_chain", "sensitive_info", "excessive_agency", "overreliance", # "model_theft", "malicious_plugins", ...] # Get probes within a family Garak::ProbeRegistry.probes_for("prompt_injection") # => 179 total probes across all families
Viewing Results
Attack Success Rate (ASR)
scan = Scan.find(scan_id) puts scan.asr_score # => 0.23 (23% attack success rate) puts scan.status # => "completed" puts scan.probe_results.count # => 47 # Per-probe breakdown scan.probe_results.each do |result| puts "#{result.probe_name}: #{result.passed? ? 'SAFE' : 'VULNERABLE'}" puts " Attempts: #{result.attempt_count}" puts " ASR: #{result.asr_score}" end
Trend Tracking
# Compare ASR across scan runs for a target target.scans.completed.order(:created_at).map do |scan| { date: scan.created_at, asr: scan.asr_score } end
PDF Report Export
# Generate PDF report for a scan scan = Scan.find(scan_id) pdf_path = ReportExporter.export_pdf(scan) # Includes: executive summary, per-probe results, per-attempt drill-down
Via UI: Navigate to a completed scan → Export PDF.
SIEM Integration
Splunk
# config/initializers/siem.rb SiemIntegration.configure do |config| config.provider = :splunk config.splunk_hec_url = ENV["SPLUNK_HEC_URL"] config.splunk_hec_token = ENV["SPLUNK_HEC_TOKEN"] config.forward_on_completion = true end
Rsyslog
SiemIntegration.configure do |config| config.provider = :rsyslog config.rsyslog_host = ENV["RSYSLOG_HOST"] config.rsyslog_port = ENV["RSYSLOG_PORT"].to_i end
Multi-Tenant Organization Management
# Create a new organization org = Organization.create!(name: "Security Team Alpha") # Invite a user user = User.invite!( email: "analyst@example.com", organization: org, role: "analyst" # roles: "admin", "analyst", "viewer" ) # Data is encrypted at rest per organization org.encryption_key # => managed automatically
Development Setup
git clone https://github.com/0din-ai/ai-scanner.git cd ai-scanner cp .env.example .env.development # Install dependencies bundle install # Database setup rails db:create db:migrate db:seed # Install garak (Python dependency) pip install garak # Start development server bin/dev
Running Tests
# Full test suite bundle exec rspec # Specific area bundle exec rspec spec/models/scan_spec.rb bundle exec rspec spec/jobs/scan_job_spec.rb # Lint bundle exec rubocop
Common Patterns
Testing a New LLM Before Deployment
# Comprehensive pre-deployment scan target = Target.create!( name: "New Model v2 - Pre-deploy", target_type: "api", api_endpoint: ENV["NEW_MODEL_ENDPOINT"], api_key: ENV["NEW_MODEL_API_KEY"], model_name: "new-model-v2", organization: current_organization ) # Run all 35 probe families scan = Scan.create!( target: target, probe_families: Garak::ProbeRegistry.families, organization: current_organization ) ScanJob.perform_now(scan.id) if scan.reload.asr_score > 0.15 puts "WARNING: ASR #{scan.asr_score} exceeds threshold. Review before deploying." else puts "PASS: Model meets security threshold." end
Using the Mock LLM for Testing Scanner Setup
The built-in Mock LLM lets you validate your scanner configuration without hitting real APIs:
target = Target.create!( name: "Mock LLM", target_type: "mock", organization: current_organization ) # Run a quick scan to verify everything works end-to-end
Webhook on Scan Completion
# config/initializers/scan_hooks.rb ActiveSupport::Notifications.subscribe("scan.completed") do |_, _, _, _, payload| scan = Scan.find(payload[:scan_id]) if scan.asr_score > 0.20 SlackNotifier.alert( channel: "#security-alerts", message: "High ASR detected: #{scan.asr_score} on #{scan.target.name}" ) end end
Docker Compose Production Tips
# docker-compose.override.yml — production additions services: web: environment: RAILS_ENV: production FORCE_SSL: "true" labels: - "traefik.enable=true" - "traefik.http.routers.scanner.rule=Host(`scanner.example.com`)" - "traefik.http.routers.scanner.tls.certresolver=letsencrypt"
# Upgrade docker compose pull docker compose up -d docker compose exec web rails db:migrate
Troubleshooting
| Problem | Solution |
|---|---|
| Scan stuck in "running" | Check — garak Python process may have crashed |
error on start | Run and set in |
| Can't connect to target API | Verify API key env var is set; check firewall allows outbound from container |
| Browser target scan fails | Ensure Playwright/Chrome is available in the worker container |
| PDF export blank | Check is installed in the web container |
| SIEM not receiving events | Verify includes full path |
# View all service logs docker compose logs -f # Check worker specifically (runs garak) docker compose logs -f worker # Rails console for debugging docker compose exec web rails console # Check garak is working docker compose exec worker python -c "import garak; print(garak.__version__)"
Key Files (for Contributors)
app/ models/ scan.rb # Core scan model, ASR calculation target.rb # Target types and validation probe_result.rb # Per-probe result storage jobs/ scan_job.rb # Async job that invokes garak services/ garak_runner.rb # Ruby wrapper around garak CLI report_exporter.rb siem_integration.rb lib/ garak/ probe_registry.rb # 179 probes, 35 families dist/ docker-compose.yml # Production compose file scripts/ install.sh # One-line installer