torusguard 0.9.3 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.torusguard/.manifest.json +2 -2
- package/.torusguard/config/torusguard.json +1 -1
- package/.torusguard/skills/torusguard/SKILL.md +11 -7
- package/README.md +214 -104
- package/bin/torusguard.js +90 -30
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +2 -2
- package/skills/torusguard/__pycache__/bootstrap.cpython-311.pyc +0 -0
- package/skills/torusguard/bootstrap.py +194 -68
- package/skills/torusguard/payload/.manifest.json +2 -2
- package/skills/torusguard/payload/config/torusguard.json +1 -1
- package/skills/torusguard/payload/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
- package/skills/torusguard/payload/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +11 -7
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"agents/validator.md": "79fc4431de5c5507f8730aee6c5c3e61fd238cbf8cf8c7c6aac462eee9761ed6",
|
|
9
9
|
"config/scope.json": "b198a86186b4c6d5e1af516bf4e3a6afa8878e622ca1d57a5bf72d294f8c6f25",
|
|
10
10
|
"config/slash-commands.json": "5390f0d26f8117a62e56c58147d3a0d2deab1a20956302b212703281d13fa84e",
|
|
11
|
-
"config/torusguard.json": "
|
|
11
|
+
"config/torusguard.json": "077bc6a948f9420aded8dba248577ff3ebf054cab64cf538a7a6d05223fe27bc",
|
|
12
12
|
"references/django-security.md": "a15b7eb11b51dd1970d3d65544cf79ebea91fb99dc0e085e58a56532a718dce7",
|
|
13
13
|
"references/drf-security.md": "c7a7af3acaef895bf4798590acc88b3a2e9831a49eb2d23b4d8f31540ab264cc",
|
|
14
14
|
"references/express-security.md": "dff1db15e614d29d8c272f9da345b418077e62dc883fe210c7a50c552c76493f",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"scripts/safety_gate.py": "3379b7534b2590cf563717a448983ad8ed7e8f174f0ad65683d33e8a10f51558",
|
|
41
41
|
"scripts/sarif_exporter.py": "35c66637413afc4b72d5bd426638447c77231d2a8594dce5addceffd4803a20d",
|
|
42
42
|
"scripts/stack_detect.py": "99b7bdf9829d58ff5b8c59afd6e8b6429bbb11d830ac73dec491101cbbc41574",
|
|
43
|
-
"skills/torusguard/SKILL.md": "
|
|
43
|
+
"skills/torusguard/SKILL.md": "31a115886ffb115f2b975c4d0670e780e11ea68201559b24b20d0d0ef456058f",
|
|
44
44
|
"skills/torusguard/bootstrap.py": "7e348065a622089ab1d51e9bf4864e5b0022aaee1ccb2ecbf7057c14e792e2c7",
|
|
45
45
|
"skills/torusguard/references/auth-and-sessions.md": "34c2843f8c0dbe3574e54f00a39a92a1f431527ec5f69b2d64c84240d424a39e",
|
|
46
46
|
"skills/torusguard/references/business-logic-and-abuse.md": "0d6088936bc1a01023070332fccef0f2e0734358a5119379055f3d2895c22567",
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: torusguard
|
|
3
|
-
description:
|
|
4
|
-
version: 0.9.
|
|
3
|
+
description: "Autonomous security engine: 71 rules across 11 families, governed remediation (Ponytail Protocol), SARIF v2.1.0 exports, and 5-agent authority separation for Python & TypeScript web applications."
|
|
4
|
+
version: 0.9.5
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# TorusGuard Master Router
|
|
7
|
+
# TorusGuard Master Security Router
|
|
8
8
|
|
|
9
|
-
**Principle:** If the browser receives it, users can inspect it. Keep secrets,
|
|
9
|
+
**Principle:** If the browser receives it, users can inspect it. Keep secrets, database queries, and authorization strictly on trusted server-side code.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
## ⚡ Workspace Bootstrap Check
|
|
14
|
-
1. **If `.torusguard/` exists:**
|
|
15
|
-
2. **If `.torusguard/` is
|
|
14
|
+
1. **If `.torusguard/` exists on disk:** Full governance active. Route slash commands to local specialist workflows below.
|
|
15
|
+
2. **If `.torusguard/` is absent (Autonomous AI Mode):** Operates standalone in any AI agent (Kimi, Antigravity, VS Code, Cursor). Apply in-memory security invariants:
|
|
16
|
+
- Server-side auth & tenant scoping (`.filter(tenant=...)`).
|
|
17
|
+
- Zero client-side secrets (`SUPABASE_SERVICE_ROLE_KEY`, live API keys).
|
|
18
|
+
- Ponytail Protocol patch limits ($\le 35$ additions, $\le 25$ deletions).
|
|
19
|
+
- *Upgrade:* Run `npx torusguard init` to unlock local `.torusguard/` run tracking & individual commands.
|
|
16
20
|
|
|
17
21
|
---
|
|
18
22
|
|
|
19
23
|
## Specialist Skill Routing (Lazy Loading)
|
|
20
|
-
Load **only** the designated sub-skill
|
|
24
|
+
Load **only** the designated sub-skill on demand to preserve the 1,000–1,500 token budget:
|
|
21
25
|
|
|
22
26
|
| Command | Specialist Skill | Agent |
|
|
23
27
|
| :--- | :--- | :--- |
|
package/README.md
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<img src="TorusGuard.png" alt="TorusGuard Security Banner" width="480" style="max-width: 100%; height: auto; border-radius: 8px;">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/githubmofo/TorusGuard/main/TorusGuard.png" alt="TorusGuard Security Banner" width="480" style="max-width: 100%; height: auto; border-radius: 8px;">
|
|
3
3
|
|
|
4
4
|
# TorusGuard
|
|
5
5
|
|
|
6
|
-
**Security
|
|
6
|
+
**Autonomous Security Guardrails, Governed Remediation, and Authorized Runtime Validation for AI-Built Web Applications.**
|
|
7
7
|
|
|
8
8
|
[](https://www.npmjs.com/package/torusguard)
|
|
9
|
-
[](https://github.com/githubmofo/TorusGuard/pkgs/npm/torusguard)
|
|
10
|
+
[](https://github.com/githubmofo/TorusGuard/releases/latest)
|
|
10
11
|
[](LICENSE)
|
|
11
12
|
[](https://python.org)
|
|
12
13
|
[](https://nodejs.org)
|
|
13
|
-
[](schemas/)
|
|
14
|
+
[](.torusguard/schemas/)
|
|
14
15
|
[](.torusguard/.manifest.json)
|
|
15
16
|
[](docs/architecture/SECURITY_ARCHITECTURE.md)
|
|
16
17
|
</div>
|
|
@@ -19,79 +20,94 @@
|
|
|
19
20
|
|
|
20
21
|
## 💡 Executive Summary
|
|
21
22
|
|
|
22
|
-
Modern AI coding agents generate full-stack applications
|
|
23
|
+
Modern AI coding agents generate full-stack web applications at unprecedented velocity. However, they consistently introduce critical security anti-patterns: leaking service-role credentials to browser bundles, omitting multi-tenant query boundaries, disabling CSRF defenses, or granting unconstrained tool permissions.
|
|
23
24
|
|
|
24
|
-
**TorusGuard** is an autonomous application security co-pilot specifically
|
|
25
|
+
**TorusGuard** is an autonomous application security co-pilot specifically engineered for AI-built software. It integrates natively into your development environment (Antigravity, Cursor, Claude Code, VS Code Copilot, Kimi, Windsurf, Cline) to deliver:
|
|
25
26
|
|
|
26
|
-
1. **
|
|
27
|
-
2. **
|
|
28
|
-
3. **
|
|
29
|
-
4. **
|
|
27
|
+
1. **Deterministic Static Auditing:** Scan Python and TypeScript source code using 71 specialized security rules across 11 families.
|
|
28
|
+
2. **Authorized Runtime Validation:** Execute bounded, non-destructive HTTP probes to eliminate false alarms and confirm real exploitability.
|
|
29
|
+
3. **Governed Minimal Remediation:** Generate surgical, reviewable patches constrained by the **Ponytail Protocol** ($\le 35$ additions, $\le 25$ deletions) to eliminate unintended regressions.
|
|
30
|
+
4. **Open Industry Standards:** Emit OASIS SARIF v2.1.0 telemetry with stable AST line-shift invariant hashes for native GitHub Code Scanning integration.
|
|
30
31
|
|
|
31
|
-
### 🌐 The Core
|
|
32
|
+
### 🌐 The Core Invariant: The Browser-Code Truth
|
|
32
33
|
> **"If the browser receives it, users can inspect it."**
|
|
33
|
-
>
|
|
34
|
+
> Frontend environment variables, JavaScript network bundles, and React Server Action payloads cannot conceal secrets. TorusGuard strictly enforces that database credentials, private API keys, and authorization barriers remain exclusively on trusted server boundaries.
|
|
34
35
|
|
|
35
36
|
---
|
|
36
37
|
|
|
37
38
|
## ⚡ Dual-Track Distribution Architecture
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
TorusGuard features a decoupled **Dual-Track Architecture** allowing teams to choose between zero-setup in-memory agent intelligence and full repository governance:
|
|
40
41
|
|
|
41
42
|
```mermaid
|
|
42
43
|
flowchart TD
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
subgraph Core ["🛡️ TorusGuard Core Intelligence Engine"]
|
|
45
|
+
Rules["71 Canonical Security Rules"]
|
|
46
|
+
Ponytail["Ponytail Patch Governor (<=35 add, <=25 del)"]
|
|
47
|
+
Scorer["5-Factor Mathematical Confidence Scorer"]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Core --> Track1["⚡ Track 1: Universal AI Agent Skill"]
|
|
51
|
+
Core --> Track2["🛡️ Track 2: Production NPM Package"]
|
|
52
|
+
|
|
53
|
+
subgraph Track1Scope ["Track 1: In-Memory Agent Execution"]
|
|
54
|
+
T1Cmd["npx skills add ... -a universal -y"]
|
|
55
|
+
T1Env["Works in ANY AI Agent (Cursor, Kimi, Antigravity, Copilot)"]
|
|
56
|
+
T1Disk["Zero local file footprint (pure in-memory reasoning)"]
|
|
57
|
+
T1Router["Single clean slash command: /torusguard"]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
subgraph Track2Scope ["Track 2: Full Local Governance"]
|
|
61
|
+
T2Cmd["npx torusguard init / npm i -D torusguard"]
|
|
62
|
+
T2Env["Persistent .torusguard/ repository workspace"]
|
|
63
|
+
T2CLI["Native Terminal CLI: npx torusguard status / audit"]
|
|
64
|
+
T2Palette["Unlocks all 11 individual slash commands (/torusguard-*)"]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
Track1 --> Track1Scope
|
|
68
|
+
Track2 --> Track2Scope
|
|
69
|
+
|
|
70
|
+
Track1Scope -. Harmonizes with .- Track2Scope
|
|
56
71
|
```
|
|
57
72
|
|
|
58
73
|
### Track Comparison Matrix
|
|
59
74
|
|
|
60
|
-
|
|
|
75
|
+
| Capability | ⚡ Track 1: Universal AI Agent Skill | 🛡️ Track 2: Production NPM Package |
|
|
61
76
|
| :--- | :--- | :--- |
|
|
62
|
-
| **
|
|
63
|
-
| **
|
|
64
|
-
| **
|
|
65
|
-
| **Slash Commands** | Single
|
|
66
|
-
| **
|
|
67
|
-
| **
|
|
77
|
+
| **Primary Command** | `npx skills add https://github.com/githubmofo/TorusGuard -a universal -y` | `npx torusguard init` or `npm install -D torusguard` |
|
|
78
|
+
| **Supported Agents** | All AI Agents (Antigravity, Cursor, Claude Code, Copilot, Kimi, Windsurf) | Any Node/Python repository, GitHub Actions CI/CD, Antigravity, Cursor |
|
|
79
|
+
| **Disk Footprint** | In-memory agent context (`.agents/skills/torusguard/` only) | Complete local workspace (`.torusguard/` with config, rules, schemas, runs) |
|
|
80
|
+
| **Slash Commands** | Single master dispatcher: `/torusguard` | Full 11-command palette: `/torusguard-audit`, `/torusguard-apply`, etc. |
|
|
81
|
+
| **Terminal CLI** | None (AI chat-driven) | Native terminal runner: `npx torusguard status`, `npx torusguard audit` |
|
|
82
|
+
| **Prerequisites** | None (pure AI agent execution) | Node.js 18+ (and Python 3.10+ for native verification scripts) |
|
|
83
|
+
| **Best For** | Instant zero-setup security advice in chat | Production repositories, team compliance, CI/CD SARIF exports |
|
|
68
84
|
|
|
69
85
|
---
|
|
70
86
|
|
|
71
87
|
## 🚀 Installation & Quick Start
|
|
72
88
|
|
|
73
|
-
Choose the path that fits your development workflow:
|
|
74
|
-
|
|
75
89
|
### Track 1: Universal AI Agent Skill (Zero Setup)
|
|
76
|
-
Install directly into any AI assistant
|
|
90
|
+
Install directly into any AI assistant adhering to the Open Agent Skills standard:
|
|
77
91
|
```bash
|
|
78
|
-
|
|
92
|
+
# Recommended one-liner (silent, zero-prompts, targets all IDE agents):
|
|
93
|
+
npx skills add https://github.com/githubmofo/TorusGuard -a universal -y
|
|
79
94
|
```
|
|
95
|
+
* **`-a universal`**: Automatically registers the skill for Antigravity, Cursor, Gemini CLI, Claude Code, VS Code Copilot, and Kimi without prompt friction.
|
|
96
|
+
* **`-y`**: Bypasses interactive confirmation prompts and completes in **under 2 seconds**.
|
|
80
97
|
* Once installed, simply type `/torusguard` in chat or ask: *"Audit this component for security flaws"*.
|
|
81
|
-
* Operates immediately with zero project configuration required.
|
|
82
98
|
|
|
83
99
|
### Track 2: Production NPM Package (Full Governance)
|
|
84
|
-
Scaffold your repository with
|
|
100
|
+
Scaffold your repository with local configuration, offline scripts, and granular workflows:
|
|
85
101
|
```bash
|
|
86
102
|
# Direct runner (recommended):
|
|
87
103
|
npx torusguard init
|
|
88
104
|
|
|
89
|
-
# Or install as a
|
|
105
|
+
# Or install as a development dependency:
|
|
90
106
|
npm install -D torusguard
|
|
91
107
|
```
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* Run
|
|
108
|
+
* Generates the `.torusguard/` workspace directory.
|
|
109
|
+
* Populates your IDE command palette with all 11 individual `/torusguard-*` workflows.
|
|
110
|
+
* Run instant terminal checks anytime:
|
|
95
111
|
```bash
|
|
96
112
|
npx torusguard status
|
|
97
113
|
npx torusguard audit
|
|
@@ -100,7 +116,7 @@ npm install -D torusguard
|
|
|
100
116
|
### Standalone Python Installer (Alternative)
|
|
101
117
|
For Python-only environments, Docker containers, or air-gapped CI/CD runners:
|
|
102
118
|
```bash
|
|
103
|
-
#
|
|
119
|
+
# From cloned repository:
|
|
104
120
|
python install.py
|
|
105
121
|
|
|
106
122
|
# Or via remote one-liner:
|
|
@@ -113,7 +129,7 @@ curl -sSL https://raw.githubusercontent.com/githubmofo/TorusGuard/main/install.p
|
|
|
113
129
|
|
|
114
130
|
When Track 2 is initialized, the complete 11-command palette becomes available in your IDE (`.agent/workflows/`, `.agents/workflows/`, `.claude/commands/`, `.cursor/rules/`):
|
|
115
131
|
|
|
116
|
-
| Slash Command | Specialist Skill | Lifecycle Phase |
|
|
132
|
+
| Slash Command | Specialist Skill | Lifecycle Phase | Operational Description | Code Changed? |
|
|
117
133
|
| :--- | :--- | :---: | :--- | :---: |
|
|
118
134
|
| `/torusguard` | `skills/torusguard` | Router | Master natural-language command dispatcher and prompt auditor. | No |
|
|
119
135
|
| `/torusguard init`<br>*(or `/torusguard-init`)* | `skills/torusguard-init` | Phase 0 | Profiles repository stack, discovers frameworks, and enables matching rules. | Yes (`.torusguard/`) |
|
|
@@ -133,33 +149,37 @@ When Track 2 is initialized, the complete 11-command palette becomes available i
|
|
|
133
149
|
|
|
134
150
|
## 🔄 The 7-Stage Closed-Loop Finding Lifecycle
|
|
135
151
|
|
|
136
|
-
Every candidate vulnerability transitions through an auditable, deterministic state machine:
|
|
152
|
+
Every candidate vulnerability transitions through an auditable, deterministic state machine with zero regression tolerance:
|
|
137
153
|
|
|
138
154
|
```mermaid
|
|
139
155
|
flowchart LR
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
style
|
|
148
|
-
style
|
|
149
|
-
style
|
|
150
|
-
style
|
|
151
|
-
style
|
|
152
|
-
style
|
|
153
|
-
style
|
|
156
|
+
Detect["1. Detect<br>/torusguard audit"] --> Classify["2. Classify<br>AST Line Hashing"]
|
|
157
|
+
Classify --> Verify["3. Verify<br>verify / web-validate"]
|
|
158
|
+
Verify --> Remediate["4. Remediate<br>/torusguard harden"]
|
|
159
|
+
Remediate --> Apply["5. Apply<br>/torusguard apply"]
|
|
160
|
+
Apply --> Recheck["6. Recheck<br>/torusguard recheck"]
|
|
161
|
+
Recheck --> Report["7. Report<br>/torusguard report"]
|
|
162
|
+
|
|
163
|
+
style Detect fill:#1e293b,stroke:#3b82f6,stroke-width:2px,color:#fff
|
|
164
|
+
style Classify fill:#1e293b,stroke:#6366f1,stroke-width:2px,color:#fff
|
|
165
|
+
style Verify fill:#1e293b,stroke:#8b5cf6,stroke-width:2px,color:#fff
|
|
166
|
+
style Remediate fill:#1e293b,stroke:#ec4899,stroke-width:2px,color:#fff
|
|
167
|
+
style Apply fill:#1e293b,stroke:#f59e0b,stroke-width:2px,color:#fff
|
|
168
|
+
style Recheck fill:#1e293b,stroke:#10b981,stroke-width:2px,color:#fff
|
|
169
|
+
style Report fill:#1e293b,stroke:#06b6d4,stroke-width:2px,color:#fff
|
|
154
170
|
```
|
|
155
171
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
172
|
+
### Lifecycle Stage Breakdown
|
|
173
|
+
|
|
174
|
+
| Stage | Command | Responsible Agent | Primary Activity & Invariant Guarantee |
|
|
175
|
+
| :---: | :--- | :---: | :--- |
|
|
176
|
+
| **1. Detect** | `/torusguard audit` | `auditor` | Static AST and regex inspection flags potential vulnerabilities across Python and TypeScript. |
|
|
177
|
+
| **2. Classify** | *(automatic)* | `auditor` | Computes line-shift invariant `primaryLocationLineHash` fingerprints and clusters repeated instances into root causes. |
|
|
178
|
+
| **3. Verify** | `/torusguard verify` | `validator` | Applies a 5-factor mathematical scoring model (0–100) and executes authorized, bounded runtime HTTP probes. |
|
|
179
|
+
| **4. Remediate** | `/torusguard harden` | `remediator` | Generates self-contained Remediation Bundles containing unified diffs and rollbacks. |
|
|
180
|
+
| **5. Apply** | `/torusguard apply` | `remediator` | Takes pre-apply file snapshots and enforces **Ponytail bounds** ($\le 35$ additions, $\le 25$ deletions). |
|
|
181
|
+
| **6. Recheck** | `/torusguard recheck` | `reviewer` | Performs differential re-audit strictly on modified files to verify fix closure without introducing new flaws. |
|
|
182
|
+
| **7. Report** | `/torusguard report` | `reviewer` | Synthesizes an executive Markdown summary and exports an OASIS SARIF v2.1.0 file for CI/CD tracking. |
|
|
163
183
|
|
|
164
184
|
---
|
|
165
185
|
|
|
@@ -169,27 +189,32 @@ To eliminate AI confirmation bias, security responsibilities are divided across
|
|
|
169
189
|
|
|
170
190
|
```mermaid
|
|
171
191
|
flowchart TD
|
|
172
|
-
subgraph Discovery
|
|
173
|
-
P["🔍 Profiler Agent<br
|
|
192
|
+
subgraph DiscoveryPhase ["Discovery Phase"]
|
|
193
|
+
P["🔍 Profiler Agent<br>profiler.md"]
|
|
174
194
|
end
|
|
175
|
-
|
|
176
|
-
|
|
195
|
+
|
|
196
|
+
subgraph DetectionPhase ["Detection Phase"]
|
|
197
|
+
A["🔎 Auditor Agent<br>auditor.md"]
|
|
177
198
|
end
|
|
178
|
-
|
|
179
|
-
|
|
199
|
+
|
|
200
|
+
subgraph VerificationPhase ["Verification Phase"]
|
|
201
|
+
V["🧪 Validator Agent<br>validator.md"]
|
|
180
202
|
end
|
|
181
|
-
|
|
182
|
-
|
|
203
|
+
|
|
204
|
+
subgraph RemediationPhase ["Remediation Phase"]
|
|
205
|
+
R["🛠️ Remediator Agent<br>remediator.md"]
|
|
183
206
|
end
|
|
184
|
-
|
|
185
|
-
|
|
207
|
+
|
|
208
|
+
subgraph ReviewPhase ["Review & Sign-Off Phase"]
|
|
209
|
+
REV["⚖️ Reviewer Agent<br>reviewer.md"]
|
|
210
|
+
HumanGate["👤 Human Gate (Approval)"]
|
|
186
211
|
end
|
|
187
212
|
|
|
188
213
|
P -->|Stack Profile| A
|
|
189
214
|
A -->|Static Findings| V
|
|
190
215
|
V -->|Validated Evidence| R
|
|
191
216
|
R -->|Remediation Diff| REV
|
|
192
|
-
REV -->|
|
|
217
|
+
REV -->|Zero-Regress Sign-Off| HumanGate
|
|
193
218
|
|
|
194
219
|
style P fill:#1e293b,stroke:#3b82f6,stroke-width:2px,color:#fff
|
|
195
220
|
style A fill:#1e293b,stroke:#6366f1,stroke-width:2px,color:#fff
|
|
@@ -199,8 +224,40 @@ flowchart TD
|
|
|
199
224
|
style HumanGate fill:#334155,stroke:#f59e0b,stroke-width:2px,color:#fff
|
|
200
225
|
```
|
|
201
226
|
|
|
202
|
-
|
|
203
|
-
|
|
227
|
+
### Agent Responsibilities & Isolation Rules
|
|
228
|
+
|
|
229
|
+
| Agent | Specification | Dedicated Purpose | Anti-Bias Isolation Rule |
|
|
230
|
+
| :--- | :--- | :--- | :--- |
|
|
231
|
+
| **🔍 Profiler** | `.torusguard/agents/profiler.md` | Discovers frameworks, ORMs, and packages. | Cannot conduct vulnerability detection. |
|
|
232
|
+
| **🔎 Auditor** | `.torusguard/agents/auditor.md` | AST pattern matching and root-cause clustering. | Cannot propose code modifications or execute probes. |
|
|
233
|
+
| **🧪 Validator** | `.torusguard/agents/validator.md` | Bounded runtime HTTP validation and scoring. | Bound by `scope.json` authorization boundaries. |
|
|
234
|
+
| **🛠️ Remediator** | `.torusguard/agents/remediator.md` | Formulates surgical, minimal code patches. | **Cannot approve its own patch.** |
|
|
235
|
+
| **⚖️ Reviewer** | `.torusguard/agents/reviewer.md` | Pre-flight verification and compliance sign-off. | **Must be independent from Remediator.** |
|
|
236
|
+
|
|
237
|
+
* **Zero Self-Review:** The agent that writes a patch (`Remediator`) can never sign off on its merge (`Reviewer` + Human Gate required).
|
|
238
|
+
* **Cryptographic Provenance:** Every role handoff is recorded in `role-audit.json` with SHA-256 signatures.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 🛡️ Core Innovation Highlights
|
|
243
|
+
|
|
244
|
+
### 1. The Ponytail Protocol (Minimal Patch Churn Bounds)
|
|
245
|
+
Unbounded AI code generators frequently rewrite adjacent business logic, introduce accidental syntax errors, or strip comments. TorusGuard strictly enforces the **Ponytail Protocol**:
|
|
246
|
+
* **$\le 35$ Additions** per remediation patch.
|
|
247
|
+
* **$\le 25$ Deletions** per remediation patch.
|
|
248
|
+
* **Deterministic Single Responsibility:** Every patch resolves exactly one root-cause cluster without side effects.
|
|
249
|
+
|
|
250
|
+
### 2. Auditable Mathematical Confidence Scoring (0–100)
|
|
251
|
+
TorusGuard computes confidence scores using a formal 5-factor mathematical formula before escalating findings to developers:
|
|
252
|
+
$$\text{Score} = (w_d \cdot D) + (w_e \cdot E) + (w_c \cdot C_{ast}) - P_{fp} - P_{drift}$$
|
|
253
|
+
* **$D$ (Detection Determinism, 30%):** Exact string/AST regex matches vs speculative patterns.
|
|
254
|
+
* **$E$ (Runtime Evidence, 25%):** Confirmed HTTP exploitability response status.
|
|
255
|
+
* **$C_{ast}$ (AST Contextuality, 25%):** Direct assignment in critical execution path vs commented code.
|
|
256
|
+
* **$P_{fp}$ (False Positive Penalty, up to -20):** Safe wrapper detection (e.g. parameterized queries, sanitizers).
|
|
257
|
+
* **$P_{drift}$ (Line Drift Penalty, up to -10):** Unmatched surrounding file context.
|
|
258
|
+
|
|
259
|
+
### 3. Stable Line-Shift Invariant Fingerprinting (`primaryLocationLineHash`)
|
|
260
|
+
Traditional static tools break finding identity when a developer inserts 2 lines at the top of a file. TorusGuard computes a stable SHA-256 hash across the AST node content, enclosing function scope, and syntactic tokens. Findings maintain permanent tracking identity across Git commits and branch renames.
|
|
204
261
|
|
|
205
262
|
---
|
|
206
263
|
|
|
@@ -208,61 +265,111 @@ flowchart TD
|
|
|
208
265
|
|
|
209
266
|
TorusGuard enforces 71 rules across modern application stacks:
|
|
210
267
|
|
|
211
|
-
| Rule Family | Domain |
|
|
268
|
+
| Rule Family | Target Domain | Invariant Guarantees & Detection Scope |
|
|
212
269
|
| :--- | :--- | :--- |
|
|
213
270
|
| **`TG-SEC-*`** | Secrets & Credentials | Blocks exposed API keys, private certs, Supabase service roles, and hardcoded tokens. |
|
|
214
|
-
| **`TG-DB-*`** | Database & Queries |
|
|
215
|
-
| **`TG-INPUT-*`** | Input Validation | Pydantic/Zod
|
|
216
|
-
| **`TG-AUTH-*`** | Authentication & RBAC |
|
|
271
|
+
| **`TG-DB-*`** | Database & Queries | Enforces parameterized SQL queries and mandatory multi-tenant isolation filters (`.filter(tenant=...)`). |
|
|
272
|
+
| **`TG-INPUT-*`** | Input Validation | Validates Pydantic/Zod boundaries, prevents path traversal, and blocks unsanitized command execution. |
|
|
273
|
+
| **`TG-AUTH-*`** | Authentication & RBAC | Requires server-side route guards, enforces session TTLs, stops mass-assignment, and guards against IDOR. |
|
|
217
274
|
| **`TG-CLIENT-*`** | Client Bundle Leaks | Blocks server-side environment variables (`SUPABASE_KEY`, `DATABASE_URL`) from browser bundles. |
|
|
218
275
|
| **`TG-DIFF-*`** | Diff Line Inspection | Evaluates patch additions/deletions for auth bypass comments (`// nosec`), disabled TLS, or filter removals. |
|
|
219
|
-
| **`TG-AGENT-*`** | AI Agent & MCP Security |
|
|
220
|
-
| **`TG-EDGE-*`** | Serverless & Edge |
|
|
221
|
-
| **`TG-SUPPLY-*`** | Supply Chain & CI/CD | GitHub Actions least
|
|
222
|
-
| **`TG-SSRF-*`** | Outbound Networking |
|
|
223
|
-
| **`TG-BIZ-*`** | Business Logic |
|
|
276
|
+
| **`TG-AGENT-*`** | AI Agent & MCP Security | Enforces prompt injection delimiters, sandboxes tool execution, and restricts destructive tool capabilities. |
|
|
277
|
+
| **`TG-EDGE-*`** | Serverless & Edge | Prevents global memory leakage in V8 isolates (Cloudflare Workers) and cold-start state bleed in AWS Lambda. |
|
|
278
|
+
| **`TG-SUPPLY-*`** | Supply Chain & CI/CD | Enforces GitHub Actions least-privilege permissions, validates Docker build secrets, and flags risky deps. |
|
|
279
|
+
| **`TG-SSRF-*`** | Outbound Networking | Enforces webhook HMAC signature verification, prevents SSRF DNS rebinding, and blocks internal subnets. |
|
|
280
|
+
| **`TG-BIZ-*`** | Business Logic | Protects multi-step financial transactions, race conditions, and currency rounding precision. |
|
|
224
281
|
|
|
225
282
|
---
|
|
226
283
|
|
|
227
284
|
## 🔬 Content-Aware Diff Line Scanner (`diff_guard.py`)
|
|
228
285
|
|
|
229
|
-
Every patch generated by TorusGuard (or submitted via
|
|
230
|
-
* **`TG-DIFF-001` (Bypass Markers):**
|
|
231
|
-
* **`TG-DIFF-002` (Credential Ingestion):**
|
|
232
|
-
* **`TG-DIFF-003` (Tenant Removal):**
|
|
286
|
+
Every patch generated by TorusGuard (or submitted via Pull Request) is analyzed by our unified diff inspector:
|
|
287
|
+
* **`TG-DIFF-001` (Bypass Markers):** Detects bypass comments (`# bypass auth`, `// nosec`) and disabled TLS verification (`verify=False`).
|
|
288
|
+
* **`TG-DIFF-002` (Credential Ingestion):** Intercepts live JWTs, Bearer tokens, or high-entropy secrets introduced in additions.
|
|
289
|
+
* **`TG-DIFF-003` (Tenant Removal):** Blocks deletions that strip tenant isolation clauses (`.filter(tenant=...)`, `where tenant_id`).
|
|
233
290
|
|
|
234
291
|
---
|
|
235
292
|
|
|
236
293
|
## 🏢 Monorepo Sub-Scope Orchestration (`monorepo_detector.py`)
|
|
237
294
|
|
|
238
|
-
TorusGuard
|
|
295
|
+
TorusGuard natively discovers and isolates sub-projects in complex monorepos:
|
|
239
296
|
* **Package Managers:** Turborepo, pnpm workspaces, npm/yarn workspaces, Lerna.
|
|
240
|
-
* **Service
|
|
241
|
-
* **Targeted
|
|
297
|
+
* **Service Independence:** Profiles backend services (FastAPI/Django) and frontend applications (Next.js/React) separately.
|
|
298
|
+
* **Targeted Scanning:** Audit the entire repository or focus strictly on a specific service:
|
|
299
|
+
```bash
|
|
300
|
+
npx torusguard audit --target apps/api
|
|
301
|
+
```
|
|
242
302
|
|
|
243
303
|
---
|
|
244
304
|
|
|
245
305
|
## 🎮 Interactive Multi-Stack Playground (`demo/playground/`)
|
|
246
306
|
|
|
247
|
-
Test TorusGuard against real, runnable vulnerable applications without
|
|
307
|
+
Test TorusGuard against real, runnable vulnerable applications without exposing production code:
|
|
248
308
|
```bash
|
|
249
309
|
# Explore FastAPI playground:
|
|
250
310
|
python demo/playground/vulnerable_fastapi/main.py
|
|
251
311
|
|
|
252
|
-
# Run TorusGuard audit
|
|
312
|
+
# Run TorusGuard audit against the playground:
|
|
253
313
|
npx torusguard audit --target demo/playground/vulnerable_fastapi
|
|
254
314
|
```
|
|
255
|
-
* **FastAPI Playground:** Demonstrates SQL
|
|
315
|
+
* **FastAPI Playground:** Demonstrates raw SQL string formatting, unauthenticated routes, and missing tenant scopes.
|
|
256
316
|
* **Next.js Playground:** Demonstrates Next.js Server Action data leaks, prompt injection sinks, and exposed client secrets.
|
|
257
317
|
|
|
258
318
|
---
|
|
259
319
|
|
|
260
|
-
##
|
|
320
|
+
## 🚀 GitHub Actions CI/CD Integration
|
|
321
|
+
|
|
322
|
+
Integrate TorusGuard directly into your GitHub Actions workflow to scan pull requests and export OASIS SARIF v2.1.0 to GitHub Advanced Security:
|
|
323
|
+
|
|
324
|
+
```yaml
|
|
325
|
+
name: TorusGuard Security Scan
|
|
326
|
+
|
|
327
|
+
on:
|
|
328
|
+
push:
|
|
329
|
+
branches: [main]
|
|
330
|
+
pull_request:
|
|
331
|
+
branches: [main]
|
|
332
|
+
|
|
333
|
+
jobs:
|
|
334
|
+
security-audit:
|
|
335
|
+
runs-on: ubuntu-latest
|
|
336
|
+
steps:
|
|
337
|
+
- name: Checkout Code
|
|
338
|
+
uses: actions/checkout@v4
|
|
339
|
+
|
|
340
|
+
- name: Setup Node.js
|
|
341
|
+
uses: actions/setup-node@v4
|
|
342
|
+
with:
|
|
343
|
+
node-version: 18
|
|
344
|
+
|
|
345
|
+
- name: Setup Python
|
|
346
|
+
uses: actions/setup-python@v5
|
|
347
|
+
with:
|
|
348
|
+
python-version: '3.11'
|
|
349
|
+
|
|
350
|
+
- name: Initialize TorusGuard
|
|
351
|
+
run: npx torusguard init --force
|
|
352
|
+
|
|
353
|
+
- name: Execute Security Audit
|
|
354
|
+
run: npx torusguard audit
|
|
355
|
+
|
|
356
|
+
- name: Generate SARIF Telemetry
|
|
357
|
+
run: npx torusguard report
|
|
358
|
+
|
|
359
|
+
- name: Upload SARIF to GitHub Code Scanning
|
|
360
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
361
|
+
with:
|
|
362
|
+
sarif_file: .torusguard/runs/latest/report.sarif
|
|
363
|
+
if: always()
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## 🧪 Comprehensive Verification Battery (11/11 Passed)
|
|
261
369
|
|
|
262
|
-
TorusGuard
|
|
370
|
+
TorusGuard enforces strict testing standards. Every release must achieve a **100% pass rate** across our entire test suite:
|
|
263
371
|
|
|
264
372
|
```bash
|
|
265
|
-
# Run the complete test battery:
|
|
266
373
|
python harness/validate_v0_9_2_dual_track.py
|
|
267
374
|
python harness/validate_v0_9_2_diff_and_monorepo.py
|
|
268
375
|
python harness/validate_v0_9_2_workflows_and_skills.py
|
|
@@ -276,8 +383,8 @@ python harness/validate_v0_8_0_part2.py
|
|
|
276
383
|
python harness/validate_v0_8_0_part3.py
|
|
277
384
|
```
|
|
278
385
|
|
|
279
|
-
* **Cryptographic
|
|
280
|
-
* **Token Budget Guarantee:** All skills and workflows strictly respect a **1,000–1,500 token budget** to
|
|
386
|
+
* **Cryptographic Manifest:** All workspace templates are verified against SHA-256 signatures in `.torusguard/.manifest.json`.
|
|
387
|
+
* **Token Budget Guarantee:** All skills and workflows strictly respect a **1,000–1,500 token budget** to avoid AI context bloat.
|
|
281
388
|
|
|
282
389
|
---
|
|
283
390
|
|
|
@@ -289,3 +396,6 @@ TorusGuard is open-source software licensed under the [MIT License](LICENSE).
|
|
|
289
396
|
* **Repository:** [https://github.com/githubmofo/TorusGuard](https://github.com/githubmofo/TorusGuard)
|
|
290
397
|
* **NPM Package:** [https://www.npmjs.com/package/torusguard](https://www.npmjs.com/package/torusguard)
|
|
291
398
|
* **Bug Reports & Issues:** [https://github.com/githubmofo/TorusGuard/issues](https://github.com/githubmofo/TorusGuard/issues)
|
|
399
|
+
* **Security Policy:** [SECURITY.md](SECURITY.md)
|
|
400
|
+
* **Contributing Guide:** [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
401
|
+
* **Maintainer Hygiene:** [MAINTAINERS.md](MAINTAINERS.md)
|
package/bin/torusguard.js
CHANGED
|
@@ -15,6 +15,17 @@ const command = args[0] || 'init';
|
|
|
15
15
|
const rootDir = path.resolve(__dirname, '..');
|
|
16
16
|
const cwd = process.cwd();
|
|
17
17
|
|
|
18
|
+
// ─── ANSI Color Helpers ───────────────────────────────────────────────────────
|
|
19
|
+
const BOLD = '\x1b[1m';
|
|
20
|
+
const DIM = '\x1b[2m';
|
|
21
|
+
const RESET = '\x1b[0m';
|
|
22
|
+
const CYAN = '\x1b[36m';
|
|
23
|
+
const GREEN = '\x1b[32m';
|
|
24
|
+
const YELLOW = '\x1b[33m';
|
|
25
|
+
const WHITE = '\x1b[97m';
|
|
26
|
+
const GRAY = '\x1b[90m';
|
|
27
|
+
const RED = '\x1b[31m';
|
|
28
|
+
|
|
18
29
|
// Detect available Python binary (python or python3)
|
|
19
30
|
let pythonCmd = 'python';
|
|
20
31
|
try {
|
|
@@ -36,23 +47,41 @@ try {
|
|
|
36
47
|
|
|
37
48
|
function printHelp() {
|
|
38
49
|
console.log(`
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
${CYAN}╭─────────────────────────────────────────────────────────────────────────╮${RESET}
|
|
51
|
+
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
52
|
+
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ T O R U S G U A R D C L I${RESET} ${GRAY}v0.9.5${RESET} ${CYAN}│${RESET}
|
|
53
|
+
${CYAN}│${RESET} ${DIM}Autonomous Security Engine for AI-Built Applications${RESET} ${CYAN}│${RESET}
|
|
54
|
+
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
55
|
+
${CYAN}╰─────────────────────────────────────────────────────────────────────────╯${RESET}
|
|
56
|
+
|
|
57
|
+
${BOLD}Usage:${RESET} ${GREEN}npx torusguard${RESET} ${WHITE}[command]${RESET} ${GRAY}[options]${RESET}
|
|
58
|
+
|
|
59
|
+
${CYAN}┌─────────────────────────────────────────────────────────────────────────┐${RESET}
|
|
60
|
+
${CYAN}│${RESET} ${BOLD}Commands${RESET} ${CYAN}│${RESET}
|
|
61
|
+
${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
|
|
62
|
+
${CYAN}│${RESET} ${GREEN}init${RESET} Scaffold ${BOLD}.torusguard/${RESET} workspace + unlock 11 slash commands ${CYAN}│${RESET}
|
|
63
|
+
${CYAN}│${RESET} ${GREEN}status${RESET} Display active security posture, rules, and stack info ${CYAN}│${RESET}
|
|
64
|
+
${CYAN}│${RESET} ${GREEN}audit${RESET} Run static AST security scan on the target project ${CYAN}│${RESET}
|
|
65
|
+
${CYAN}│${RESET} ${GREEN}report${RESET} Export OASIS SARIF v2.1.0 structured telemetry ${CYAN}│${RESET}
|
|
66
|
+
${CYAN}│${RESET} ${GREEN}help${RESET} Show this interactive command guide ${CYAN}│${RESET}
|
|
67
|
+
${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
|
|
68
|
+
${CYAN}│${RESET} ${BOLD}Options${RESET} ${CYAN}│${RESET}
|
|
69
|
+
${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
|
|
70
|
+
${CYAN}│${RESET} ${GRAY}--target <dir>${RESET} Target directory to analyze or scaffold ${DIM}(default: .)${RESET} ${CYAN}│${RESET}
|
|
71
|
+
${CYAN}│${RESET} ${GRAY}--force${RESET} Overwrite existing workspace and re-scaffold ${CYAN}│${RESET}
|
|
72
|
+
${CYAN}└─────────────────────────────────────────────────────────────────────────┘${RESET}
|
|
73
|
+
|
|
74
|
+
${BOLD}AI Chat Commands:${RESET}
|
|
75
|
+
${DIM}In your AI IDE chat, use any of these slash commands:${RESET}
|
|
76
|
+
${CYAN}/torusguard${RESET} Main orchestrator (status, audit, harden, etc.)
|
|
77
|
+
${CYAN}/torusguard-audit${RESET} Static AST security scan
|
|
78
|
+
${CYAN}/torusguard-harden${RESET} Generate governed fix patches
|
|
79
|
+
${CYAN}/torusguard-apply${RESET} Apply patches with rollback snapshots
|
|
80
|
+
${CYAN}/torusguard-report${RESET} Executive security posture report
|
|
81
|
+
${CYAN}/torusguard-status${RESET} Read-only workspace diagnostic
|
|
82
|
+
|
|
83
|
+
${DIM}Documentation:${RESET} ${CYAN}https://github.com/githubmofo/TorusGuard${RESET}
|
|
84
|
+
${DIM}NPM Package:${RESET} ${CYAN}https://npmjs.com/package/torusguard${RESET}
|
|
56
85
|
`);
|
|
57
86
|
}
|
|
58
87
|
|
|
@@ -66,23 +95,55 @@ if (command === 'status') {
|
|
|
66
95
|
if (fs.existsSync(cfgPath)) {
|
|
67
96
|
try {
|
|
68
97
|
const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf-8'));
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
console.log(`
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
98
|
+
const stackLang = cfg.detected_stack?.language || 'Not yet detected';
|
|
99
|
+
const stackFw = cfg.detected_stack?.framework || 'Not yet detected';
|
|
100
|
+
const stackDb = cfg.detected_stack?.data_layer || 'Not yet detected';
|
|
101
|
+
const stackStatus = cfg.detected_stack ? `${GREEN}Detected${RESET}` : `${YELLOW}Pending first audit${RESET}`;
|
|
102
|
+
|
|
103
|
+
console.log(`
|
|
104
|
+
${CYAN}╭─────────────────────────────────────────────────────────────────────────╮${RESET}
|
|
105
|
+
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
106
|
+
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ TORUSGUARD SECURITY POSTURE${RESET} ${GRAY}v0.9.5${RESET} ${CYAN}│${RESET}
|
|
107
|
+
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
108
|
+
${CYAN}╰─────────────────────────────────────────────────────────────────────────╯${RESET}
|
|
109
|
+
|
|
110
|
+
${BOLD}▸ Workspace:${RESET} ${GREEN}${cwd}${RESET}
|
|
111
|
+
${BOLD}▸ Governance:${RESET} ${GREEN}Full Local Governance (.torusguard/)${RESET}
|
|
112
|
+
|
|
113
|
+
${CYAN}┌── Environment & Stack ──────────────────────────────────────────────────┐${RESET}
|
|
114
|
+
${CYAN}│${RESET} Language: ${BOLD}${stackLang}${RESET}
|
|
115
|
+
${CYAN}│${RESET} Framework: ${BOLD}${stackFw}${RESET}
|
|
116
|
+
${CYAN}│${RESET} Data Layer: ${BOLD}${stackDb}${RESET}
|
|
117
|
+
${CYAN}│${RESET} Stack Detection: ${stackStatus}
|
|
118
|
+
${CYAN}└─────────────────────────────────────────────────────────────────────────┘${RESET}
|
|
119
|
+
|
|
120
|
+
${CYAN}┌── Governance Telemetry ─────────────────────────────────────────────────┐${RESET}
|
|
121
|
+
${CYAN}│${RESET} Rules Catalog: ${GREEN}71 Canonical Security Rules${RESET} (11 families)
|
|
122
|
+
${CYAN}│${RESET} Severity Floor: ${YELLOW}${cfg.severity_threshold || 'medium'}${RESET}
|
|
123
|
+
${CYAN}│${RESET} Runs Directory: ${DIM}${cfg.runs_dir || '.torusguard/runs'}${RESET}
|
|
124
|
+
${CYAN}│${RESET} Ponytail Bounds: ${GREEN}<= 35 additions, <= 25 deletions${RESET}
|
|
125
|
+
${CYAN}└─────────────────────────────────────────────────────────────────────────┘${RESET}
|
|
126
|
+
|
|
127
|
+
${CYAN}┌── Rule Families ────────────────────────────────────────────────────────┐${RESET}
|
|
128
|
+
${CYAN}│${RESET} ${YELLOW}TG-SEC${RESET} Secrets & Credentials ${YELLOW}TG-DB${RESET} Database Safety
|
|
129
|
+
${CYAN}│${RESET} ${YELLOW}TG-INPUT${RESET} Input Validation ${YELLOW}TG-AUTH${RESET} Authentication
|
|
130
|
+
${CYAN}│${RESET} ${YELLOW}TG-CLIENT${RESET} Client Bundle Leaks ${YELLOW}TG-DIFF${RESET} Diff Inspection
|
|
131
|
+
${CYAN}│${RESET} ${YELLOW}TG-AGENT${RESET} AI Agent Security ${YELLOW}TG-EDGE${RESET} Serverless
|
|
132
|
+
${CYAN}│${RESET} ${YELLOW}TG-SUPPLY${RESET} Supply Chain & CI/CD ${YELLOW}TG-SSRF${RESET} Outbound Net
|
|
133
|
+
${CYAN}│${RESET} ${YELLOW}TG-BIZ${RESET} Business Logic
|
|
134
|
+
${CYAN}└─────────────────────────────────────────────────────────────────────────┘${RESET}
|
|
135
|
+
|
|
136
|
+
${DIM}Quick Action:${RESET} In your AI chat, run ${CYAN}/torusguard-audit${RESET} to scan.
|
|
137
|
+
`);
|
|
79
138
|
process.exit(0);
|
|
80
139
|
} catch (e) {
|
|
81
140
|
// Fallback to python runner
|
|
82
141
|
}
|
|
83
142
|
} else {
|
|
84
|
-
console.log(
|
|
85
|
-
|
|
143
|
+
console.log(`
|
|
144
|
+
${YELLOW}⚠${RESET} No .torusguard workspace found in current directory.
|
|
145
|
+
Run ${GREEN}npx torusguard init${RESET} to scaffold full workspace governance.
|
|
146
|
+
`);
|
|
86
147
|
process.exit(0);
|
|
87
148
|
}
|
|
88
149
|
}
|
|
@@ -96,7 +157,6 @@ const scriptToRun = fs.existsSync(localBootstrap) ? localBootstrap : localInstal
|
|
|
96
157
|
let scriptArgs = [scriptToRun];
|
|
97
158
|
if (command === 'init') {
|
|
98
159
|
scriptArgs.push('--full-commands');
|
|
99
|
-
// Forward remaining arguments
|
|
100
160
|
scriptArgs.push(...args.slice(1));
|
|
101
161
|
} else {
|
|
102
162
|
scriptArgs.push(...args);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: torusguard
|
|
3
|
-
description:
|
|
4
|
-
version: 0.9.
|
|
3
|
+
description: "Autonomous security engine: 71 rules across 11 families, governed remediation (Ponytail Protocol), SARIF v2.1.0 exports, and 5-agent authority separation for Python & TypeScript web applications."
|
|
4
|
+
version: 0.9.5
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# TorusGuard Master Security Router
|
|
Binary file
|
|
@@ -10,9 +10,33 @@ import sys
|
|
|
10
10
|
import shutil
|
|
11
11
|
import json
|
|
12
12
|
import argparse
|
|
13
|
-
import subprocess
|
|
14
13
|
from pathlib import Path
|
|
15
14
|
|
|
15
|
+
# Ensure UTF-8 stdout/stderr on Windows consoles
|
|
16
|
+
if sys.stdout and hasattr(sys.stdout, "reconfigure"):
|
|
17
|
+
try:
|
|
18
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
19
|
+
except Exception:
|
|
20
|
+
pass
|
|
21
|
+
if sys.stderr and hasattr(sys.stderr, "reconfigure"):
|
|
22
|
+
try:
|
|
23
|
+
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
|
|
24
|
+
except Exception:
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
# ─── ANSI Color Helpers ───────────────────────────────────────────────────────
|
|
28
|
+
BOLD = "\033[1m"
|
|
29
|
+
DIM = "\033[2m"
|
|
30
|
+
RESET = "\033[0m"
|
|
31
|
+
CYAN = "\033[36m"
|
|
32
|
+
GREEN = "\033[32m"
|
|
33
|
+
YELLOW = "\033[33m"
|
|
34
|
+
WHITE = "\033[97m"
|
|
35
|
+
GRAY = "\033[90m"
|
|
36
|
+
RED = "\033[31m"
|
|
37
|
+
BG_GREEN = "\033[42m"
|
|
38
|
+
BG_CYAN = "\033[46m"
|
|
39
|
+
|
|
16
40
|
|
|
17
41
|
def find_project_root(start_dir=None):
|
|
18
42
|
"""Detect project root directory by searching for standard repo root markers."""
|
|
@@ -33,6 +57,114 @@ def find_project_root(start_dir=None):
|
|
|
33
57
|
return current
|
|
34
58
|
|
|
35
59
|
|
|
60
|
+
def print_header():
|
|
61
|
+
"""Print the branded TorusGuard header card."""
|
|
62
|
+
print(f"""
|
|
63
|
+
{CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}
|
|
64
|
+
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
65
|
+
{CYAN}│{RESET} {BOLD}{WHITE}🛡️ T O R U S G U A R D{RESET} {GRAY}v0.9.5{RESET} {CYAN}│{RESET}
|
|
66
|
+
{CYAN}│{RESET} {DIM}Autonomous Security Engine for AI-Built Applications{RESET} {CYAN}│{RESET}
|
|
67
|
+
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
68
|
+
{CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}
|
|
69
|
+
""")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def print_step_1_assets(file_count):
|
|
73
|
+
"""Print the enhanced Step 1 asset unpacking card."""
|
|
74
|
+
print(f""" {CYAN}┌─ {BOLD}Step 1/3{RESET} {CYAN}──────────────────────── {WHITE}Unpacking Governance Assets{RESET} {CYAN}──────┐{RESET}
|
|
75
|
+
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
76
|
+
{CYAN}│{RESET} {GREEN}✔{RESET} Canonical security rules {DIM}71 rules across 11 families{RESET} {CYAN}│{RESET}
|
|
77
|
+
{CYAN}│{RESET} {GREEN}✔{RESET} JSON validation schemas {DIM}8 formal schemas{RESET} {CYAN}│{RESET}
|
|
78
|
+
{CYAN}│{RESET} {GREEN}✔{RESET} Specialist agent specifications {DIM}5 isolated agents{RESET} {CYAN}│{RESET}
|
|
79
|
+
{CYAN}│{RESET} {GREEN}✔{RESET} Workflow templates {DIM}11 slash commands{RESET} {CYAN}│{RESET}
|
|
80
|
+
{CYAN}│{RESET} {GREEN}✔{RESET} Framework reference guides {DIM}10 security guides{RESET} {CYAN}│{RESET}
|
|
81
|
+
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
82
|
+
{CYAN}│{RESET} {BOLD}{WHITE}{file_count} files unpacked{RESET} {CYAN}│{RESET}
|
|
83
|
+
{CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
|
|
84
|
+
""")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def print_step_2_profile(detected_stack=None):
|
|
88
|
+
"""Print the security profile & coverage card (in-process stack alignment)."""
|
|
89
|
+
if detected_stack and detected_stack.get("framework") and detected_stack.get("framework") != "None":
|
|
90
|
+
fw = str(detected_stack.get("framework"))
|
|
91
|
+
lang = str(detected_stack.get("language", ""))
|
|
92
|
+
label = f"Auto-aligned stack: {fw} ({lang})"
|
|
93
|
+
pad = " " * max(0, 66 - len(label))
|
|
94
|
+
status_line = f" {CYAN}│{RESET} {GREEN}✔{RESET} {BOLD}Auto-aligned stack:{RESET} {WHITE}{fw}{RESET} {DIM}({lang}){RESET}{pad}{CYAN}│{RESET}"
|
|
95
|
+
else:
|
|
96
|
+
status_line = f" {CYAN}│{RESET} {DIM}ℹ Stack auto-detected on first /torusguard-audit run{RESET} {CYAN}│{RESET}"
|
|
97
|
+
|
|
98
|
+
print(f""" {CYAN}┌─ {BOLD}Step 2/3{RESET} {CYAN}──────────────────── {WHITE}Security Profile & Coverage{RESET} {CYAN}────────┐{RESET}
|
|
99
|
+
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
100
|
+
{CYAN}│{RESET} {BOLD}Rule Families:{RESET} {CYAN}│{RESET}
|
|
101
|
+
{CYAN}│{RESET} {YELLOW}TG-SEC{RESET} Secrets & Credentials {YELLOW}TG-DB{RESET} Database Safety {CYAN}│{RESET}
|
|
102
|
+
{CYAN}│{RESET} {YELLOW}TG-INPUT{RESET} Input Validation {YELLOW}TG-AUTH{RESET} Authentication {CYAN}│{RESET}
|
|
103
|
+
{CYAN}│{RESET} {YELLOW}TG-CLIENT{RESET} Client Bundle Leaks {YELLOW}TG-DIFF{RESET} Diff Inspection {CYAN}│{RESET}
|
|
104
|
+
{CYAN}│{RESET} {YELLOW}TG-AGENT{RESET} AI Agent Security {YELLOW}TG-EDGE{RESET} Serverless {CYAN}│{RESET}
|
|
105
|
+
{CYAN}│{RESET} {YELLOW}TG-SUPPLY{RESET} Supply Chain & CI/CD {YELLOW}TG-SSRF{RESET} Outbound Net {CYAN}│{RESET}
|
|
106
|
+
{CYAN}│{RESET} {YELLOW}TG-BIZ{RESET} Business Logic {CYAN}│{RESET}
|
|
107
|
+
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
108
|
+
{CYAN}│{RESET} {BOLD}Supported Stacks:{RESET} {CYAN}│{RESET}
|
|
109
|
+
{CYAN}│{RESET} {GREEN}Python{RESET} Django {DIM}·{RESET} FastAPI {DIM}·{RESET} Flask {DIM}·{RESET} DRF {DIM}·{RESET} SQLAlchemy {CYAN}│{RESET}
|
|
110
|
+
{CYAN}│{RESET} {GREEN}Node.js{RESET} Next.js {DIM}·{RESET} Express {DIM}·{RESET} React {DIM}·{RESET} Supabase {DIM}·{RESET} Firebase {CYAN}│{RESET}
|
|
111
|
+
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
112
|
+
{status_line}
|
|
113
|
+
{CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
|
|
114
|
+
""")
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def print_step_3_bridges(registered_ides):
|
|
118
|
+
"""Print the IDE command registration card."""
|
|
119
|
+
lines = ""
|
|
120
|
+
for r in registered_ides:
|
|
121
|
+
lines += f" {CYAN}│{RESET} {GREEN}✔{RESET} {r:<67} {CYAN}│{RESET}\n"
|
|
122
|
+
|
|
123
|
+
print(f""" {CYAN}┌─ {BOLD}Step 3/3{RESET} {CYAN}─────────────────── {WHITE}AI IDE Command Registration{RESET} {CYAN}─────────┐{RESET}
|
|
124
|
+
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
125
|
+
{lines} {CYAN}│{RESET} {CYAN}│{RESET}
|
|
126
|
+
{CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
|
|
127
|
+
""")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def print_success_card():
|
|
131
|
+
"""Print the final success card with next steps."""
|
|
132
|
+
print(f""" {GREEN}╔═══════════════════════════════════════════════════════════════════════╗{RESET}
|
|
133
|
+
{GREEN}║{RESET} {GREEN}║{RESET}
|
|
134
|
+
{GREEN}║{RESET} {GREEN}{BOLD}✅ WORKSPACE INITIALIZED SUCCESSFULLY{RESET} {GREEN}║{RESET}
|
|
135
|
+
{GREEN}║{RESET} {GREEN}║{RESET}
|
|
136
|
+
{GREEN}╠═══════════════════════════════════════════════════════════════════════╣{RESET}
|
|
137
|
+
{GREEN}║{RESET} {GREEN}║{RESET}
|
|
138
|
+
{GREEN}║{RESET} {BOLD}Next Steps:{RESET} {GREEN}║{RESET}
|
|
139
|
+
{GREEN}║{RESET} {GREEN}║{RESET}
|
|
140
|
+
{GREEN}║{RESET} {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard-audit{RESET} or {WHITE}/torusguard{RESET} {GREEN}║{RESET}
|
|
141
|
+
{GREEN}║{RESET} {CYAN}2.{RESET} In Terminal {WHITE}npx torusguard status{RESET} {GREEN}║{RESET}
|
|
142
|
+
{GREEN}║{RESET} {CYAN}3.{RESET} In CI/CD {WHITE}npx torusguard audit{RESET} {GREEN}║{RESET}
|
|
143
|
+
{GREEN}║{RESET} {GREEN}║{RESET}
|
|
144
|
+
{GREEN}║{RESET} {DIM}Docs{RESET} {CYAN}https://github.com/githubmofo/TorusGuard{RESET} {GREEN}║{RESET}
|
|
145
|
+
{GREEN}║{RESET} {DIM}NPM{RESET} {CYAN}https://npmjs.com/package/torusguard{RESET} {GREEN}║{RESET}
|
|
146
|
+
{GREEN}║{RESET} {GREEN}║{RESET}
|
|
147
|
+
{GREEN}╚═══════════════════════════════════════════════════════════════════════╝{RESET}
|
|
148
|
+
""")
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def print_already_initialized(target_root, cfg):
|
|
152
|
+
"""Print the already-initialized status card."""
|
|
153
|
+
print(f"""
|
|
154
|
+
{CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}
|
|
155
|
+
{CYAN}│{RESET} {BOLD}{WHITE}🛡️ TORUSGUARD WORKSPACE{RESET} {GREEN}[Active]{RESET} {CYAN}│{RESET}
|
|
156
|
+
{CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}
|
|
157
|
+
|
|
158
|
+
{BOLD}▸ Project Root:{RESET} {GREEN}{target_root}{RESET}
|
|
159
|
+
{BOLD}▸ Workspace:{RESET} {GREEN}.torusguard/{RESET} {DIM}(Already Initialized){RESET}
|
|
160
|
+
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '0.9.5')}{RESET}
|
|
161
|
+
{BOLD}▸ Severity Floor:{RESET} {YELLOW}{cfg.get('severity_threshold', 'medium')}{RESET}
|
|
162
|
+
|
|
163
|
+
{DIM}To refresh templates or re-scaffold, run:{RESET}
|
|
164
|
+
{CYAN}npx torusguard init --force{RESET}
|
|
165
|
+
""")
|
|
166
|
+
|
|
167
|
+
|
|
36
168
|
def scaffold_workspace(target_root=None, force=False, full_commands=False):
|
|
37
169
|
"""Scaffold the .torusguard workspace into the target project root."""
|
|
38
170
|
target_root = Path(target_root or find_project_root()).resolve()
|
|
@@ -40,29 +172,26 @@ def scaffold_workspace(target_root=None, force=False, full_commands=False):
|
|
|
40
172
|
script_dir = Path(__file__).resolve().parent
|
|
41
173
|
payload_dir = script_dir / "payload"
|
|
42
174
|
|
|
43
|
-
print("================================================================================")
|
|
44
|
-
print("TORUSGUARD WORKSPACE BOOTSTRAPPER")
|
|
45
|
-
print("================================================================================")
|
|
46
|
-
print(f"Target Directory: {target_root}")
|
|
47
|
-
print(f"Destination: {torusguard_target}")
|
|
48
|
-
|
|
49
175
|
if torusguard_target.exists() and not force:
|
|
50
|
-
print(f"\n[INFO] Workspace already exists at {torusguard_target}")
|
|
51
176
|
config_file = torusguard_target / "config" / "torusguard.json"
|
|
177
|
+
cfg = {}
|
|
52
178
|
if config_file.exists():
|
|
53
179
|
try:
|
|
54
180
|
with open(config_file, "r", encoding="utf-8") as f:
|
|
55
181
|
cfg = json.load(f)
|
|
56
|
-
print(f"Current Version: {cfg.get('version', 'unknown')}")
|
|
57
|
-
print(f"Severity Minimum: {cfg.get('severity_threshold', 'medium')}")
|
|
58
182
|
except Exception:
|
|
59
183
|
pass
|
|
60
|
-
|
|
184
|
+
print_already_initialized(target_root, cfg)
|
|
61
185
|
return True
|
|
62
186
|
|
|
63
|
-
#
|
|
187
|
+
# ── Header ──────────────────────────────────────────────────────────────
|
|
188
|
+
print_header()
|
|
189
|
+
print(f" {BOLD}▸ Target Project:{RESET} {WHITE}{target_root}{RESET}")
|
|
190
|
+
print(f" {BOLD}▸ Destination:{RESET} {WHITE}{torusguard_target}{RESET}")
|
|
191
|
+
|
|
192
|
+
# ── Step 1: Unpack Payload ──────────────────────────────────────────────
|
|
193
|
+
file_count = 93
|
|
64
194
|
if payload_dir.is_dir():
|
|
65
|
-
print("\n1. Unpacking bundled offline workspace payload...")
|
|
66
195
|
try:
|
|
67
196
|
if torusguard_target.exists() and force:
|
|
68
197
|
shutil.rmtree(torusguard_target)
|
|
@@ -71,22 +200,25 @@ def scaffold_workspace(target_root=None, force=False, full_commands=False):
|
|
|
71
200
|
torusguard_target,
|
|
72
201
|
ignore=shutil.ignore_patterns("runs", "*.pyc", "__pycache__", ".git*")
|
|
73
202
|
)
|
|
74
|
-
|
|
203
|
+
# Count actual files
|
|
204
|
+
file_count = sum(1 for _ in torusguard_target.rglob("*") if _.is_file())
|
|
75
205
|
except Exception as e:
|
|
76
|
-
print(f"
|
|
206
|
+
print(f"\n {RED}✖ Failed to unpack payload: {e}{RESET}")
|
|
77
207
|
return False
|
|
78
208
|
else:
|
|
79
209
|
# Fallback: create base structure
|
|
80
|
-
print("\n1. Bundled payload not found. Creating core skeleton...")
|
|
81
210
|
subdirs = [
|
|
82
211
|
"config", "agents", "workflows", "scripts", "templates",
|
|
83
212
|
"schemas", "references", "rules/active", "runs"
|
|
84
213
|
]
|
|
85
214
|
for s in subdirs:
|
|
86
215
|
(torusguard_target / s).mkdir(parents=True, exist_ok=True)
|
|
87
|
-
|
|
216
|
+
file_count = 0
|
|
217
|
+
|
|
218
|
+
print()
|
|
219
|
+
print_step_1_assets(file_count)
|
|
88
220
|
|
|
89
|
-
#
|
|
221
|
+
# ── Ensure runs and rules/active directories exist ──────────────────────
|
|
90
222
|
runs_dir = torusguard_target / "runs"
|
|
91
223
|
runs_dir.mkdir(parents=True, exist_ok=True)
|
|
92
224
|
gitkeep_runs = runs_dir / ".gitkeep"
|
|
@@ -99,50 +231,51 @@ def scaffold_workspace(target_root=None, force=False, full_commands=False):
|
|
|
99
231
|
if not gitkeep_rules.exists():
|
|
100
232
|
gitkeep_rules.write_text("", encoding="utf-8")
|
|
101
233
|
|
|
102
|
-
#
|
|
103
|
-
|
|
234
|
+
# ── Step 2: Security Profile & Coverage (In-Process, Zero Subprocess) ──
|
|
235
|
+
# Execute stack detection in-process without spawning child processes (Socket.dev safe)
|
|
236
|
+
detected_stack = None
|
|
104
237
|
stack_detect_script = torusguard_target / "scripts" / "stack_detect.py"
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if stack_detect_script.exists():
|
|
238
|
+
if stack_detect_script.is_file():
|
|
108
239
|
try:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
print(f" [DETECTED] Framework: {detected_stack.get('framework')}")
|
|
119
|
-
print(f" [DETECTED] Data Layer: {detected_stack.get('data_layer')}")
|
|
120
|
-
except Exception as e:
|
|
121
|
-
print(f" [WARN] Stack detection encountered error: {e}")
|
|
240
|
+
import importlib.util
|
|
241
|
+
spec = importlib.util.spec_from_file_location("stack_detect", str(stack_detect_script))
|
|
242
|
+
if spec and spec.loader:
|
|
243
|
+
sd_mod = importlib.util.module_from_spec(spec)
|
|
244
|
+
spec.loader.exec_module(sd_mod)
|
|
245
|
+
if hasattr(sd_mod, "detect_stack"):
|
|
246
|
+
detected_stack = sd_mod.detect_stack(target_root)
|
|
247
|
+
except Exception:
|
|
248
|
+
detected_stack = None
|
|
122
249
|
|
|
123
|
-
# 4. Update torusguard.json configuration
|
|
124
250
|
config_file = torusguard_target / "config" / "torusguard.json"
|
|
125
251
|
if config_file.exists():
|
|
126
252
|
try:
|
|
127
253
|
with open(config_file, "r", encoding="utf-8") as f:
|
|
128
254
|
cfg = json.load(f)
|
|
129
|
-
|
|
130
|
-
"
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
255
|
+
if detected_stack and detected_stack.get("framework") != "None":
|
|
256
|
+
cfg["detected_stack"] = {
|
|
257
|
+
"language": detected_stack.get("language"),
|
|
258
|
+
"framework": detected_stack.get("framework"),
|
|
259
|
+
"data_layer": detected_stack.get("data_layer")
|
|
260
|
+
}
|
|
261
|
+
else:
|
|
262
|
+
cfg["detected_stack"] = {
|
|
263
|
+
"language": "Unknown",
|
|
264
|
+
"framework": "None",
|
|
265
|
+
"data_layer": "None"
|
|
266
|
+
}
|
|
134
267
|
with open(config_file, "w", encoding="utf-8") as f:
|
|
135
268
|
json.dump(cfg, f, indent=2)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
print(f" [WARN] Failed to write stack details to config: {e}")
|
|
269
|
+
except Exception:
|
|
270
|
+
pass
|
|
139
271
|
|
|
140
|
-
|
|
141
|
-
|
|
272
|
+
print_step_2_profile(detected_stack)
|
|
273
|
+
|
|
274
|
+
# ── Step 3: Register Slash Commands for AI IDEs ─────────────────────────
|
|
142
275
|
registered_ides = []
|
|
143
276
|
tg_workflow_content = """---
|
|
144
277
|
description: TorusGuard Autonomous Security Command Engine — run static security audits, authorized runtime web validation, governed remediation, and SARIF exports.
|
|
145
|
-
version: 0.9.
|
|
278
|
+
version: 0.9.5
|
|
146
279
|
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
147
280
|
agent: auditor
|
|
148
281
|
---
|
|
@@ -168,16 +301,16 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
168
301
|
agents_wf.mkdir(parents=True, exist_ok=True)
|
|
169
302
|
(agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
170
303
|
dest_workflow_dirs.append(agents_wf)
|
|
171
|
-
registered_ides.append("Antigravity / Gemini
|
|
304
|
+
registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
|
|
172
305
|
|
|
173
306
|
agent_wf = target_root / ".agent" / "workflows"
|
|
174
307
|
agent_wf.mkdir(parents=True, exist_ok=True)
|
|
175
308
|
(agent_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
176
309
|
dest_workflow_dirs.append(agent_wf)
|
|
177
|
-
registered_ides.append("
|
|
310
|
+
registered_ides.append("Tribunal Agent Kit .agent/workflows/torusguard.md")
|
|
178
311
|
|
|
179
312
|
# When full_commands is requested (e.g. via NPM package npx torusguard init),
|
|
180
|
-
# unlock and register all 11 individual slash commands
|
|
313
|
+
# unlock and register all 11 individual slash commands
|
|
181
314
|
if full_commands:
|
|
182
315
|
src_wf = torusguard_target / "workflows"
|
|
183
316
|
if src_wf.is_dir():
|
|
@@ -189,7 +322,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
189
322
|
for d in dest_workflow_dirs:
|
|
190
323
|
shutil.copy2(wf_file, d / cmd_filename)
|
|
191
324
|
count += 1
|
|
192
|
-
registered_ides.append(f"
|
|
325
|
+
registered_ides.append(f"{count} Slash Commands /torusguard-audit, -harden, -apply, ...")
|
|
193
326
|
|
|
194
327
|
# Claude Code (.claude/commands)
|
|
195
328
|
claude_dir = target_root / ".claude"
|
|
@@ -197,7 +330,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
197
330
|
claude_commands = claude_dir / "commands"
|
|
198
331
|
claude_commands.mkdir(parents=True, exist_ok=True)
|
|
199
332
|
(claude_commands / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
200
|
-
registered_ides.append("Claude Code
|
|
333
|
+
registered_ides.append("Claude Code .claude/commands/torusguard.md")
|
|
201
334
|
|
|
202
335
|
# Cursor (.cursor/rules)
|
|
203
336
|
cursor_dir = target_root / ".cursor"
|
|
@@ -205,7 +338,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
205
338
|
cursor_rules = cursor_dir / "rules"
|
|
206
339
|
cursor_rules.mkdir(parents=True, exist_ok=True)
|
|
207
340
|
(cursor_rules / "torusguard.mdc").write_text(tg_workflow_content, encoding="utf-8")
|
|
208
|
-
registered_ides.append("Cursor
|
|
341
|
+
registered_ides.append("Cursor .cursor/rules/torusguard.mdc")
|
|
209
342
|
|
|
210
343
|
# Windsurf (.windsurfrules)
|
|
211
344
|
if (target_root / ".windsurfrules").exists() or (target_root / ".windsurf").exists():
|
|
@@ -213,7 +346,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
213
346
|
current_content = windsurf_rules.read_text(encoding="utf-8") if windsurf_rules.exists() else ""
|
|
214
347
|
if "TorusGuard" not in current_content:
|
|
215
348
|
windsurf_rules.write_text(current_content + "\n\n" + tg_workflow_content, encoding="utf-8")
|
|
216
|
-
registered_ides.append("Windsurf
|
|
349
|
+
registered_ides.append("Windsurf .windsurfrules")
|
|
217
350
|
|
|
218
351
|
# VS Code / GitHub Copilot (.github/copilot-instructions.md)
|
|
219
352
|
github_dir = target_root / ".github"
|
|
@@ -222,26 +355,19 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
222
355
|
current_content = copilot_file.read_text(encoding="utf-8") if copilot_file.exists() else ""
|
|
223
356
|
if "TorusGuard" not in current_content:
|
|
224
357
|
copilot_file.write_text(current_content + "\n\n# TorusGuard Security Instructions\n" + tg_workflow_content, encoding="utf-8")
|
|
225
|
-
registered_ides.append("VS Code / Copilot
|
|
358
|
+
registered_ides.append("VS Code / Copilot .github/copilot-instructions.md")
|
|
226
359
|
|
|
227
360
|
# Universal AGENTS.md (Kimi, Codex, Open Agent Standard)
|
|
228
361
|
agents_md = target_root / "AGENTS.md"
|
|
229
362
|
current_agents = agents_md.read_text(encoding="utf-8") if agents_md.exists() else ""
|
|
230
363
|
if "TorusGuard" not in current_agents:
|
|
231
364
|
agents_md.write_text(current_agents + ("\n\n" if current_agents else "") + "# TorusGuard Security Guardrails\n\nRun `/torusguard audit` to scan the codebase or refer to `.torusguard/` for security guidelines.\n", encoding="utf-8")
|
|
232
|
-
registered_ides.append("Universal
|
|
365
|
+
registered_ides.append("Universal AGENTS.md Kimi / Open Agent Standard")
|
|
233
366
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
print("[SUCCESS] TORUSGUARD WORKSPACE SCAFFOLDED SUCCESSFULLY!")
|
|
239
|
-
print("================================================================================")
|
|
240
|
-
print(f"Workspace Path: {torusguard_target}")
|
|
241
|
-
print("\nNext Steps:")
|
|
242
|
-
print(" 1. Run `/torusguard audit` in your AI IDE to scan the project.")
|
|
243
|
-
print(" 2. Run `/torusguard status` to verify active security posture.")
|
|
244
|
-
print("================================================================================")
|
|
367
|
+
print_step_3_bridges(registered_ides)
|
|
368
|
+
|
|
369
|
+
# ── Success Card ────────────────────────────────────────────────────────
|
|
370
|
+
print_success_card()
|
|
245
371
|
return True
|
|
246
372
|
|
|
247
373
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"agents/validator.md": "79fc4431de5c5507f8730aee6c5c3e61fd238cbf8cf8c7c6aac462eee9761ed6",
|
|
9
9
|
"config/scope.json": "b198a86186b4c6d5e1af516bf4e3a6afa8878e622ca1d57a5bf72d294f8c6f25",
|
|
10
10
|
"config/slash-commands.json": "5390f0d26f8117a62e56c58147d3a0d2deab1a20956302b212703281d13fa84e",
|
|
11
|
-
"config/torusguard.json": "
|
|
11
|
+
"config/torusguard.json": "077bc6a948f9420aded8dba248577ff3ebf054cab64cf538a7a6d05223fe27bc",
|
|
12
12
|
"references/django-security.md": "a15b7eb11b51dd1970d3d65544cf79ebea91fb99dc0e085e58a56532a718dce7",
|
|
13
13
|
"references/drf-security.md": "c7a7af3acaef895bf4798590acc88b3a2e9831a49eb2d23b4d8f31540ab264cc",
|
|
14
14
|
"references/express-security.md": "dff1db15e614d29d8c272f9da345b418077e62dc883fe210c7a50c552c76493f",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"scripts/safety_gate.py": "3379b7534b2590cf563717a448983ad8ed7e8f174f0ad65683d33e8a10f51558",
|
|
41
41
|
"scripts/sarif_exporter.py": "35c66637413afc4b72d5bd426638447c77231d2a8594dce5addceffd4803a20d",
|
|
42
42
|
"scripts/stack_detect.py": "99b7bdf9829d58ff5b8c59afd6e8b6429bbb11d830ac73dec491101cbbc41574",
|
|
43
|
-
"skills/torusguard/SKILL.md": "
|
|
43
|
+
"skills/torusguard/SKILL.md": "31a115886ffb115f2b975c4d0670e780e11ea68201559b24b20d0d0ef456058f",
|
|
44
44
|
"skills/torusguard/bootstrap.py": "7e348065a622089ab1d51e9bf4864e5b0022aaee1ccb2ecbf7057c14e792e2c7",
|
|
45
45
|
"skills/torusguard/references/auth-and-sessions.md": "34c2843f8c0dbe3574e54f00a39a92a1f431527ec5f69b2d64c84240d424a39e",
|
|
46
46
|
"skills/torusguard/references/business-logic-and-abuse.md": "0d6088936bc1a01023070332fccef0f2e0734358a5119379055f3d2895c22567",
|
|
Binary file
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: torusguard
|
|
3
|
-
description:
|
|
4
|
-
version: 0.9.
|
|
3
|
+
description: "Autonomous security engine: 71 rules across 11 families, governed remediation (Ponytail Protocol), SARIF v2.1.0 exports, and 5-agent authority separation for Python & TypeScript web applications."
|
|
4
|
+
version: 0.9.5
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# TorusGuard Master Router
|
|
7
|
+
# TorusGuard Master Security Router
|
|
8
8
|
|
|
9
|
-
**Principle:** If the browser receives it, users can inspect it. Keep secrets,
|
|
9
|
+
**Principle:** If the browser receives it, users can inspect it. Keep secrets, database queries, and authorization strictly on trusted server-side code.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
## ⚡ Workspace Bootstrap Check
|
|
14
|
-
1. **If `.torusguard/` exists:**
|
|
15
|
-
2. **If `.torusguard/` is
|
|
14
|
+
1. **If `.torusguard/` exists on disk:** Full governance active. Route slash commands to local specialist workflows below.
|
|
15
|
+
2. **If `.torusguard/` is absent (Autonomous AI Mode):** Operates standalone in any AI agent (Kimi, Antigravity, VS Code, Cursor). Apply in-memory security invariants:
|
|
16
|
+
- Server-side auth & tenant scoping (`.filter(tenant=...)`).
|
|
17
|
+
- Zero client-side secrets (`SUPABASE_SERVICE_ROLE_KEY`, live API keys).
|
|
18
|
+
- Ponytail Protocol patch limits ($\le 35$ additions, $\le 25$ deletions).
|
|
19
|
+
- *Upgrade:* Run `npx torusguard init` to unlock local `.torusguard/` run tracking & individual commands.
|
|
16
20
|
|
|
17
21
|
---
|
|
18
22
|
|
|
19
23
|
## Specialist Skill Routing (Lazy Loading)
|
|
20
|
-
Load **only** the designated sub-skill
|
|
24
|
+
Load **only** the designated sub-skill on demand to preserve the 1,000–1,500 token budget:
|
|
21
25
|
|
|
22
26
|
| Command | Specialist Skill | Agent |
|
|
23
27
|
| :--- | :--- | :--- |
|