AI कोडिंग एजेंट्स के लिए मल्टी-एजेंट स्टैटिक एप्लिकेशन-सुरक्षा समीक्षा हार्नेस: कोडबेस को मैप करता है, भेद्यता वर्गों की खोज करता है, निष्कर्षों को श्रृंखलाबद्ध और सत्यापित करता है, और SARIF, JSON, तथा PDF में रिपोर्ट करता है।
Claude Code (और, बाद में, अन्य AI एजेंट्स) के लिए एक मल्टी-एजेंट एप्लिकेशन-सुरक्षा समीक्षा हार्नेस। एक राउटर स्किल एक पूर्ण आक्रामक-सुरक्षा पाइपलाइन को डिस्पैच करता है जो एक कोडबेस को मैप करता है, प्रति-श्रेणी ज्ञान आधार के साथ कमज़ोरियों का शिकार करता है, निष्कर्षों को एस्केलेशन में श्रृंखलाबद्ध करता है, वास्तविक प्रभाव को सत्यापित करता है, और README / JSON / SARIF / doc / PDF में रिपोर्ट करता है।
दायरा: यह हार्नेस उस कोड पर स्टैटिक विश्लेषण (स्रोत समीक्षा, डेटा-फ़्लो ट्रेसिंग, PoC/पेलोड निर्माण) करता है जिसका आप स्वामी हैं या जिसका परीक्षण करने के लिए आप अधिकृत हैं। यह लाइव तृतीय-पक्ष सिस्टम पर हमला नहीं करता।
security-harness/ # a plugin marketplace └── plugins/security-harness/ ├── skills/ │ ├── sh-router # single entry point - routes any appsec request │ ├── sh-security-review # the pipeline orchestrator (Stages 0-5) │ └── sh-kb-* (15) # per-vuln-class knowledge bases ├── agents/ │ ├── sh-recon # map: Graft graph + stack/SBOM/CVE + attack surface │ ├── sh-hunter # find: source→sink hunting, one per class (parallel) │ ├── sh-chainer # escalate: combine findings into attack chains │ ├── sh-verifier # confirm: offensive + seceng + dev verification + PoC │ └── sh-reporter # deliver: README/JSON/SARIF/HTML/PDF/doc └── references/ # shared contracts (finding schema, SARIF map, state files, rubrics)
### कवर की गई भेद्यता श्रेणियाँ (`sh-kb-*` कौशल)
access-control (IDOR/BOLA/priv-esc) · sqli · xss · ssrf · injection (cmd/code/SSTI/LDAP) · auth (session/JWT)
· deserialization · path-traversal (LFI/RFI) · secrets · csrf · xxe · open-redirect · crypto · race-conditions
· file-upload. Dependency CVEs/SBOM को recon चरण द्वारा संभाला जाता है।
## इंस्टॉल
यह हार्नेस कई एजेंट्स के लिए उपलब्ध है। पूर्ण पैकेजिंग विवरण और रिलीज़
चेकलिस्ट [`docs/DISTRIBUTION.md`](https://github.com/dmdhrumilmistry/security-harness/blob/main/docs/DISTRIBUTION.md) में हैं।
**Claude Code** - इस रेपो को प्लगइन मार्केटप्लेस के रूप में जोड़ें और प्लगइन इंस्टॉल करें:```
/plugin marketplace add dmdhrumilmistry/security-harness
/plugin install security-harness
/plugin marketplace add इनमें से कोई भी स्वीकार करता है: एक GitHub owner/repo (जैसा ऊपर है), एक पूर्ण git URL
(https://github.com/dmdhrumilmistry/security-harness.git), या किसी क्लोन का स्थानीय पथ
(उदा. /plugin marketplace add ./security-harness उस डायरेक्टरी से जिसमें आपका चेकआउट है)।
फिर /plugin install security-harness चलाएँ और संकेत मिलने पर पुनः लोड करें।
Gemini CLI - एक नेटिव एक्सटेंशन, मैनिफ़ेस्ट रेपो रूट पर:```bash gemini extensions install https://github.com/dmdhrumilmistry/security-harness
**opencode, Codex, या कोई भी [agentskills.io](https://agentskills.io) एजेंट** - skills को एक discovery directory में कॉपी करें। Codex इसके अतिरिक्त स्वयं `AGENTS.md` को उठा लेता है:```bash
git clone https://github.com/dmdhrumilmistry/security-harness
cd security-harness
python3 scripts/sync-agent-skills.py --install agents # ~/.agents/skills
python3 scripts/sync-agent-skills.py --install opencode # ~/.config/opencode/skills
Graft पाइपलाइन द्वारा स्वचालित रूप से इंस्टॉल और सेटअप किया जाता है। Stage 0 npm install -g @nanonets/graft चलाता है यदि यह अनुपस्थित है (Node/npm की आवश्यकता है), फिर graft init <target> --no-agents --no-global
चलाता है ताकि लक्ष्य रेपो के लिए Graft MCP सर्वर और freshness hooks रजिस्टर हो सकें। ग्राफ स्वयं (<target>/graft/,
स्वतः-gitignored) recon के दौरान बनाया जाता है। मैन्युअल रूप से पहले से इंस्टॉल करने के लिए: npm install -g @nanonets/graft। Graft का
संरचनात्मक बिल्ड मुफ़्त है और इसके लिए किसी API key की आवश्यकता नहीं है; वैकल्पिक --deep LLM पास सेट होने पर GRAFT_API_KEY /
GRAFT_PROVIDER / GRAFT_MODEL का उपयोग करता है।
अन्य टूल्स भी Stage 0 द्वारा अनुपस्थित होने पर स्वतः-इंस्टॉल किए जाते हैं (मशीन पर उपलब्ध किसी भी पैकेज मैनेजर के माध्यम से - winget/choco/scoop, brew, apt, npm/pip/go - देखें references/tooling-setup.md)। इंस्टॉल की घोषणा की जाती है, no-elevation विधियों को प्राथमिकता दी जाती है, और रन को कभी ब्लॉक नहीं किया जाता: जो कुछ भी इंस्टॉल नहीं हो सकता उसे बस अनुपलब्ध चिह्नित कर दिया जाता है और पाइपलाइन फ़ॉलबैक कर देती है। Stage 0 केवल वही इंस्टॉल करता है जो किसी अनुपस्थित क्षमता समूह को पूरा करता है:
syft · CVEs: grype
(पसंदीदा), trivy, या osv-scanner में से एकwkhtmltopdf या pandoc (PDF/DOCX के लिए); अन्यथा आपको report.html (या एक headless-Chrome PDF) मिलता है।ये सभी वैकल्पिक हैं - यदि कोई भी इंस्टॉल नहीं होता है तो पाइपलाइन सहजता से native search + manifest parsing पर आ जाती है।
राउटर को एक प्राकृतिक-भाषा अनुरोध के साथ आमंत्रित करें:``` /sh-router full security review of ./api /sh-router find SQLi and IDOR in src/ /sh-router just map this codebase # recon only
या सीधे पाइपलाइन को कॉल करें:```
/sh-security-review . classes:sqli,access-control,ssrf depth:deep
/sh-security-review . stage:report # regenerate reports for the latest run
प्रत्येक चरण अपने संज्ञानात्मक भार से मेल खाते मॉडल पर चलता है, इसलिए टोकन वहीं खर्च होते हैं जहाँ खोज की गुणवत्ता वास्तव में उन पर निर्भर करती है और यांत्रिक कार्यों पर बचत होती है। यह डिफ़ॉल्ट है - किसी तर्क की आवश्यकता नहीं।
| चरण | डिफ़ॉल्ट मॉडल |
|---|---|
| recon | sonnet |
| hunt (प्रति वर्ग) | पैटर्न वर्गों के लिए haiku (secrets, crypto, open-redirect, csrf) · source→sink ट्रेसिंग के लिए sonnet (sqli, xss, ssrf, injection, path-traversal, xxe, file-upload, auth) · deep-logic वर्गों के लिए opus (access-control, race-conditions, deserialization) |
| chain | opus |
| verify | opus (सटीकता गेट - मजबूत रखा गया) |
| report | haiku |
models: तर्क के साथ ओवरराइड करें (राउटर के माध्यम से भी पास किया गया):```
/sh-security-review . # default tiered map above
/sh-security-review . models:max # every stage + hunter on opus (max quality, max cost)
/sh-security-review . models:cheap # aggressive downshift (trades some verify precision)
/sh-security-review . models:verify=opus,hunt=sonnet # per-stage overrides
/sh-security-review . models:report=sonnet,hunt.pattern=sonnet # per-hunter-tier override
Stages: `setup, recon, hunt, chain, verify, report`. Models: `opus, sonnet, haiku, inherit`. `hunt` के लिए,
एक bare model सभी hunters को उसी पर flatten कर देता है; `hunt.pattern` / `hunt.trace` / `hunt.logic` एक tier को target करते हैं।
अन्य token savers built in हैं: recon केवल उन classes के लिए hunters spawn करता है जिनमें real attack surface हो, hunters
whole files पढ़ने के बजाय Graft graph query करते हैं, और `findings.json`/SARIF model के बजाय एक
deterministic script द्वारा generate होते हैं।
### Output
सब कुछ `<target>/.security-harness/<run-id>/` के अंतर्गत आता है:
- `recon.md`, `codebase-map.json` - the map (stack, SBOM, CVEs, attack surface).
- `findings.jsonl` → `chains.md` → `verified.jsonl` - the working state (देखें `references/state-files.md`).
- `reports/` - `README.md`, `findings.json`, `results.sarif`, `report.html`, `report.pdf` (+ `report.docx`).
प्रत्येक published finding में एक payload, एक PoC, verification verdict, CWE/OWASP ids, CVSS, और एक
code-level mitigation होता है।
## Pull request review
`sh-pr-review` पूरे codebase के बजाय एक single pull request review करता है, परिणाम को
inline comments के रूप में **PR पर ही** post करता है, और एक `security/pr-review` commit
status set करता है जिसे branch protection enforce कर सकता है।
**इसे अपनी मशीन से, किसी भी PR पर जिसे आप पढ़ सकते हैं, चलाएँ।** Plugin install करें और पूछें:```
review https://github.com/acme/api/pull/128
review PR 42
security review this PR
एक PR लिंक पेस्ट करें और यह उस रिपॉज़िटरी में उस PR की समीक्षा करता है, पहले उसे एक अस्थायी डायरेक्टरी में क्लोन करता है, क्योंकि शिकारी केवल पैच नहीं बल्कि फ़ाइलें भी पढ़ते हैं। आप जिस रिपॉज़िटरी में काम कर रहे हैं उसमें कुछ भी नहीं लिखा जाता।
एक बेयर नंबर पास करें और यह आप जिस रिपॉज़िटरी में वर्तमान में हैं, उसके विरुद्ध रिज़ॉल्व करता है, वही
जिसकी ओर git remote इंगित करता है। कुछ भी पास न करें और यह आपकी वर्तमान ब्रांच के लिए खुला PR ले लेता है।
Phase 7 निष्कर्ष और निर्णय प्रिंट करता है और कुछ भी पोस्ट करने से पहले पूछता है - मना करना एक सामान्य परिणाम है, और पेलोड आपके द्वारा बाद में पोस्ट करने के लिए डिस्क पर रहता है।
किसी भी विश्लेषण पर खर्च करने से पहले यह जाँचता है कि आप वास्तव में लक्ष्य रिपॉज़िटरी में लिख सकते हैं या नहीं, इसलिए किसी और के प्रोजेक्ट की समीक्षा करने पर आपको पहले ही पता चल जाता है कि पोस्टिंग 403 देगी, बजाय दस मिनट बाद इसका पता लगाने के।
तीन गुण इसे शोर के बजाय मर्ज गेट के रूप में उपयोगी बनाते हैं:
pr_impact होता है
जो introduced, aggravated, या pre_existing में से एक है। पहले दो ब्लॉक करते हैं; pre_existing
रिपोर्ट किया जाता है और कभी ब्लॉक नहीं करता। उस कोड पर मर्ज ब्लॉक करना जो लेखक ने कभी लिखा ही नहीं, यही तरीका है
जिससे एक आवश्यक चेक हटा दिया जाता है, इसलिए जब कोई शिकारी aggravated और pre_existing के बीच अनिश्चित हो,
तो उसे pre_existing चुनना ही चाहिए।sh-kb-*
बेस उपयोग करते हैं, फिर एक tier चुनता है। Tier 0 (कोई सुरक्षा-प्रासंगिक परिवर्तन नहीं) कुछ भी लॉन्च नहीं करता
और फिर भी स्टेटस सेट करता है। Tier 3 पूरी पाइपलाइन चलाता है।| Verdict | Status | When |
|---|---|---|
| fail | failure | --fail-on (डिफ़ॉल्ट medium) पर या उससे ऊपर introduced या aggravated निष्कर्ष, confidence >= 80 |
| warn | success | कुछ भी introduced या aggravated नहीं; pre-existing निष्कर्ष रिपोर्ट किए गए |
| pass | success | कोई निष्कर्ष नहीं, या triage Tier 0 पर रुक गया |
| error | error | समीक्षा पूरी नहीं हो सकी |
warn जानबूझकर success रिपोर्ट करता है: एक चेतावनी जो मर्ज ब्लॉक करती है, वह अतिरिक्त चरणों वाली विफलता है,
और टीमें चेक को हटाकर प्रतिक्रिया देती हैं। error को failure से अलग रखा जाता है ताकि एक टूटी हुई रन कभी
ऐसी भेद्यता जैसी न दिखे जो उसने नहीं खोजी।
रिव्यू इवेंट हमेशा COMMENT होता है, कभी REQUEST_CHANGES या APPROVE नहीं। कमिट
स्टेटस प्रवर्तन तंत्र है, और यही वह है जिसे branch protection पढ़ता है।
दायरा: स्किल पुल रिक्वेस्ट और कमिट स्टेटस में लिखती है, और कहीं नहीं। यह कोई issue नहीं खोलती और किसी बाहरी tracker में कुछ भी नहीं बनाती।
एक PR को प्रति पुश एक बार रिव्यू किया जाता है, इसलिए दूसरे रिव्यू को पहले से सस्ता होना चाहिए वरना टूल ऐसी चीज़ बन जाता है जिसे लोग बंद कर देते हैं।
Dedup खर्च से पहले होता है, पोस्टिंग से पहले नहीं। PR पर पहले से मौजूद fingerprints Phase 1 में पढ़े जाते हैं और शिकारियों तथा verifier को सौंपे जाते हैं। अंत में डुप्लिकेट खोजने का मतलब होगा कि पाइपलाइन के सबसे महंगे मॉडल ने पहले ही उस निष्कर्ष की पुनः पुष्टि कर दी जो PR पर पूरे समय लिखा हुआ था। इसके लिए किसी cache की आवश्यकता नहीं: स्थिति PR में रहती है, इसलिए यह ठंडी मशीन पर और CI में काम करती है।
एक स्थानीय cache बाकी को इंक्रीमेंटल बनाता है। sh-review-cache प्रत्येक रन के फ़ाइल
हैश, निष्कर्ष और verdicts को आपकी OS cache डायरेक्टरी के अंतर्गत संग्रहीत करता है (कभी रिपॉज़िटरी में नहीं, क्योंकि
एक क्रॉस-रेपो रिव्यू एक अस्थायी क्लोन में चलता है जो हटा दिया जाता है)। अगला रिव्यू केवल उन फ़ाइलों को फिर से
शिकार करता है जिनकी सामग्री वास्तव में बदली है, अपरिवर्तित निष्कर्षों के लिए verdicts का पुनः उपयोग करता है, और
recon map का पुनः उपयोग करता है यदि उसके कवर की गई कोई चीज़ नहीं हिली।
एक base-branch मर्ज में कुछ खर्च नहीं होता। main को PR ब्रांच में मर्ज करने से head
SHA बदल जाता है और लेखक ने जो लिखा उसमें कुछ नहीं, लेकिन एक कमिट स्टेटस एक SHA पर पिन होता है, इसलिए आवश्यक
चेक नए head से चुपचाप गायब हो जाता है। जब PR की अपनी फ़ाइलें byte-identical हों और base delta
उस किसी चीज़ को न छुए जिस पर निष्कर्ष निर्भर करते हैं, तो पिछला verdict बिना कोई agent लॉन्च किए नए SHA पर
फिर से स्टैम्प कर दिया जाता है। यही अंतिम शर्त इसे सुरक्षित बनाती है: एक base मर्ज जो sanitizer हटा देता है,
हर PR फ़ाइल को अपरिवर्तित छोड़ता है जबकि एक सुरक्षित पंक्ति को शोषण-योग्य बना देता है।
Invalidation जानबूझकर रूढ़िवादी है, क्योंकि एक सुरक्षा टूल में पुरानी प्रविष्टि उसे धीमा नहीं बनाती, यह उसे
गलत बनाती है। Cache key हर sh-kb-* नॉलेज बेस को हैश करती है, इसलिए एक KB अपडेट हर cached
निष्कर्ष को अमान्य कर देता है - एक cached "clean" को कभी उस निष्कर्ष को दबाना नहीं चाहिए जिसे पकड़ने के लिए
वह अपडेट लिखा गया था। Model identity, skill version, फ़ाइल सामग्री और 7-दिन का TTL भी सब
अमान्य करते हैं, और एक अनिर्दिष्ट मॉडल को miss माना जाता है।
--no-cache इसे अक्षम करता है, --refresh-cache फिर से बेसलाइन करता है, और run.md प्रति phase
रिकॉर्ड करता है कि क्या लॉन्च किया गया, पुनः उपयोग किया गया और छोड़ा गया, ताकि एक cache जो चुपचाप hit होना
बंद कर दे, वह अनुमान के बजाय दिखाई दे।
रिव्यू और कमिट स्टेटस डिफ़ॉल्ट रूप से पोस्ट किए जाते हैं। एक रिव्यू जो गणना किया गया और
कभी पहुँचाया नहीं गया, उसने किसी की मदद नहीं की। --confirm पोस्ट करने से पहले एक प्रॉम्प्ट बहाल करता है,
--dry-run कुछ नहीं भेजता, --no-status रिव्यू पोस्ट करता है लेकिन कमिट स्टेटस को अकेला छोड़ देता है।
पोस्टिंग हाथ से बनाए गए API कॉल के बजाय scripts/sh-pr-post.py के माध्यम से होती है, क्योंकि यह
एक बहु-चरणीय ऑपरेशन है जिसमें एक अनिवार्य tail होता है: रिव्यू, फिर स्टेटस, फिर receipts, जिसमें
एक 422 को पंक्ति संख्या खिसकाने के बजाय टिप्पणी को हटाकर ठीक किया जाता है। स्क्रिप्ट
कभी स्टेटस को pending पर छोड़कर बाहर नहीं निकलती - यदि रिव्यू पोस्ट नहीं किया जा सकता तो भी यह
error सेट करती है, यह कहते हुए कि tooling विफल हुई न कि PR पर आरोप लगाते हुए।
Inline टिप्पणियाँ medium या उससे ऊपर के निष्कर्षों के लिए आरक्षित हैं जिनका confidence >= 80 हो। कम-गंभीरता वाले निष्कर्ष collapsed body सेक्शन में जाते हैं, इसलिए शून्य inline टिप्पणियों के साथ दिखने वाला कम-प्राथमिकता वाला निष्कर्ष नीति के काम करने का परिणाम है, विफलता नहीं।
प्रत्येक रन रिकॉर्ड करता है कि उस पर क्या खर्च हुआ, ताकि "cache काम कर रहा है" और "रिव्यू धीमे हो गए" जैसी बातें राय के विषय न रहें।```bash python3 /scripts/sh-metrics.py path # where records live python3 /scripts/sh-metrics.py report # aggregate, by model python3 /scripts/sh-metrics.py purge --older-than-days 30
दो append-only JSONL फ़ाइलें - `runs.jsonl` (repo, PR, tier, verdict, totals, आपके द्वारा पास किए गए flags) और `events.jsonl` (प्रत्येक phase या agent के लिए एक पंक्ति: model, tokens, duration, outcome, क्या इसे cache से पुनः उपयोग किया गया था)। JSONL इसलिए ताकि crash होने पर भी crash के ऊपर valid पंक्तियाँ बनी रहें।
| Platform | Metrics | Cache |
|---|---|---|
| **Linux / BSD** | `$XDG_DATA_HOME/security-harness/metrics`<br>default `~/.local/share/security-harness/metrics` | `$XDG_CACHE_HOME/security-harness`<br>default `~/.cache/security-harness` |
| macOS | `~/Library/Application Support/security-harness/metrics` | `~/Library/Caches/security-harness` |
| Windows | `%LOCALAPPDATA%\security-harness\metrics` | `%LOCALAPPDATA%\security-harness\cache` |
Linux XDG Base Directory spec का पालन करता है, इसलिए दोनों सेट होने पर `XDG_DATA_HOME` और
`XDG_CACHE_HOME` का सम्मान करते हैं और सेट न होने पर `~/.local/share` और `~/.cache` पर वापस चले जाते हैं। `SH_METRICS_DIR` और `SH_REVIEW_CACHE_DIR` के साथ किसी भी एक को सीधे override करें।
**`python` बनाम `python3` पर:** अधिकांश Linux distributions `python3` के साथ आते हैं और उनमें `python` बिल्कुल नहीं होता, इसलिए यहाँ के उदाहरण `python3` का उपयोग करते हैं। bundled scripts में `#!/usr/bin/env python3` shebang होता है और वे executable हैं, इसलिए `./scripts/sh-metrics.py report` Linux और macOS पर सीधे काम करता है। skill प्रति run एक बार `PY="$(command -v python3 || command -v python)"` resolve करता है, जो Windows पर Git Bash सहित तीनों platforms को cover करता है।
**पूरी तरह local।** दोनों scripts में कोई network code या reporting endpoint नहीं है। token-जैसा कुछ भी लिखे जाने से पहले redact कर दिया जाता है, क्योंकि local files issues में paste हो जाती हैं।
### इसे unattended चलाना
वैकल्पिक, और skill का उपयोग करने से एक अलग निर्णय। पहले कुछ समय अपने PRs पर इसे हाथ से चलाएँ, ताकि आपकी team के सामने कहने से पहले आप जान लें कि यह आपके codebase के बारे में क्या कहता है।
जब आप तैयार हों, [`references/pr-review-mapping.md`](https://github.com/dmdhrumilmistry/security-harness/blob/main/plugins/security-harness/references/pr-review-mapping.md) में "Enforcing the check on a repository" में **आपके** repo के लिए एक copy-paste workflow है, साथ ही वह fail-safe भी जो एक मृत job को required check को `pending` पर अटके रहने से रोकता है।
threshold default `medium` पर ही रहता है। पहले से मौजूद findings कभी merge को block नहीं करते, इसलिए एक unscanned codebase पहले दिन लाल रंग की दीवार नहीं बनाता - केवल वही जो कोई PR वास्तव में पेश करता है या बिगाड़ता है, उसे fail करा सकता है।
## यह कैसे काम करता है
1. **Setup** - उपलब्ध tools की जाँच करें, scope परिभाषित करें, run directory बनाएँ।
2. **Recon** (`sh-recon`) - Graft graph बनाएँ; stack/versions detect करें; SBOM + CVEs; entry points, trust boundaries, और dangerous sinks की गणना करें।
3. **Hunt** (`sh-hunter` ×N, parallel) - प्रत्येक relevant class के लिए एक hunter अपना `sh-kb-*` knowledge base load करता है, attacker input को source से sink तक trace करता है, और candidates record करता है। एक साझा **attempts ledger** agents को एक-दूसरे की probes दोहराने से रोकता है।
4. **Chain** (`sh-chainer`) - findings को उच्च-गंभीरता वाले attack paths में compose करें।
5. **Verify** (`sh-verifier`) - पहले खंडन करें, फिर evidence से exploitability की पुष्टि करें, PoCs बनाएँ, CVSS assign करें, और false positives काटें।
6. **Report** (`sh-reporter`) - deliverables तैयार करें।
Subagents files के अलावा कुछ साझा नहीं करते; contract `plugins/security-harness/references/state-files.md` में है।
## विस्तार करना
साझा template का पालन करते हुए `skills/sh-kb-<class>/SKILL.md` बनाकर एक नई vulnerability class जोड़ें
(When to hunt · Sources & sinks · Detection recipe · Payloads/PoC · False-positive filters · CWE/OWASP ·
Chaining hints · Mitigation), फिर उसका slug `references/finding-schema.json` में `class` enum और
`skills/sh-router/SKILL.md` में routing table में जोड़ें।
## स्वचालित knowledge-base अपडेट
एक scheduled GitHub Action (`.github/workflows/update-knowledge-base.yml`) `sh-kb-*` knowledge
bases को ताज़ा रखता है। **हर दूसरे दिन** (और manual `workflow_dispatch` पर), यह एक agent चलाता है जो नई,
प्रतिष्ठित सार्वजनिक security research - OWASP, PortSwigger Research, CWE/CAPEC, NIST, MDN, curated GitHub
repos, और सार्वजनिक HackerOne disclosures - को छोटे, अच्छी तरह sourced सुधारों में distill करता है। फिर एक **दूसरा, adversarial
reviewer agent** परिणामी diff को दुर्भावनापूर्ण/injected content के लिए scan करता है, और PR
**केवल तभी auto-merged होता है जब वह reviewer approve करता है**।
### दो workflows, तीन jobs
PR creation को जानबूझकर review और merge से अलग रखा गया है, ताकि जो diff लिखता है वह कभी वह न हो जो इसे ship करने का निर्णय लेता है।
**Stage 1 - [`update-knowledge-base.yml`](https://github.com/dmdhrumilmistry/security-harness/blob/main/.github/workflows/update-knowledge-base.yml)**
(scheduled या manual)। एक job, `create-pr`:
1. **Generate** - agent allowlisted sources से KB को edit करता है। कोई commit नहीं, कोई push नहीं।
2. **Open PR** - एक deterministic step `automated/kb-update` branch पर एक PR खोलता है (या update करता है), जिस पर `awaiting-review` label लगा होता है।
3. **Hand off** - सफल PR creation पर यह PR number के साथ stage 2 को dispatch करता है।
**Stage 2 - [`kb-review-and-merge.yml`](https://github.com/dmdhrumilmistry/security-harness/blob/main/.github/workflows/kb-review-and-merge.yml)**
(stage 1 द्वारा dispatched, या किसी भी automated PR के विरुद्ध हाथ से चलाया गया)। दो jobs:
- **`review`** - एक *अलग* agent run diff को **adversarially** जाँचता है
prompt-injection artifacts, out-of-scope edits, secrets/exfil, PII, weaponized
exploits, off-allowlist sourcing, या house-style violations के लिए। इसमें **कोई web नहीं और कोई
shell नहीं** है, और यह **fail closed** करता है: कुछ भी संदिग्ध, कोई भी अनिश्चितता, या एक गायब
verdict file → REJECT। verdict एक PR comment के रूप में पोस्ट किया जाता है और label को नियंत्रित करता है।
- **`merge`** - **केवल** `APPROVE` पर चलता है, और PR को merge करता है। एक `REJECT` इसे skip कर देता है और
`blocked` job बताता है कि क्यों।
> **`pull_request` trigger के बजाय dispatch क्यों:** `GITHUB_TOKEN` द्वारा खोला गया PR
> `pull_request` workflows को trigger नहीं करता। `workflow_dispatch` उन दो events में से एक है
> जो उस recursion guard से मुक्त हैं, इसलिए stage 1 विश्वसनीय रूप से hand off कर सकता है।
**Auto-merge का अर्थ है कि एक approving agent `main` में code land करता है।** उस पर नियंत्रण:
- merge job किसी भी ऐसे PR को अस्वीकार करता है जो closed है, किसी fork से है, या जिसकी head branch
`automated/*` के बाहर है (workflow में `ALLOWED_HEAD_PREFIX`)।
- यह GitHub के अपने auto-merge को प्राथमिकता देता है, इसलिए **branch protection अभी भी लागू रहता है**। `main` पर एक rule
के साथ जो approving review की माँग करता है, PR queue में लग जाता है और merge होने के बजाय एक इंसान का इंतज़ार करता है। यह
केवल उन repos पर तत्काल merge पर वापस जाता है जहाँ auto-merge बंद है।
- merge किए बिना review करने के लिए manual run पर `auto_merge` input को `false` पर सेट करें।
- reviewer prompt agent को बताता है कि उसका verdict binding है, advisory नहीं।
> इसके लिए repo setting **"Allow GitHub Actions to create and approve pull requests"** (Settings →
> Actions → General → Workflow permissions) चाहिए ताकि workflow PR खोल सके। यदि आप auto-merge के बावजूद एक इंसान को
> loop में चाहते हैं, तो `main` को एक branch-protection rule से सुरक्षित करें जो एक pull request और कम से कम
> एक approving review की माँग करता है - auto-merge path इसका सम्मान करता है।
### Pluggable agents
दोनों stages [`.github/actions/ai-agent`](https://github.com/dmdhrumilmistry/security-harness/blob/main/.github/actions/ai-agent/action.yml) के माध्यम से चलते हैं,
एक composite action जो उस agent को dispatch करता है जिसे आप configure करते हैं। Claude Code, OpenAI
Codex, Gemini CLI, और बाकी किसी भी चीज़ के लिए एक escape hatch:
| `agent` | Runs | Credential |
|---|---|---|
| `claude` (default) | `anthropics/claude-code-action@v1` | `CLAUDE_CODE_OAUTH_TOKEN` या `ANTHROPIC_API_KEY` |
| `codex` | `codex exec --full-auto` | `OPENAI_API_KEY` |
| `gemini` | `gemini --yolo --prompt` | `GEMINI_API_KEY` |
| `custom` | आपका `KB_AGENT_INSTALL` / `KB_AGENT_COMMAND` | जो भी इसे चाहिए |
प्रति run `workflow_dispatch` inputs से चुनें, या default बदलने के लिए repo variables सेट करें: generator के लिए `KB_AGENT` और `KB_MODEL`, reviewer के लिए `KB_REVIEW_AGENT` और
`KB_REVIEW_MODEL`। generator और reviewer को **अलग-अलग
agents** पर चलाना एक सार्थक hardening step है: एक model के लिए tuned injection के दूसरे, स्वतंत्र model पर लगने की संभावना कम होती है।
`agent: custom` के लिए, `KB_AGENT_COMMAND` को एक shell command पर सेट करें। prompt उस
file में लिखा जाता है जिसका नाम `$AGENT_PROMPT_FILE` है, और `$AGENT_MODEL` model input ले जाता है।
Prompt-injection defenses, क्योंकि generator खुले web को पढ़ता है:
- **Domain allowlist.** `WebFetch` `.github/kb-update/trusted-sources.md` में भरोसेमंद domains तक सीमित है (workflow के `--allowedTools` में mirrored)। `WebSearch` URLs
खोज सकता है, लेकिन केवल allowlisted domains ही वास्तव में fetch किए जा सकते हैं।
- **Content data है, commands नहीं।** task prompt (`.github/kb-update/prompt.md`) Claude को निर्देश देता है कि
हर fetched byte को अविश्वसनीय reference material माने और किसी page में embedded किसी भी instruction को अनदेखा करे - HackerOne report bodies (user-generated) को उच्चतम-जोखिम tier के रूप में flag किया जाता है।
- **generator पर कोई shell नहीं, कोई push नहीं; reviewer ही gate है।** generator केवल files edit कर सकता है।
स्वतंत्र reviewer (`.github/kb-update/review-prompt.md`) वही है जो fetched content
और `main` के बीच खड़ा है - इसकी स्पष्ट approval के बिना कुछ merge नहीं होता।
- **generator और reviewer के लिए अलग agents।** वैकल्पिक, और gate का सबसे मजबूत संस्करण: `KB_AGENT` और `KB_REVIEW_AGENT` को दो अलग engines पर सेट करें।
**Setup:**
- जो भी agent आप उपयोग करते हैं उसके लिए credential जोड़ें (Settings → Secrets and variables → Actions):
**`CLAUDE_CODE_OAUTH_TOKEN`** (default), `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, या `GEMINI_API_KEY`।
OAuth token metered API key के बजाय **आपकी Claude subscription की usage limits** के विरुद्ध authenticate करता है - इसे locally `claude setup-token` से generate करें (एक सक्रिय Claude Pro/Max subscription आवश्यक है)
और परिणाम paste करें।
- **"Allow GitHub Actions to create and approve pull requests"** enable करें (Settings → Actions → General →
Workflow permissions) ताकि workflow अपना PR खोल सके। अनुशंसित: `main` पर एक branch-protection rule जोड़ें
जो एक PR और एक approving review की माँग करता है, ताकि auto-merge चालू होने पर भी कोई automated change किसी इंसान के बिना land न कर सके।
- यह बदलने के लिए कि कौन से sources allowed हैं, `trusted-sources.md` में allowlist **और** workflow में मेल खाती
`WebFetch(domain:...)` entries edit करें - दोनों को sync में रखें।
प्रत्येक run ने क्या किया, यह `.github/kb-update/last-run-summary.md` में record करता है।
## Roadmap
- ~~Codex / Cursor mirror wiring.~~
✅ Shipped: `AGENTS.md`, एक Gemini CLI extension, और `.agents/skills` तथा opencode के लिए `scripts/sync-agent-skills.py`।
देखें [`docs/DISTRIBUTION.md`](https://github.com/dmdhrumilmistry/security-harness/blob/main/docs/DISTRIBUTION.md)।
- ~~curated references के ऊपर knowledge bases का optional live-fetch augmentation (PortSwigger/OWASP/CWE)।~~
✅ ऊपर दिए गए scheduled knowledge-base updater के रूप में Shipped।
- `needs-runtime` findings की runtime confirmation के लिए optional DAST bridge।
## License
MIT