Skip to content

Commit b8ff971

Browse files
authored
feat(scanner): add contributor infrastructure (PR-01) (#12)
Add scanner-specific GitHub issue-form templates (false-positive, false-negative, new-rule, bug) plus an issue-chooser config with an OWASP Slack contact link. Add the scanner CONTRIBUTING funnel, a public ROADMAP distilled from the improvement plan (Phases 1-4), and the CHANGES_v0.3 changelog scaffold that every subsequent PR appends to. Templates are prefixed [scanner] so they filter cleanly in the shared monorepo issue tracker. Labels and good-first-issues are created after merge.
1 parent 734a77f commit b8ff971

8 files changed

Lines changed: 432 additions & 0 deletions

File tree

‎.github/ISSUE_TEMPLATE/config.yml‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
blank_issues_enabled: true
2+
contact_links:
3+
# TODO(maintainer): replace the OWASP Slack invite URL below with the direct
4+
# invite link to the initiative's channel (e.g. #genai-data-security) once known.
5+
- name: OWASP GenAI Slack (DSGAI scanner discussion)
6+
url: https://owasp.org/slack/invite
7+
about: >-
8+
Questions, scan reports, or general discussion? Join the OWASP Slack and find
9+
the GenAI Data Security Initiative channel. For wrong scanner results, please
10+
still file a [scanner] false-positive / false-negative issue so it becomes a test case.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: "[scanner] Bug"
2+
description: A general behavior bug in the DSGAI scanner (report rendering, CI, flags, CLI).
3+
title: "[scanner] Bug: "
4+
labels: ["scanner", "bug"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
For wrong findings, prefer the false-positive / false-negative templates.
10+
Use this one for everything else: crashes, rendering, CI, flag handling.
11+
- type: textarea
12+
id: what-happened
13+
attributes:
14+
label: What happened
15+
description: Describe the bug and what you expected instead.
16+
validations:
17+
required: true
18+
- type: textarea
19+
id: repro
20+
attributes:
21+
label: Steps to reproduce
22+
description: Exact commands / actions. MUST NOT contain real secrets.
23+
render: text
24+
validations:
25+
required: true
26+
- type: dropdown
27+
id: area
28+
attributes:
29+
label: Area
30+
options:
31+
- Report rendering (HTML)
32+
- CLI (dsgai_scan.py)
33+
- Claude Code skill
34+
- GitHub Action / CI
35+
- Flags / arguments
36+
- Other
37+
validations:
38+
required: true
39+
- type: input
40+
id: version
41+
attributes:
42+
label: Skill / CLI version
43+
placeholder: "0.3.0"
44+
validations:
45+
required: true
46+
- type: textarea
47+
id: context
48+
attributes:
49+
label: Logs / additional context
50+
description: Paste relevant output. Redact anything sensitive.
51+
render: text
52+
validations:
53+
required: false
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: "[scanner] False negative"
2+
description: The DSGAI scanner missed something it should have flagged.
3+
title: "[scanner] False negative: "
4+
labels: ["scanner", "false-negative"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
Thanks for improving the DSGAI scanner's coverage. Every accepted false-negative
10+
report becomes a permanent positive test case in the public fixture corpus, with credit.
11+
- type: textarea
12+
id: what-missed
13+
attributes:
14+
label: What should have been flagged
15+
description: Describe the issue the scanner failed to detect.
16+
validations:
17+
required: true
18+
- type: textarea
19+
id: snippet
20+
attributes:
21+
label: Minimal reproducing snippet
22+
description: The smallest code that should have triggered a finding. MUST NOT contain real secrets — use obviously fake values.
23+
render: text
24+
validations:
25+
required: true
26+
- type: input
27+
id: expected-control
28+
attributes:
29+
label: Expected control
30+
description: Which DSGAI control should this map to, e.g. `DSGAI02`.
31+
placeholder: DSGAI02
32+
validations:
33+
required: true
34+
- type: dropdown
35+
id: expected-severity
36+
attributes:
37+
label: Expected severity
38+
options:
39+
- FAIL
40+
- WARN
41+
- PASS signal
42+
validations:
43+
required: true
44+
- type: input
45+
id: version
46+
attributes:
47+
label: Skill / CLI version
48+
description: e.g. `0.3.0`. See the report header or `dsgai_scan.py --version`.
49+
placeholder: "0.3.0"
50+
validations:
51+
required: true
52+
- type: markdown
53+
attributes:
54+
value: |
55+
> Reproducing snippets are added to the public test fixture corpus under the repo license.
56+
> Never paste real credentials — use obviously fake values.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: "[scanner] False positive"
2+
description: The DSGAI scanner flagged something that is not actually a problem.
3+
title: "[scanner] False positive: "
4+
labels: ["scanner", "false-positive"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
Thanks for improving the DSGAI scanner's precision. Every accepted false-positive
10+
report becomes a permanent negative test case in the public fixture corpus, with credit.
11+
- type: input
12+
id: pattern-id
13+
attributes:
14+
label: Pattern ID
15+
description: The rule that fired, e.g. `P12.1`. Find it in the report next to the finding.
16+
placeholder: P12.1
17+
validations:
18+
required: true
19+
- type: input
20+
id: control
21+
attributes:
22+
label: DSGAI control
23+
description: The control the rule maps to, e.g. `DSGAI12`.
24+
placeholder: DSGAI12
25+
validations:
26+
required: false
27+
- type: textarea
28+
id: snippet
29+
attributes:
30+
label: Minimal reproducing snippet
31+
description: The smallest code that triggers the false positive. MUST NOT contain real secrets — use obviously fake values.
32+
render: text
33+
validations:
34+
required: true
35+
- type: textarea
36+
id: reported
37+
attributes:
38+
label: What the scanner reported
39+
description: Paste the finding line(s) from the report or SARIF.
40+
validations:
41+
required: true
42+
- type: textarea
43+
id: why-wrong
44+
attributes:
45+
label: Why it's wrong
46+
description: Explain why this code is safe / why the finding is incorrect.
47+
validations:
48+
required: true
49+
- type: dropdown
50+
id: environment
51+
attributes:
52+
label: Environment
53+
description: How did you run the scanner?
54+
options:
55+
- Claude Code skill (dsgai_scanner_tool.md)
56+
- Deterministic CLI (cli/dsgai_scan.py)
57+
- GitHub Action
58+
- Other tool (prompt variant)
59+
validations:
60+
required: true
61+
- type: input
62+
id: version
63+
attributes:
64+
label: Skill / CLI version
65+
description: e.g. `0.3.0`. See the report header or `dsgai_scan.py --version`.
66+
placeholder: "0.3.0"
67+
validations:
68+
required: true
69+
- type: markdown
70+
attributes:
71+
value: |
72+
> Reproducing snippets are added to the public test fixture corpus under the repo license.
73+
> Never paste real credentials — use obviously fake values.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: "[scanner] Propose a new rule"
2+
description: Propose a new detection rule for a DSGAI control.
3+
title: "[scanner] New rule: "
4+
labels: ["scanner", "rules"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
Thanks for extending DSGAI coverage. Accepted rules ship with your test snippets
10+
as permanent fixture cases, with credit. Rules cannot be merged without at least
11+
one positive and one negative test case.
12+
- type: input
13+
id: control
14+
attributes:
15+
label: Proposed control mapping
16+
description: Which DSGAI control does this rule serve, e.g. `DSGAI17`.
17+
placeholder: DSGAI17
18+
validations:
19+
required: true
20+
- type: textarea
21+
id: pcre
22+
attributes:
23+
label: Proposed PCRE pattern
24+
description: The regex (PCRE2, ripgrep-compatible). Give it as a code block, not a table cell.
25+
render: text
26+
validations:
27+
required: true
28+
- type: dropdown
29+
id: classification
30+
attributes:
31+
label: Classification
32+
description: STRUCTURAL rules match code shape; VALUE-BEARING rules match around secret material and run in location-only mode.
33+
options:
34+
- STRUCTURAL
35+
- VALUE-BEARING
36+
validations:
37+
required: true
38+
- type: textarea
39+
id: positive
40+
attributes:
41+
label: Positive test snippet(s)
42+
description: Code that MUST match. Fake values only. Goes straight into the fixture app on acceptance.
43+
render: text
44+
validations:
45+
required: true
46+
- type: textarea
47+
id: negative
48+
attributes:
49+
label: Negative test snippet(s)
50+
description: Similar-looking code that MUST NOT match. Fake values only.
51+
render: text
52+
validations:
53+
required: true
54+
- type: markdown
55+
attributes:
56+
value: |
57+
> Test snippets are added to the public test fixture corpus under the repo license.
58+
> Never paste real credentials — use obviously fake values.

‎dsgai_scanner_tool/CHANGES_v0.3.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Changelog — DSGAI Scanner Tool v0.3
2+
3+
All notable changes for the v0.3 line. This file is appended by every merged PR.
4+
v0.3 releases when Phases 0–2 of the improvement plan are complete.
5+
6+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loosely;
7+
dates are ISO-8601. The previous line is recorded in [`CHANGES_v0.2.md`](CHANGES_v0.2.md).
8+
9+
## [Unreleased]
10+
11+
### Added
12+
- Contributor infrastructure: `[scanner]` GitHub issue-form templates (false-positive,
13+
false-negative, new-rule, bug), scanner `CONTRIBUTING.md`, public `ROADMAP.md`, and
14+
this changelog scaffold. (PR-01)
15+
16+
### Changed
17+
- _nothing yet_
18+
19+
### Fixed
20+
- _nothing yet_

‎dsgai_scanner_tool/CONTRIBUTING.md‎

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Contributing to the DSGAI Scanner Tool
2+
3+
The DSGAI scanner is a Claude Code skill (plus a deterministic CLI, landing across
4+
v0.3) that audits GenAI applications against the 21 [OWASP GenAI Data Security
5+
controls](https://genai.owasp.org/resource/owasp-genai-data-security-risks-mitigations-2026/).
6+
It gets more useful every time someone runs it on a real repo and tells us what it
7+
got wrong. That is the single most valuable thing you can do here.
8+
9+
> This file covers the **scanner subproject** (`dsgai_scanner_tool/`). For the wider
10+
> initiative, see the [repository-root CONTRIBUTING](../CONTRIBUTING.md).
11+
12+
## Fastest way to help
13+
14+
1. Run the scan on one of your own GenAI repos.
15+
2. When it flags something wrong, or misses something real, open an issue with the
16+
[scanner templates](../.github/ISSUE_TEMPLATE/):
17+
- **[scanner] False positive** — it flagged safe code.
18+
- **[scanner] False negative** — it missed a real problem.
19+
- **[scanner] Propose a new rule** — a control needs coverage it doesn't have.
20+
- **[scanner] Bug** — anything else (rendering, CLI, CI, flags).
21+
22+
**Every accepted false-positive / false-negative report becomes a permanent test case
23+
in the public fixture corpus, credited to you.** You don't have to write any code to
24+
make the tool measurably better — a good repro is the contribution.
25+
26+
> Never paste real credentials into an issue or a fixture. Use obviously fake,
27+
> canonical values (e.g. `sk-proj-FAKE00000000000000000000000000`).
28+
29+
## Contributing a rule
30+
31+
Detection rules are moving from prose in `dsgai_scanner_tool.md` into data at
32+
`rules/dsgai-rules.yaml`, validated by `rules/rules.schema.json`. **(Landing soon —
33+
tracked by PR-03.)** Until that lands, describe your rule in a
34+
[new-rule issue](../.github/ISSUE_TEMPLATE/scanner-new-rule.yml) using the format below;
35+
once the YAML rule format ships, this section will point at `rules/README.md`.
36+
37+
Every rule needs:
38+
39+
- **A control mapping** — one of `DSGAI01`–`DSGAI21`.
40+
- **A PCRE pattern** — PCRE2 syntax, runs under `rg --pcre2`. Give it in a fenced code
41+
block, never a markdown table cell (`\|` becomes a literal pipe when the file is read
42+
back and silently breaks alternation).
43+
- **A classification** (see below).
44+
- **At least one positive and one negative test snippet.** No exceptions — a rule
45+
without a negative case has no defined precision.
46+
47+
### STRUCTURAL vs VALUE-BEARING
48+
49+
This classification controls *how* a rule executes and *what may appear in a report*.
50+
51+
| Class | The match is… | Report may show the matched line? | Execution |
52+
|---|---|---|---|
53+
| **STRUCTURAL** | a code shape — a call, a missing import, a missing decorator, an architectural gap. Contains no runtime secret. | Yes | normal `rg` match |
54+
| **VALUE-BEARING ⚠️** | a line whose *content is* a credential, key, secret, connection string, or PII. | **Never** — not in the report, checkpoint, or any persisted tool call, even if the value looks fake. | location-only: `rg -n -o --replace '' --pcre2` so ripgrep erases the match before emitting `path:line:` |
55+
56+
The four VALUE-BEARING controls today are **DSGAI02, DSGAI13, DSGAI14, DSGAI15**. If
57+
your rule matches lines that could contain secret material, it is VALUE-BEARING — when
58+
in doubt, classify up.
59+
60+
### Running the self-test locally
61+
62+
Once the test infrastructure lands (PR-04/PR-05/PR-06):
63+
64+
```bash
65+
pip install pyyaml pytest
66+
pytest dsgai_scanner_tool/tests/ -q
67+
```
68+
69+
The suite compiles every rule's PCRE, scans the fixture app, and checks the result
70+
against `tests/expected-findings.yaml`. **Rule PRs are only safely reviewable once this
71+
infrastructure exists** — if you draft a rule PR before then, that's welcome, just
72+
expect it to sit until the fixtures land (see the `blocked-on-phase-1` label).
73+
74+
## Code contributions
75+
76+
- **Branch naming:** `improve/pr-NN-short-slug` for planned work, or a short descriptive
77+
slug otherwise. Never commit to `main`.
78+
- **Conventional commits:** `fix:`, `feat:`, `docs:`, `ci:`, `test:`, `refactor:`.
79+
- **Shell scripts** must be `shellcheck` clean and portable (bash 3.2 / macOS included —
80+
no `mapfile`, `readarray`, `${var,,}`, or GNU-only `grep` flags).
81+
- **CI must be green** — the scanner has path-filtered lint and self-test workflows.
82+
83+
## What we will NOT merge
84+
85+
The scanner has deliberate limits that keep it maintainable and trustworthy. See the
86+
[Non-goals section of the README](README.md#non-goals) — please read it before
87+
proposing large additions, so your effort lands somewhere we can accept it.
88+
89+
## Recognition
90+
91+
Contributors are credited by handle in every release note. **Recurring contributors are
92+
invited to become co-maintainers** — this project explicitly wants to grow its
93+
maintainer base, and consistent, high-quality contributors are how that happens. If you
94+
land a few accepted issues or PRs, expect an invitation.

0 commit comments

Comments
 (0)