diff --git a/dsgai_scanner_tool/README.md b/dsgai_scanner_tool/README.md index cbe4ca6..239ce78 100644 --- a/dsgai_scanner_tool/README.md +++ b/dsgai_scanner_tool/README.md @@ -1,455 +1,340 @@ -# GenAI Data Security Risks (DSGAI) Tool โ€” OWASP GenAI Data Security Compliance Report +
-[![OWASP](https://img.shields.io/badge/OWASP-GenAI%20Data%20Security-blue)](https://genai.owasp.org/initiative/data-security/) -[![Framework](https://img.shields.io/badge/Framework-DSGAI%202026%20v1.0-purple)](https://genai.owasp.org/resource/owasp-genai-data-security-risks-mitigations-2026/) -[![Skill Version](https://img.shields.io/badge/Skill-v0.3-green)](./CHANGES_v0.3.md) -[![License](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey)](https://creativecommons.org/licenses/by-sa/4.0/) +# ๐Ÿ›ก๏ธ DSGAI Scanner -Scans GenAI and agentic codebases against the **OWASP GenAI Data Security Risks and Mitigations 2026 (v1.0)** โ€” all 21 DSGAI risk controls across the GenAI data lifecycle. A **deterministic CLI** (`cli/dsgai_scan.py`) owns pattern matching so results are reproducible; the **Claude Code skill** orchestrates and writes the report. The report is **strict-by-default redacted** (file IDs + line numbers only, value-bearing matches never shown) โ€” designed to minimize disclosure. It is not automatically public-safe: the existence and location of failing controls is itself information, so handle it like any security assessment. +**OWASP GenAI Data Security compliance scanning for AI & agentic codebases** -Part of the [OWASP GenAI Data Security Initiative](https://genai.owasp.org/initiative/data-security/). +Audits your GenAI app against all **21 controls** of the [OWASP GenAI Data Security Risks & Mitigations 2026](https://genai.owasp.org/resource/owasp-genai-data-security-risks-mitigations-2026/) framework. A **deterministic engine** owns the pattern matching, so results are reproducible and secrets never leave your machine โ€” the LLM only orchestrates and writes prose. ---- - -## How It Works - -```mermaid -flowchart LR - Dev([Developer]) -->|/dsgai_scanner_tool| Skill[DSGAI Skill] - Repo[(Your GenAI Repo)] --> Skill +[![OWASP](https://img.shields.io/badge/OWASP-GenAI%20Data%20Security-1a4b8c?logo=owasp&logoColor=white)](https://genai.owasp.org/initiative/data-security/) +[![Framework](https://img.shields.io/badge/Framework-DSGAI%202026%20v1.0-6d28d9)](https://genai.owasp.org/resource/owasp-genai-data-security-risks-mitigations-2026/) +[![Version](https://img.shields.io/badge/version-0.3.0-16a34a)](./CHANGES_v0.3.md) +[![Self-test](https://img.shields.io/github/actions/workflow/status/GenAI-Security-Project/GenAI-Data-Security-Initiative/scanner-selftest.yml?branch=main&label=self-test)](../.github/workflows/scanner-selftest.yml) +[![SARIF](https://img.shields.io/badge/output-SARIF%202.1.0-0b7285)](#cicd-and-code-scanning) +[![License](https://img.shields.io/badge/license-CC%20BY--SA%204.0-lightgrey)](#license) - Skill --> Detect{Step 0
GenAI signals?} - Detect -->|No| Minimal[Minimal report
21 ร— NOT APPLICABLE] - Detect -->|Yes| CVE[Step 0.5
Live CVE enrichment] +[Quick start](#quick-start) ยท [How it works](#how-it-works) ยท [Features](#features) ยท [Usage](#usage) ยท [CI/CD](#cicd-and-code-scanning) ยท [The report](#the-report) ยท [Contributing](#contributing) - CVE -.->|package + version
only| Sources((OSV ยท NVD
GitHub Advisory
AVID)) - - CVE --> Scan[Step 2
21 parallel scans] - Scan --> Class{Step 3
Classify} - Class --> Report[DSGAI-report.html
self-contained
STRICT-redacted by default] - - Report --> Auditor([Auditor / GRC]) - Report --> Ticket([Jira / Backlog]) - Report --> CICD([CI/CD artifact]) - - style Skill fill:#7c3aed,color:#fff - style Report fill:#16a34a,color:#fff - style Minimal fill:#6b7280,color:#fff - style Sources fill:#e0e7ff,color:#1e1b4b -``` - -The whole thing runs on your local machine. Source code never leaves it โ€” only public package names + pinned versions go to public CVE databases (and only if you haven't passed `--no-cve`). +
--- -## Quick Start (60 seconds) +Most scanners either miss GenAI-specific risk (generic SAST) or hand the judgment to an LLM that produces a different answer every run. **DSGAI Scanner splits the job:** a single-file, dependency-free Python CLI (`cli/dsgai_scan.py`) runs 107 PCRE rules over your code via [ripgrep](https://github.com/BurntSushi/ripgrep) and emits identical findings every time; the [Claude Code](https://www.anthropic.com/claude-code) skill orchestrates the run, classifies ambiguous cases, and renders the report. You get a **reproducible compliance artifact** โ€” and, if you want it, a $0 LLM-free path that drops straight into CI as SARIF. -```bash -# 1. Install the skill into Claude Code -curl -fsSL https://raw.githubusercontent.com/GenAI-Security-Project/GenAI-Data-Security-Initiative/main/dsgai_scanner_tool/dsgai_scanner_tool.md \ - -o ~/.claude/commands/dsgai_scanner_tool.md # macOS/Linux +
+Table of contents -# 2. cd into your GenAI repo and launch Claude Code -cd ~/my-genai-app -claude +- [Quick start](#quick-start) +- [How it works](#how-it-works) +- [Features](#features) +- [The 21 DSGAI controls](#the-21-dsgai-controls) +- [Usage](#usage) +- [CI/CD & Code Scanning](#cicd-and-code-scanning) +- [The report](#the-report) +- [How redaction works](#how-redaction-works) +- [Reference](#reference) โ€” checkpoint file ยท PDF export ยท scope annotation ยท remediation tiers +- [Cost & runtime](#cost-and-runtime) +- [Contributing](#contributing) ยท [Non-goals](#non-goals) +- [License & attribution](#license) -# 3. Run the scan (the skill prefers the deterministic CLI if bundled) -/dsgai_scanner_tool +
-# 4. Open the timestamped report from dsgai-reports/ -open dsgai-reports/DSGAI-report-*.html # macOS -xdg-open dsgai-reports/DSGAI-report-*.html # Linux -start dsgai-reports\DSGAI-report-.html # Windows -``` +## Quick start -**Deterministic, LLM-free option ($0):** run the CLI directly for reproducible findings + SARIF, no API cost: +**Deterministic CLI โ€” $0, no LLM, no account.** Reproducible findings + SARIF in seconds. Needs only Python 3.10+ and ripgrep with PCRE2. ```bash -python dsgai_scanner_tool/cli/dsgai_scan.py scan . --sarif DSGAI-scan.sarif +git clone --depth 1 https://github.com/GenAI-Security-Project/GenAI-Data-Security-Initiative +python GenAI-Data-Security-Initiative/dsgai_scanner_tool/cli/dsgai_scan.py scan . \ + --sarif DSGAI-scan.sarif --json-out DSGAI-scan.json ``` -That's it. Full installation, flags, and CI integration are documented below. - ---- - -## What It Does - -When you run `/dsgai_scanner_tool` inside a repository, the skill: - -1. **Detects** whether the repo contains GenAI/agentic patterns (LangChain, LlamaIndex, OpenAI SDK, vector stores, MCP servers, etc.) โ€” bails out gracefully if none are found. -2. **Enriches live CVEs** by querying OSV, NVD, GitHub Advisory Database, and AVID against the exact package versions pinned in the repo (Python, JS/TS, Java, **Go**). -3. **Scans source code** for all 21 DSGAI risk indicators across all 21 controls โ€” credentials, SQL injection via LLM output, vector store auth, telemetry logging, RAG access controls, MCP transport security, resilience, multimodal handling, synthetic data, labeling pipelines, IDE plugin scoping, and more. -4. **Generates a timestamped `dsgai-reports/DSGAI-report-.html`** โ€” a self-contained, print-ready HTML report with findings, file locations, line numbers, remediation steps, MITRE ATLAS technique mapping, and a CVE advisory panel โ€” **strict-by-default obfuscation designed to minimize disclosure** (share under security-assessment handling; see *Residual risk*). - -**Performance:** All 21 control scans and all CVE source queries run as parallel tool calls โ€” the skill fires multiple grep scans and API requests simultaneously rather than sequentially. Typical scan time: 2โ€“5 minutes (in Claude Code; other AI tools may run sequentially and take longer). - ---- - -## Privacy, Obfuscation & Data Handling - -The skill runs **entirely on your local machine**. Your source code is never uploaded. - -### What stays local -- All source code files scanned for security patterns -- Configuration files, secrets, environment variables -- Dependency manifests and build files - -### What is sent to the internet (optional, CVE lookups only) -- Package names and version numbers (e.g. `langchain==0.1.0`) sent to public vulnerability databases -- Only these public databases: [OSV](https://osv.dev), [NVD](https://nvd.nist.gov), [GitHub Advisory Database](https://github.com/advisories), [AVID](https://avidml.org) -- No actual code, secrets, file contents, or identifying information leaves your machine -- Pass `--no-cve` to skip all network traffic โ€” the scan falls back to the embedded CVE database +**Claude Code skill โ€” full report with narrative + remediation.** -### Report obfuscation โ€” strict by default - -The report **defaults to strict mode**. The default exists because OWASP-aligned compliance reports are routinely shared with auditors, attached to tickets, and stored in public repos โ€” and a leaked secret in a "compliance report" is worse than no report at all. - -| Mode | How to invoke | What evidence shows | When to use | -|---|---|---|---| -| **๐Ÿ›ก๏ธ STRICT** (default) | `/dsgai_scanner_tool` | Filename + line only (`config.py:12`). Intermediate directories dropped. Value-bearing matches (credentials, tokens, PII in logs) NEVER displayed, even with `--internal`. | Sharing with auditors, attaching to a Jira ticket, committing the report to git, posting in Slack, archiving as compliance evidence. | -| **๐Ÿ”“ INTERNAL** | `/dsgai_scanner_tool --internal` | Full relative path (`app/services/agent/config.py:12`). Value-bearing matches still NEVER displayed. | Your team's working copy on a private dev machine when you want to click straight to the file. | - -Value-bearing scans (DSGAI02 credentials, DSGAI13 vector store tokens, DSGAI14 telemetry PII, DSGAI15 system prompt secrets) use a six-step protocol that **never lets the matched secret value enter the report, the on-disk checkpoint, or any persistent tool call** โ€” regardless of mode. - ---- - -## Prerequisites - -- A repository containing GenAI or agentic code (Python, TypeScript, Java, Go) -- An AI coding tool with **file reading access** to your codebase -- **Web access** for live CVE lookups (optional โ€” pass `--no-cve` for fully offline operation) - -No Python packages or external tools required to generate the HTML report. - ---- - -## Running with Claude Code (Native) - -Claude Code has first-class support for this skill via its slash command system. - -**Install โ€” macOS / Linux:** ```bash -cp dsgai_scanner_tool.md ~/.claude/commands/ -``` - -**Install โ€” Windows (PowerShell):** -```powershell -Copy-Item dsgai_scanner_tool.md $env:USERPROFILE\.claude\commands\ -``` - -**Install โ€” Windows (cmd):** -``` -copy dsgai_scanner_tool.md %USERPROFILE%\.claude\commands\ -``` - -**Usage โ€” all flags combinable:** - -| Command | What it does | -|---|---| -| `/dsgai_scanner_tool` | Default scan. STRICT obfuscation. Live CVE enrichment. Full repo. | -| `/dsgai_scanner_tool --internal` | Full file paths (team-internal report) | -| `/dsgai_scanner_tool --no-cve` | Skip live CVE lookups (air-gapped / offline) | -| `/dsgai_scanner_tool --scope app/agents/` | Only scan this sub-directory (large monorepos) | -| `/dsgai_scanner_tool --internal --no-cve --scope services/` | All three combined | +# 1. Install the skill +curl -fsSL https://raw.githubusercontent.com/GenAI-Security-Project/GenAI-Data-Security-Initiative/main/dsgai_scanner_tool/dsgai_scanner_tool.md \ + -o ~/.claude/commands/dsgai_scanner_tool.md -Claude scans the codebase โ€” typically 2โ€“5 minutes depending on repo size. A `DSGAI-report.html` file is saved at the repository root. +# 2. Scan your repo +cd ~/my-genai-app && claude +/dsgai_scanner_tool -**Open the report:** -```bash -# macOS -open DSGAI-report.html -# Linux -xdg-open DSGAI-report.html -# Windows -start DSGAI-report.html +# 3. Open the timestamped report +open dsgai-reports/DSGAI-report-*.html # macOS (xdg-open on Linux, start on Windows) ``` ---- +> [!TIP] +> Check your environment first with `python cli/dsgai_scan.py doctor` โ€” it verifies Python, ripgrep + PCRE2, and that the ruleset loads. -## Running with Other AI Coding Tools +## How it works -The skill file is plain Markdown. Any AI tool with file reading access to your codebase can run it โ€” paste the contents as your prompt. +The deterministic CLI does all pattern matching and CVE lookups; the skill (or the CI's report renderer) turns the checkpoint into a report. Nothing but package names + versions ever leaves your machine. -| Tool | How to run | -|---|---| -| **Cursor** | Open `dsgai_scanner_prompt.md` (the plain-prompt variant), copy contents, paste into Cursor's AI chat | -| **GitHub Copilot Chat** | Open `dsgai_scanner_prompt.md`, copy contents, paste into Copilot Chat in VS Code with repo files as context | -| **ChatGPT / GPT-5** | Paste `dsgai_scanner_prompt.md` as the system prompt, then upload or paste the relevant source files | -| **Google Gemini** | Paste `dsgai_scanner_prompt.md` as instructions, attach source files for analysis | - -> **Why a separate `dsgai_scanner_prompt.md`?** The Claude Code skill assumes specific tools (Grep with output modes, parallel tool calls, Write/Edit). The plain-prompt variant strips those assumptions so it works in tools that just ingest text + files. - -These tools generally cannot run scans in parallel, so total runtime can be 10โ€“20 minutes for large repos. - ---- - -## CI/CD Integrations - -### GitHub Action - -A drop-in workflow that runs the scan on every PR, posts a summary comment, and uploads the report as a build artifact: - -- Triggers on PRs, pushes to `main`/`master`, and manual dispatch -- Installs Claude Code via `npm install -g @anthropic-ai/claude-code` -- Runs the scan in STRICT mode (artifacts can end up in build logs visible to anyone with repo read access) -- Posts a PR comment with FAIL / WARN / PASS / Vendor Attestation / Exploitable CVE counts -- Optionally fails the build on any FAIL-class finding +```mermaid +flowchart TD + Repo[(Your GenAI repo)] --> Detect{"GenAI / agentic
code detected?"} + Detect -->|No| NA["Minimal report
21 ร— NOT APPLICABLE"] + + Detect -->|Yes| Engine + subgraph Engine["Deterministic CLI โ€” cli/dsgai_scan.py ยท stdlib + ripgrep ยท no LLM"] + direction TB + Scan[Scan 21 DSGAI controls
107 PCRE rules] + CVE[CVE enrichment
6 ecosystems ยท cached] + Scan --> Out[DSGAI-scan.json
+ SARIF 2.1.0] + CVE --> Out + end + CVE -. package + version only .-> Sources((OSV ยท NVD)) + + Out --> Skill[Claude Code skill
classify ยท judge ยท prose] + Skill --> Report[Timestamped HTML report
STRICT-redacted] + Out --> Renderer[cli/dsgai_report.py
deterministic HTML] + Renderer --> Report + Out --> CodeScan[GitHub Code Scanning] -Required repo secret: `ANTHROPIC_API_KEY`. Optional: `NVD_API_KEY` (raises rate limit). `GITHUB_TOKEN` is auto-provided by Actions. + Report --> Auditor([Auditor / GRC]) + Report --> Ticket([Jira / backlog]) + CodeScan --> PR([PR annotations]) -```yaml -# .github/workflows/dsgai-scan.yml -name: OWASP DSGAI Compliance Scan -on: - pull_request: { branches: [main] } - workflow_dispatch: -# ... full workflow body in ./integrations/dsgai-scan.yml + style Engine fill:#0f172a,color:#fff + style Skill fill:#7c3aed,color:#fff + style Report fill:#16a34a,color:#fff + style CodeScan fill:#0b7285,color:#fff + style NA fill:#6b7280,color:#fff + style Sources fill:#e0e7ff,color:#1e1b4b ``` -See [`integrations/dsgai-scan.yml`](integrations/dsgai-scan.yml) for the complete workflow. - -### Pre-commit Hook (fast secret scan only) +**Value-bearing rules never surface the secret.** Credential/PII patterns run through ripgrep in erase-the-match mode (`rg -o --replace ''`), so the matched value is destroyed *inside ripgrep* before anything is emitted โ€” it cannot reach the report, the checkpoint, or a tool call. See [How redaction works](#how-redaction-works). -A pre-commit hook that runs a fast subset (DSGAI02 hardcoded LLM API key scan) to block secrets before commit. See [`integrations/pre-commit-hook.md`](integrations/pre-commit-hook.md) for the recipe. +## Features ---- - -## What Gets Scanned - -All 21 DSGAI risks from the OWASP GenAI Data Security framework: - -| Risk | Control Area | Scope | +| | | +|---|---| +| ๐ŸŽฏ **Deterministic engine** | 107 PCRE rules, run via `rg --pcre2`. Identical findings on identical input โ€” a compliance report you can diff, not an LLM opinion. | +| ๐Ÿ”’ **Redaction by construction** | Value-bearing matches are erased inside ripgrep; the checkpoint schema *forbids* content fields (machine-checked). | +| ๐Ÿงพ **SARIF 2.1.0 โ†’ Code Scanning** | Native GitHub Code Scanning annotations on changed lines, plus a portable artifact. | +| ๐Ÿ› **CVE enrichment, no hallucination** | The CLI queries OSV (+ NVD for CVSS) per pinned version across **6 ecosystems**; the LLM never transcribes CVE data. Cached, offline-capable. | +| ๐ŸŒ **Multi-language** | Python, JS/TS, Java, Kotlin, Go, and credential coverage for **C#, Rust, Ruby**. | +| ๐Ÿงฐ **Ships with the ecosystem** | A [gitleaks](integrations/gitleaks/dsgai.toml) rule pack and a [Semgrep](dist/dsgai.semgrep.yaml) export so incumbent toolchains carry the framework. | +| ๐ŸŽš๏ธ **Team-scale controls** | Inline `# dsgai-ignore` suppressions (with reasons), a **baseline** so CI gates only on new findings, and incremental `--diff` scans. | +| โœ… **Tested & gated** | A public [vulnerable fixture app](tests/fixtures/vulnerable-app/) with a line-pinned answer sheet and a CI self-test that makes external rule PRs safe to merge. | +| ๐Ÿ—ฃ๏ธ **Honest reporting** | STRICT mode renders stable file IDs, never the secret; the report declares its own residual risk instead of implying it can be published as-is. | + +### The 21 DSGAI controls + +
+Every control is rated PASS / WARN / FAIL / NOT VALIDATED / NOT APPLICABLE / VENDOR ATTESTATION REQUIRED โ€” click to expand the full list. + +| Risk | Control | Responsibility | |---|---|---| | DSGAI01 | Training Data Privacy | BOTH | -| DSGAI02 | Agentic Identity & Credential Management | BUILD | -| DSGAI03 | Shadow AI & Unauthorized Data Flows | BOTH | +| DSGAI02 | Agentic Identity & Credential Management | BUILD | +| DSGAI03 | Shadow AI & Unauthorized Data Flows | BOTH | | DSGAI04 | AI Supply Chain Security | BUILD | | DSGAI05 | RAG Data Security | BUILD | -| DSGAI06 | MCP & Plugin Security | BUILD | +| DSGAI06 | MCP & Plugin Security | BUILD | | DSGAI07 | Data Lifecycle Management | BUILD | -| DSGAI08 | Regulatory & Privacy Compliance | BOTH | +| DSGAI08 | Regulatory & Privacy Compliance | BOTH | | DSGAI09 | Multimodal AI Data Security | BOTH | | DSGAI10 | Synthetic Data Security | BUILD | | DSGAI11 | Multi-Tenant Data Isolation | BUILD | | DSGAI12 | Database Agent Security | BUILD | | DSGAI13 | Vector Store Security | BUILD | -| DSGAI14 | AI Telemetry & Observability Security | BUILD | +| DSGAI14 | AI Telemetry & Observability Security | BUILD | | DSGAI15 | Context Window Data Security | BUILD | -| DSGAI16 | AI IDE Plugin & Extension Security | BUILD | -| DSGAI17 | AI System Resilience & Availability | BUILD | +| DSGAI16 | AI IDE Plugin & Extension Security | BUILD | +| DSGAI17 | AI System Resilience & Availability | BUILD | | DSGAI18 | Model Output Data Security | BUILD | | DSGAI19 | AI Data Labeling Security | BUILD | | DSGAI20 | Inference API Security | BOTH | | DSGAI21 | Knowledge Store Security | BUILD | -Each control is rated: **PASS** / **WARN** / **FAIL** / **NOT VALIDATED** / **NOT APPLICABLE** / **VENDOR ATTESTATION REQUIRED**. - -> **VENDOR ATTESTATION REQUIRED** is new in v0.2. For BUY-tagged controls and the BUY portions of BOTH-tagged controls, the code scan cannot determine compliance โ€” the report lists exactly which vendor attestations to request (e.g. SOC 2 report, training data retention policy, rate-limit documentation). - -### Remediation Tiers +**[BUILD]** you implement (scanned mechanically) ยท **[BUY]** the vendor is responsible (emits a *Vendor Attestation Required* callout) ยท **[BOTH]** shared. See the **Reference โ†’ Scope annotation** section below. -Each finding in the Recommendations section is tagged with one of three tiers so teams can sequence work: +
-| Tier | Colour | Meaning | Example | -|---|---|---|---| -| **Tier 1** | ๐Ÿ”ด Red | Fix today. FAIL items + exploitable CVEs affecting your repo. | Hardcoded `sk-` API key; unauthenticated vector store; `torch.load()` unsafe pickle. | -| **Tier 2** | ๐ŸŸก Yellow | Architecture backlog. WARN items + structural improvements. | Add circuit breaker; centralize PII redaction middleware; replace third-party LLM call with internal gateway. | -| **Tier 3** | ๐Ÿ”ต Blue | Maturity program. NOT VALIDATED items needing process evidence. | Run quarterly red-team exercise; complete DPIA; commission AppSec architecture review. | +## Usage -Vendor attestations to request from BUY/BOTH controls render as a separate ๐ŸŸฃ purple card. +### Deterministic CLI ---- +`cli/dsgai_scan.py` is a single stdlib-only file that shells out to ripgrep. Subcommands: -## Evidence Safety โ€” Structural vs Value-Bearing Patterns +| Command | What it does | +|---|---| +| `scan [path]` | Run the ruleset; emit `DSGAI-scan.json`, SARIF, and/or a table. | +| `detect [path]` | Exit 0 if the repo contains GenAI/agentic signals, 1 otherwise. | +| `doctor` | Check Python, ripgrep + PCRE2, and that the ruleset loads. | +| `baseline [path]` | Snapshot current findings to a baseline file. | +| `cve [path]` | CVE enrichment only, from dependency manifests. | -When the skill scans your codebase and finds a match, it needs to include that evidence in the report. Not all matches are equal โ€” some show *architectural gaps* (safe to display), others target *credential and PII-bearing lines* (must never appear in a shareable report). +Key `scan` flags (all combinable): -### Structural Patterns [STRUCTURAL] +| Flag | Effect | +|---|---| +| `--sarif FILE` | Write SARIF 2.1.0 for GitHub Code Scanning. | +| `--json-out FILE` | Write the `DSGAI-scan.json` checkpoint. | +| `--internal` | Render full paths (default STRICT renders file IDs). | +| `--scope PATH` | Restrict the scan to a sub-directory. | +| `--exclude PATH` | Exclude a path/glob (repeatable). | +| `--diff REF` | Incremental: only files changed vs `REF`. | +| `--baseline FILE` | Gate only on findings **not** in the baseline. | +| `--no-cve` / `--offline` / `--refresh-cve` | Control CVE enrichment & caching. | +| `--fail-on {fail,warn}` | Exit non-zero at this threshold (CI gating). | + +Suppress a finding inline (a reason is required, and it stays visible in a *Suppressed* section): + +```python +db.execute(query) # dsgai-ignore: P12.1 reason="reviewed 2026-07 โ€” ORM param binding" +``` -The match shows a code *pattern* โ€” a missing import, an absent decorator, a function call without a required argument. The matched line contains no runtime secret or PII. It is reproduced in the evidence block because it proves the finding without exposing anything sensitive. +### Claude Code skill -**Examples (safe to show):** -``` -# DSGAI04 โ€” torch.load() without weights_only=True -loader.py:22 โ€” model = torch.load(model_path) +The skill prefers the bundled CLI and falls back to an in-context scan if it isn't present; the report header names which engine ran. -# DSGAI06 โ€” MCP server binding all interfaces with no auth middleware -server.py:42 โ€” uvicorn.run(app, host="0.0.0.0", port=8001) +| Command | What it does | +|---|---| +| `/dsgai_scanner_tool` | Full scan. STRICT redaction, CVE enrichment, whole repo. | +| `/dsgai_scanner_tool --internal` | Full file paths (team-internal report). | +| `/dsgai_scanner_tool --no-cve` | Skip CVE lookups (air-gapped / offline). | +| `/dsgai_scanner_tool --scope app/agents/` | Scan one sub-directory (monorepos). | +| `/dsgai_scanner_tool --diff main --baseline dsgai-baseline.json` | Incremental, gated on new findings. | -# DSGAI20 โ€” FastAPI endpoint missing rate-limiting decorator -main.py:55 โ€” @app.post("/chat") # no @limiter.limit decorator +### Other AI coding tools -# DSGAI05 โ€” similarity_search() missing access-control filter -retriever.py:41 โ€” results = vectorstore.similarity_search(query, k=5) -``` +The tool-neutral variant [`dsgai_scanner_prompt.md`](dsgai_scanner_prompt.md) is generated from the skill (so the two never drift) and works with any assistant that can run shell commands โ€” Cursor, Copilot Chat, ChatGPT, Gemini. Paste it as instructions and give the model access to your files and a shell. -### Value-Bearing Patterns [VALUE-BEARING โš ๏ธ] +## CI/CD and Code Scanning -The match specifically targets lines where the *content IS the sensitive value* โ€” a credential assignment, a secret key, a connection string, or a log statement that may contain PII. Reproducing this in a shareable report would leak the actual value. +### GitHub Action โ€” [`integrations/dsgai-scan.yml`](integrations/dsgai-scan.yml) -The skill applies a **six-step protocol** (V1โ€“V6, defined in the skill file) that guarantees the matched value never enters the report, the on-disk checkpoint file, or any persistent tool call. Additionally, every STRUCTURAL match is swept for accidental secret patterns before display. +A hardened, **two-job** workflow. The design keeps secrets away from any job that reads untrusted code: -**What the report shows for value-bearing findings:** -``` -config.py:12 โ€” hardcoded OpenAI API key pattern detected (value redacted โ€” review file directly) -config.py:18 โ€” hardcoded vector store auth token pattern detected (value redacted โ€” review file directly) -logging.py:28 โ€” prompt logging statement detected (content redacted โ€” review file directly) -``` +- **`scan`** โ€” runs the **deterministic CLI only**: no LLM, no API key, no network egress with a secret. Safe on fork PRs. Uploads **SARIF to Code Scanning** (same-repo) and the checkpoint as an artifact. +- **`narrate`** โ€” renders the HTML report **deterministically** (`cli/dsgai_report.py`); no LLM, no secret either. -The four DSGAI controls whose scans are classified VALUE-BEARING: +All third-party actions are **pinned by commit SHA**. Gating is **report-only by default** โ€” set the repo variable `DSGAI_FAIL_ON` to `fail` or `warn` to break the build. No `ANTHROPIC_API_KEY` is required. -| Control | Why value-bearing | -|---|---| -| **DSGAI02** โ€” Agentic Credential Management | Matches lines containing actual API keys, database passwords, JWT secrets, cloud credentials | -| **DSGAI13** โ€” Vector Store Security | May match lines where vector store auth tokens are hardcoded as literal values | -| **DSGAI14** โ€” AI Telemetry Security | Matches log statements whose format strings reference PII fields or contain inline test data | -| **DSGAI15** โ€” Context Window Security | Matches system prompt construction that may embed credential strings or sensitive config | +> [!IMPORTANT] +> CI always scans in STRICT mode (file IDs, never full paths or values). Don't pass `--internal` in a workflow whose artifacts or logs are visible beyond your team. -All 17 remaining controls (DSGAI01, 03โ€“12, 16โ€“21) are **STRUCTURAL** โ€” matched content is always safe to show (after defense-in-depth secret sweep). +### Pre-commit โ€” gitleaks pack + portable fallback ---- +Block hardcoded credentials before they land. Recommended path is the [gitleaks rule pack](integrations/gitleaks/dsgai.toml) (entropy-aware, cross-platform); a zero-dependency [ripgrep script](integrations/dsgai-secret-scan.sh) is provided as a bash-3.2-safe fallback. See [`integrations/pre-commit-hook.md`](integrations/pre-commit-hook.md). -## Report Output +### Semgrep pack -

- Sample DSGAI compliance report showing dashboard, findings cards, and CVE advisory panel -
- DSGAI report rendered deterministically (cli/dsgai_report.py) from a scan of the public fixture app โ€” STRICT mode, file IDs + line numbers only, zero real-repo disclosure. Fully reproducible. -

+[`dist/dsgai.semgrep.yaml`](dist/dsgai.semgrep.yaml) exports the STRUCTURAL rules as a Semgrep pack โ€” run the DSGAI framework inside a toolchain you already have. -The generated `DSGAI-report.html` contains: +## Why this scanner -- **Executive Summary** โ€” overall posture and key FAIL findings -- **Obfuscation Mode badge** โ€” STRICT ๐Ÿ›ก๏ธ or INTERNAL ๐Ÿ”“ -- **Dashboard** โ€” counts of PASS / WARN / FAIL / NOT VALIDATED / NOT APPLICABLE / VENDOR ATTESTATION across all 21 controls -- **AI Component Inventory** โ€” detected frameworks, vector stores, LLM providers, MCP servers -- **MITRE ATLAS Techniques** โ€” AI attack techniques relevant to the detected stack -- **Summary Table** โ€” all 21 risks at a glance with status and key evidence -- **Detailed Findings** โ€” one card per risk with file locations, line numbers, remediation steps -- **Recommendations** โ€” tiered action plan (fix today / architecture backlog / maturity / vendor attestations) -- **CVE Advisory Panel** โ€” live CVEs for your exact dependency versions, grouped by DSGAI risk -- **Compliance Artifacts Checklist** โ€” 15-item checklist mappable to GDPR, EU AI Act, SOC 2, ISO 42001 +It's built to *complement* the tools you already run, not replace them โ€” it even ships packs for them. -The report is fully self-contained (no CDN, no external fonts) and renders correctly when saved as PDF. +- **Framework-native.** The reference implementation of the OWASP GenAI Data Security 2026 framework, maintained inside the initiative that authors it. Findings map 1:1 to the 21 controls, so the report reads as compliance evidence, not generic lint output. +- **Deterministic where it matters.** Pattern matching, CVE lookup, and report structure are code (stdlib CLI + ripgrep) โ€” not model output. Identical input yields byte-identical findings, and every rule is data pinned to a known-answer fixture corpus. The optional LLM layer only adds prose; it never decides what was found. +- **Redaction by construction, not by policy.** Value-bearing rules erase the match inside ripgrep, and the checkpoint schema formally forbids content fields โ€” so the guarantee is machine-checked in CI, not left to discipline. +- **GenAI-specific depth, not SAST breadth.** Vector-store auth, RAG access control, MCP transport, prompt-logging PII, unsafe model deserialization, agentic credential handling โ€” patterns general rulesets don't carry. +- **Feeds your toolchain.** SARIF into GitHub Code Scanning; exported Semgrep and gitleaks packs so the framework rides tools you already operate. ---- +## The report -## Scan Checkpoint File (`DSGAI-scan.json`) +

+ Sample DSGAI compliance report showing the dashboard, finding cards, and CVE advisory panel +
+ Rendered deterministically by cli/dsgai_report.py from a scan of the public fixture app โ€” STRICT mode, file IDs + line numbers only, zero real-repo disclosure. Fully reproducible. +

-When the skill runs, it writes a local checkpoint file called `DSGAI-scan.json` to the repository root after each major scan phase. +The self-contained HTML report (no CDN, no external fonts; prints cleanly to PDF) contains: -### Why it exists +- **Executive summary** & an **obfuscation-mode badge** (๐Ÿ›ก๏ธ STRICT / ๐Ÿ”“ INTERNAL) +- **Compliance dashboard** โ€” counts across all 21 controls; every status carries a symbol + text label, not colour alone +- **AI component inventory** โ€” detected frameworks, vector stores, LLM providers, MCP servers +- **MITRE ATLAS techniques** relevant to the detected stack (from a versioned [static map](rules/atlas-map.yaml)) +- **Findings** โ€” one card per risk with locations, line numbers, and tiered remediation +- **CVE advisory panel** โ€” advisories for your exact dependency versions, grouped by DSGAI risk +- **Compliance checklist** mappable to GDPR, EU AI Act, SOC 2, ISO 42001 -The scan involves three time-consuming phases: repository detection, live CVE enrichment, and 21-control grep scanning. If the session times out before the HTML report is written, everything is lost and the scan restarts from zero. The checkpoint prevents this โ€” on the next run the skill skips already-completed phases. +> [!WARNING] +> **Residual risk.** STRICT mode is designed to *minimize* disclosure โ€” file IDs + line numbers only, value-bearing matches never shown. It does **not** make the report public-safe: the existence and location of failing controls is itself information. Handle it like any security assessment. -### What it stores โ€” and what it doesn't +## How redaction works -The file contains only **structural scan metadata**: detected framework versions, DSGAI control findings (status, rendered file paths, line numbers, pattern IDs), and CVE query results. +The redaction guarantee is **structural**, not a matter of remembering to be careful: -The same redaction rules that apply to the HTML report apply here: -- VALUE-BEARING findings store only `{control, path_rendered, line, pattern_id, status}` โ€” never `match_text`, `raw_grep_output`, or `value` -- In STRICT mode, the `path_internal` field is omitted entirely โ€” keeping full paths out of the checkpoint, which minimizes disclosure without making the checkpoint public-safe -- In INTERNAL mode, both `path_rendered` and `path_internal` are present for team convenience +1. **Location-only matching.** Value-bearing rules (DSGAI02/13/14/15 โ€” credentials, vector-store tokens, telemetry PII, system-prompt secrets) run `rg -o --replace ''`. Ripgrep erases the matched text *before it emits anything*, so the output is `path:line:` โ€” the secret never leaves the ripgrep process. +2. **Stable file IDs in STRICT mode.** Findings render as `F07:12`; the `F## โ†’ path` map is written to a **gitignored** `DSGAI-filemap.json` that is never embedded in the report. +3. **A schema that forbids leakage.** [`schemas/dsgai-scan.schema.json`](schemas/dsgai-scan.schema.json) rejects any finding carrying `match_text`, `content`, `value`, or `raw_grep_output`, and the CLI self-validates before writing. The guarantee is machine-checked by CI. -### Lifecycle +## Reference -In STRICT mode it contains no secrets and no full paths, but it still records which controls fail and where โ€” treat it as a security artifact (commit only if your repo's threat model allows, or `.gitignore` it). Regenerated on each full scan. +
+Checkpoint file โ€” DSGAI-scan.json ---- +The CLI writes a schema-validated checkpoint alongside the report: framework/ruleset versions, per-control statuses, findings (control, rule ID, rendered path, line, status), suppressed findings, and CVEs. It carries **no** match content by construction. In STRICT mode it holds file IDs, not full paths โ€” but it still records which controls fail and where, so treat it as a security artifact (commit only if your threat model allows, or `.gitignore` it). -## Exporting to PDF +
-**Option 1 โ€” Browser print (simplest):** -Open `DSGAI-report.html` in Chrome or Edge โ†’ `Ctrl+P` / `Cmd+P` โ†’ Save as PDF. All cards expand automatically for print. +
+Export to PDF -**Option 2 โ€” Chrome headless (scriptable):** +**Browser:** open the report in Chrome/Edge โ†’ `Ctrl/Cmd+P` โ†’ Save as PDF (cards expand for print). +**Headless:** ```bash -# macOS -"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ - --headless=new --print-to-pdf=DSGAI-report.pdf \ - --print-to-pdf-no-header "file://$(pwd)/DSGAI-report.html" - -# Linux google-chrome --headless=new --print-to-pdf=DSGAI-report.pdf \ - --print-to-pdf-no-header "file://$(pwd)/DSGAI-report.html" -``` - -```powershell -# Windows (PowerShell) -& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` - --headless=new --print-to-pdf=DSGAI-report.pdf ` - --print-to-pdf-no-header "file:///$((Get-Location).Path)/DSGAI-report.html" + --print-to-pdf-no-header "file://$(pwd)/dsgai-reports/DSGAI-report-.html" ``` ---- - -## Scope Annotation - -Each DSGAI control is tagged by responsibility: - -- **[BUILD]** โ€” your team implements this in the codebase. Scanned mechanically. -- **[BUY]** โ€” the LLM provider / SaaS vendor is responsible. Emits a `VENDOR ATTESTATION REQUIRED` callout listing what to request. -- **[BOTH]** โ€” shared responsibility. The BUILD portion is scanned; the BUY portion emits a vendor attestation callout. +
-Controls with BUY-side aspects (DSGAI01, 08, 09, 20) generate a consolidated "Vendor Attestations to Request" recommendation card. +
+Scope annotation โ€” BUILD / BUY / BOTH ---- +Each control is tagged by responsibility. **[BUILD]** controls are scanned mechanically. **[BUY]** controls (the vendor's responsibility) emit a `VENDOR ATTESTATION REQUIRED` callout listing exactly what to request (e.g. SOC 2 report, data-retention policy, rate-limit documentation). **[BOTH]** controls scan the BUILD portion and emit an attestation callout for the BUY portion. Controls with BUY aspects (DSGAI01, 08, 09, 20) consolidate into one *Vendor Attestations to Request* card. -## Based On +
-**OWASP GenAI Data Security Risks and Mitigations 2026 (v1.0, March 2026)** -[https://genai.owasp.org/resource/owasp-genai-data-security-risks-mitigations-2026/](https://genai.owasp.org/resource/owasp-genai-data-security-risks-mitigations-2026/) +
+Remediation tiers -[OWASP GenAI Data Security Initiative](https://genai.owasp.org/initiative/data-security/) โ€” led by [Emmanuel Guilherme Junior](https://www.linkedin.com/in/emmanuelgjr/). +| Tier | Meaning | Example | +|---|---|---| +| ๐Ÿ”ด **Tier 1** โ€” fix today | FAIL items + exploitable CVEs | Hardcoded `sk-` key; unauthenticated vector store; unsafe `torch.load()` | +| ๐ŸŸก **Tier 2** โ€” architecture backlog | WARN + structural gaps | Add a circuit breaker; centralize PII redaction; route via an internal LLM gateway | +| ๐Ÿ”ต **Tier 3** โ€” maturity program | NOT VALIDATED (process evidence) | Quarterly red-team; complete a DPIA; commission an AppSec review | ---- +
-## Cost & runtime +## Cost and runtime -- **CLI-only mode: $0.** `python cli/dsgai_scan.py scan .` uses no LLM โ€” just ripgrep. Reproducible findings + SARIF in seconds. This is what the hardened GitHub Action runs on every PR (including fork PRs, since it needs no secrets). -- **Skill mode (LLM orchestration):** a full scan of the public fixture app renders in roughly **1โ€“3 minutes** in Claude Code; token cost depends on repo size and the report prose. The deterministic engine does the matching; the model only classifies, writes remediation prose, and renders the report โ€” so cost scales with findings, not lines of code. -- **Fork PRs:** the Action's scan job runs on forks and uploads the SARIF as an artifact (Code Scanning upload is skipped โ€” fork tokens can't write security events); the LLM narration job is skipped on forks by design. -- Incremental `--diff` scans (seconds, near-zero cost) are planned for **v0.4**. +- **CLI-only mode: $0.** `python cli/dsgai_scan.py scan .` uses no LLM โ€” just ripgrep. Reproducible findings + SARIF in seconds. This is what the Action runs on every PR (including forks, since it needs no secrets). +- **Skill mode:** a full scan of the fixture app renders in ~1โ€“3 minutes in Claude Code; token cost scales with findings and report prose, not lines of code โ€” the deterministic engine does the matching. +- Everything runs **locally**. Only package names + pinned versions go to public CVE databases, and only if you don't pass `--no-cve`. ## Contributing +> [!TIP] > **Found a wrong result? That's a contribution.** Run the scan on your repo and file a -> [false-positive](../.github/ISSUE_TEMPLATE/scanner-false-positive.yml) or -> [false-negative](../.github/ISSUE_TEMPLATE/scanner-false-negative.yml) issue โ€” every -> accepted report becomes a permanent, credited test case. No code required. - -This is an OWASP project. Contributions welcome โ€” open an issue or PR against [GenAI-Security-Project/GenAI-Data-Security-Initiative](https://github.com/GenAI-Security-Project/GenAI-Data-Security-Initiative). +> [false-positive](https://github.com/GenAI-Security-Project/GenAI-Data-Security-Initiative/issues/new?template=scanner-false-positive.yml) or +> [false-negative](https://github.com/GenAI-Security-Project/GenAI-Data-Security-Initiative/issues/new?template=scanner-false-negative.yml) issue โ€” every accepted +> report becomes a permanent, credited test case in the fixture corpus. No code required. -When proposing new scan patterns: -1. Classify them as STRUCTURAL or VALUE-BEARING (use the table in the skill's Step 2) -2. Validate the PCRE pattern with `rg --pcre2 'pattern' .` against a real repo -3. For VALUE-BEARING patterns, prove the value never escapes by inspecting `DSGAI-scan.json` after a test run +Detection rules live as data in [`rules/dsgai-rules.yaml`](rules/dsgai-rules.yaml) (schema-validated, compiled to JSON). To add or fix a rule, see [`rules/README.md`](rules/README.md) and the full guide in [`CONTRIBUTING.md`](CONTRIBUTING.md); the [`ROADMAP.md`](ROADMAP.md) tracks what's planned. Every rule ships with positive **and** negative fixture cases โ€” the CI self-test is the gate. -See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full contributor guide and the -[`ROADMAP.md`](ROADMAP.md) for what's planned. +### Non-goals -## Non-goals +To stay maintainable and trustworthy, some things are deliberately out of scope: -To keep the scanner maintainable and trustworthy, some things are deliberately out of scope: - -- **We will not reimplement general-purpose secret scanning.** We ship a gitleaks rule - pack instead (see `integrations/gitleaks/`) and lean on battle-tested tooling for - entropy-based detection. -- **We will not become a general-purpose SAST tool.** Scope is the 21 DSGAI controls and - the GenAI-specific patterns behind them โ€” not every code smell in a repo. -- **We will not add rules without fixture test cases.** A rule with no positive *and* - negative test has no defined precision, so it doesn't merge. -- **We will not accept changes that weaken the redaction guarantees.** Value-bearing - matches never enter a report, checkpoint, or persisted tool call โ€” that property is - non-negotiable. - ---- +- **No general-purpose secret scanning** โ€” we ship a gitleaks pack and lean on battle-tested tooling instead. +- **No general SAST** โ€” scope is the 21 DSGAI controls, not every code smell. +- **No rules without fixture tests** โ€” a rule with no positive *and* negative case has no defined precision. +- **No changes that weaken the redaction guarantee** โ€” that property is non-negotiable. ## License -This skill is based on materials licensed under [Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/legalcode). +Based on the **OWASP GenAI Data Security Risks and Mitigations 2026 (v1.0, March 2026)**, licensed under [Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/legalcode). *(A split that keeps framework text under CC BY-SA 4.0 while re-licensing the executable code under Apache-2.0 is under review with OWASP leadership.)* -**Original work:** OWASP GenAI Data Security Risks and Mitigations 2026 (v1.0, March 2026) by the [OWASP GenAI Data Security Initiative](https://genai.owasp.org/initiative/data-security/), led by [Emmanuel Guilherme Junior](https://www.linkedin.com/in/emmanuelgjr/). +**Framework & scanner** by the [OWASP GenAI Data Security Initiative](https://genai.owasp.org/initiative/data-security/), led by [Emmanuel Guilherme Junior](https://www.linkedin.com/in/emmanuelgjr/). v0.1 groundwork by Harish Ramachandran. -**This adaptation:** Created by [Harish Ramachandran](https://www.linkedin.com/in/harish-ramachandran-a8026443/). You are free to share and adapt this skill for any purpose, including commercial use, under the same CC BY-SA 4.0 terms. +
+Part of the OWASP GenAI Data Security Initiative ยท genai.owasp.org +