torusguard 2.1.1 → 2.1.3
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 +11 -3
- package/.torusguard/config/torusguard.json +1 -1
- package/.torusguard/custom_rules/README.md +24 -0
- package/.torusguard/scripts/__pycache__/audit_runner.cpython-314.pyc +0 -0
- package/.torusguard/scripts/__pycache__/finding_scorer.cpython-314.pyc +0 -0
- package/.torusguard/scripts/__pycache__/manifest_builder.cpython-314.pyc +0 -0
- package/.torusguard/scripts/__pycache__/term_ui.cpython-314.pyc +0 -0
- package/.torusguard/scripts/deliberation_tournament.py +136 -0
- package/.torusguard/scripts/reachability_analyzer.py +165 -0
- package/.torusguard/scripts/status_runner.py +3 -3
- package/.torusguard/scripts/stride_generator.py +198 -0
- package/.torusguard/scripts/term_ui.py +1 -1
- package/.torusguard/skills/torusguard-review/SKILL.md +27 -0
- package/.torusguard/skills/torusguard-threatmodel/SKILL.md +27 -0
- package/.torusguard/workflows/review.md +11 -0
- package/.torusguard/workflows/threatmodel.md +9 -0
- package/README.md +194 -45
- package/bin/torusguard.js +26 -26
- package/package.json +5 -1
- package/skills/torusguard/__pycache__/bootstrap.cpython-314.pyc +0 -0
- package/skills/torusguard/bootstrap.py +32 -65
- package/skills/torusguard/payload/.manifest.json +12 -4
- package/skills/torusguard/payload/config/torusguard.json +1 -1
- package/skills/torusguard/payload/custom_rules/README.md +15 -0
- package/skills/torusguard/payload/scripts/deliberation_tournament.py +127 -0
- package/skills/torusguard/payload/scripts/reachability_analyzer.py +164 -0
- package/skills/torusguard/payload/scripts/status_runner.py +3 -3
- package/skills/torusguard/payload/scripts/stride_generator.py +196 -0
- package/skills/torusguard/payload/scripts/term_ui.py +1 -1
- package/skills/torusguard/payload/skills/torusguard/bootstrap.py +32 -65
- package/skills/torusguard/payload/skills/torusguard-review/SKILL.md +27 -0
- package/skills/torusguard/payload/skills/torusguard-threatmodel/SKILL.md +27 -0
- package/skills/torusguard/payload/workflows/review.md +11 -0
- package/skills/torusguard/payload/workflows/threatmodel.md +9 -0
- package/skills/torusguard-review/SKILL.md +27 -0
- package/skills/torusguard-threatmodel/SKILL.md +27 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
TorusGuard STRIDE Threat Modeling & Data Flow Diagram (DFD) Synthesizer
|
|
4
|
+
Automatically maps application entry points, trust boundaries, and datastores to generate
|
|
5
|
+
interactive Mermaid DFDs and structured STRIDE risk registers for security compliance.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import re
|
|
10
|
+
import json
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Dict, List, Set, Any
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def discover_architecture_components(root_dir: Path) -> Dict[str, Any]:
|
|
16
|
+
entrypoints = []
|
|
17
|
+
datastores = set()
|
|
18
|
+
external_sinks = set()
|
|
19
|
+
trust_boundaries = ["Public Internet", "API Perimeter / DMZ", "Protected Core Services", "Isolated Data Tier"]
|
|
20
|
+
|
|
21
|
+
skip_dirs = {"node_modules", ".git", ".torusguard", "dist", "build", ".next", "__pycache__"}
|
|
22
|
+
|
|
23
|
+
# Patterns for HTTP routes
|
|
24
|
+
route_patterns = [
|
|
25
|
+
re.compile(r"""(?:app|router|server)\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]"""),
|
|
26
|
+
re.compile(r"""@(?:app|router)\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]"""),
|
|
27
|
+
re.compile(r"""http\.HandleFunc\s*\(\s*['"]([^'"]+)['"]"""),
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
# Patterns for datastores & sinks
|
|
31
|
+
db_patterns = [
|
|
32
|
+
(re.compile(r"""(?i)(postgres|pg|prisma|typeorm|sequelize)"""), "PostgreSQL / Relational DB"),
|
|
33
|
+
(re.compile(r"""(?i)(mongo|mongoose)"""), "MongoDB / Document Store"),
|
|
34
|
+
(re.compile(r"""(?i)(redis|ioredis)"""), "Redis / In-Memory Cache"),
|
|
35
|
+
(re.compile(r"""(?i)(sqlite|sqlite3)"""), "SQLite / Local DB"),
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
sink_patterns = [
|
|
39
|
+
(re.compile(r"""(?i)(stripe|paypal)"""), "Payment Gateway (Stripe/PayPal)"),
|
|
40
|
+
(re.compile(r"""(?i)(openai|anthropic|bedrock)"""), "AI LLM Provider (OpenAI/Anthropic)"),
|
|
41
|
+
(re.compile(r"""(?i)(aws-sdk|boto3|s3)"""), "Cloud Storage (AWS S3)"),
|
|
42
|
+
(re.compile(r"""(?i)(sendgrid|nodemailer|twilio)"""), "Communication Gateway (Twilio/SendGrid)"),
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
for root, dirs, files in os.walk(root_dir):
|
|
46
|
+
dirs[:] = [d for d in dirs if d not in skip_dirs]
|
|
47
|
+
for f in files:
|
|
48
|
+
ext = os.path.splitext(f)[1].lower()
|
|
49
|
+
if ext not in {".js", ".jsx", ".ts", ".tsx", ".py", ".go"}:
|
|
50
|
+
continue
|
|
51
|
+
file_path = Path(root) / f
|
|
52
|
+
try:
|
|
53
|
+
content = file_path.read_text(encoding="utf-8", errors="ignore")
|
|
54
|
+
rel_path = file_path.relative_to(root_dir).as_posix()
|
|
55
|
+
|
|
56
|
+
# Find routes
|
|
57
|
+
for pat in route_patterns:
|
|
58
|
+
for method, path in pat.findall(content):
|
|
59
|
+
entrypoints.append({
|
|
60
|
+
"method": method.upper(),
|
|
61
|
+
"path": path,
|
|
62
|
+
"file": rel_path
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
# Find DBs
|
|
66
|
+
for pat, name in db_patterns:
|
|
67
|
+
if pat.search(content):
|
|
68
|
+
datastores.add(name)
|
|
69
|
+
|
|
70
|
+
# Find Sinks
|
|
71
|
+
for pat, name in sink_patterns:
|
|
72
|
+
if pat.search(content):
|
|
73
|
+
external_sinks.add(name)
|
|
74
|
+
|
|
75
|
+
except Exception:
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
"entrypoints": entrypoints[:25],
|
|
80
|
+
"total_routes_detected": len(entrypoints),
|
|
81
|
+
"datastores": sorted(datastores) if datastores else ["Internal SQLite / Local Memory Store"],
|
|
82
|
+
"external_sinks": sorted(external_sinks) if external_sinks else ["Standard Outbound HTTPS Sinks"],
|
|
83
|
+
"trust_boundaries": trust_boundaries
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def generate_mermaid_dfd(components: Dict[str, Any]) -> str:
|
|
88
|
+
lines = [
|
|
89
|
+
"```mermaid",
|
|
90
|
+
"flowchart TB",
|
|
91
|
+
" subgraph Zone1 [Public Internet / Client Tier]",
|
|
92
|
+
" User([Web / Mobile Client])",
|
|
93
|
+
" Attacker([Adversarial Threat Actor])",
|
|
94
|
+
" end",
|
|
95
|
+
"",
|
|
96
|
+
" subgraph Zone2 [API Perimeter & Trust Boundary]",
|
|
97
|
+
" Gateway[API Gateway / Router Handlers]"
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
for i, ep in enumerate(components["entrypoints"][:4]):
|
|
101
|
+
lines.append(f" Route_{i}[{ep['method']} {ep['path']}]")
|
|
102
|
+
|
|
103
|
+
lines.extend([
|
|
104
|
+
" end",
|
|
105
|
+
"",
|
|
106
|
+
" subgraph Zone3 [Core Application Execution Tier]",
|
|
107
|
+
" AppEngine[TorusGuard Governed App Logic]",
|
|
108
|
+
" AuthModule[Authentication & Tenant Scoper]",
|
|
109
|
+
" end",
|
|
110
|
+
"",
|
|
111
|
+
" subgraph Zone4 [Data & External Integration Tier]"
|
|
112
|
+
])
|
|
113
|
+
|
|
114
|
+
for i, db in enumerate(components["datastores"]):
|
|
115
|
+
lines.append(f" DB_{i}[({db})]")
|
|
116
|
+
|
|
117
|
+
for i, sink in enumerate(components["external_sinks"]):
|
|
118
|
+
lines.append(f" Sink_{i}[/{sink}/]")
|
|
119
|
+
|
|
120
|
+
lines.extend([
|
|
121
|
+
" end",
|
|
122
|
+
"",
|
|
123
|
+
" User -->|HTTP / TLS| Gateway",
|
|
124
|
+
" Attacker -.->|Untrusted Payloads| Gateway",
|
|
125
|
+
" Gateway --> AppEngine",
|
|
126
|
+
" AppEngine --> AuthModule",
|
|
127
|
+
])
|
|
128
|
+
|
|
129
|
+
for i in range(len(components["datastores"])):
|
|
130
|
+
lines.append(f" AuthModule -->|Scoped Query| DB_{i}")
|
|
131
|
+
|
|
132
|
+
for i in range(len(components["external_sinks"])):
|
|
133
|
+
lines.append(f" AppEngine -->|Egress HTTPS| Sink_{i}")
|
|
134
|
+
|
|
135
|
+
lines.append("```")
|
|
136
|
+
return "\n".join(lines)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def generate_stride_report(root_dir: Path) -> str:
|
|
140
|
+
comp = discover_architecture_components(root_dir)
|
|
141
|
+
mermaid = generate_mermaid_dfd(comp)
|
|
142
|
+
|
|
143
|
+
report = f"""# TorusGuard Architectural Threat Model & STRIDE Register
|
|
144
|
+
|
|
145
|
+
**Generated by:** TorusGuard Threat Modeling Engine (v2.1.3)
|
|
146
|
+
**Workspace:** `{root_dir.resolve().as_posix()}`
|
|
147
|
+
**Analyzed Routes:** {comp['total_routes_detected']}
|
|
148
|
+
**Identified Data Stores:** {', '.join(comp['datastores'])}
|
|
149
|
+
**External Egress Sinks:** {', '.join(comp['external_sinks'])}
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 1. Architectural Data Flow Diagram (DFD)
|
|
154
|
+
|
|
155
|
+
{mermaid}
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 2. STRIDE Risk Assessment & Invariant Ledger
|
|
160
|
+
|
|
161
|
+
| STRIDE Category | Threat Description | Attack Vector | TorusGuard Guardrail | Mitigation Status |
|
|
162
|
+
| :--- | :--- | :--- | :---: | :---: |
|
|
163
|
+
| **Spoofing** | Attacker impersonates legitimate user or service via unverified JWT or forged credentials. | Forged token on `{comp['entrypoints'][0]['path'] if comp['entrypoints'] else '/api'}` | `TG-AUTH-001` / `TG-SEC-001` | **Enforced** |
|
|
164
|
+
| **Tampering** | Unsanitized parameter injection modifies database records or query logic across tenants. | Dynamic SQL concatenation or unpartitioned PK lookups | `TG-DB-001` / `TG-DB-002` | **Enforced** |
|
|
165
|
+
| **Repudiation** | Actions executed without persistent audit traces or immutable transaction locks. | Missing audit headers on state-changing API endpoints | `TG-BIZ-002` / `TG-AUDIT-001` | **Monitored** |
|
|
166
|
+
| **Information Disclosure** | Credentials, API tokens, or multi-tenant database partitions exposed to browser clients. | Bundled service keys or error stack traces | `TG-CLIENT-001` / `TG-DB-001` | **Enforced** |
|
|
167
|
+
| **Denial of Service** | Resource exhaustion via unbounded regex backtracking or unthrottled authentication endpoints. | Catastrophic ReDoS input or unrate-limited auth routes | `TG-REDOS-001` / `TG-RATE-001` | **Enforced** |
|
|
168
|
+
| **Elevation of Privilege** | Unsandboxed tool dispatch or privileged container execution breaks host isolation. | Docker socket mounts or missing role checks | `TG-CONT-002` / `TG-AGENT-002` | **Enforced** |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 3. Trust Boundary Verification Checklist
|
|
173
|
+
|
|
174
|
+
- [x] **Boundary 1 (Internet to Gateway):** Enforce strict TLS, rate limiting, and CORS origin verification (`TG-RATE-001`, `TG-WS-001`).
|
|
175
|
+
- [x] **Boundary 2 (Gateway to App Core):** Mandatory tenant scoping and structural prompt isolation for LLMs (`TG-DB-001`, `TG-AGENT-001`).
|
|
176
|
+
- [x] **Boundary 3 (App Core to Data Stores):** Parameterized queries and fail-closed entropy validation (`TG-DB-002`, `TG-SEC-004`).
|
|
177
|
+
- [x] **Boundary 4 (App Core to External Sinks):** SSRF hostname whitelisting and private IP resolution blocking (`TG-SSRF-001`, `TG-SSRF-002`).
|
|
178
|
+
|
|
179
|
+
*Report automatically synced with workspace security posture ledger.*
|
|
180
|
+
"""
|
|
181
|
+
return report
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def main():
|
|
185
|
+
import sys
|
|
186
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
187
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
188
|
+
target = Path(sys.argv[1] if len(sys.argv) > 1 else ".")
|
|
189
|
+
report_content = generate_stride_report(target)
|
|
190
|
+
out_file = target / "SECURITY_THREAT_MODEL.md"
|
|
191
|
+
out_file.write_text(report_content, encoding="utf-8")
|
|
192
|
+
print(f"[+] Generated architectural STRIDE threat model: {out_file.as_posix()}")
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
if __name__ == "__main__":
|
|
196
|
+
main()
|
|
@@ -143,7 +143,7 @@ def card_divider(title: str = "", border_color: str = CYAN, double: bool = False
|
|
|
143
143
|
return f" {border_color}{left}{h} {BOLD}{WHITE}{title}{RESET}{border_color} {h * rem}{right}{RESET}"
|
|
144
144
|
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
145
145
|
|
|
146
|
-
def card_header(title: str, subtitle: str = "", version: str = "
|
|
146
|
+
def card_header(title: str, subtitle: str = "", version: str = "v2.1.3", border_color: str = CYAN) -> str:
|
|
147
147
|
"""Generate standardized 75-column curved header box."""
|
|
148
148
|
top = f" {border_color}╭{'─' * 71}╮{RESET}"
|
|
149
149
|
bottom = f" {border_color}╰{'─' * 71}╯{RESET}"
|
|
@@ -144,7 +144,7 @@ def card_divider(title: str = "", border_color: str = CYAN, double: bool = False
|
|
|
144
144
|
return f" {border_color}{left}{h} {BOLD}{WHITE}{title}{RESET}{border_color} {h * rem}{right}{RESET}"
|
|
145
145
|
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
146
146
|
|
|
147
|
-
def card_header(title: str, subtitle: str = "", version: str = "v2.1.
|
|
147
|
+
def card_header(title: str, subtitle: str = "", version: str = "v2.1.3", border_color: str = CYAN) -> str:
|
|
148
148
|
"""Generate standardized 75-column curved header box."""
|
|
149
149
|
top = f" {border_color}╭{'─' * 71}╮{RESET}"
|
|
150
150
|
bottom = f" {border_color}╰{'─' * 71}╯{RESET}"
|
|
@@ -164,7 +164,7 @@ def card_header(title: str, subtitle: str = "", version: str = "v2.1.1", border_
|
|
|
164
164
|
def print_header():
|
|
165
165
|
"""Print the branded TorusGuard header card."""
|
|
166
166
|
print()
|
|
167
|
-
print(card_header("🛡️ T O R U S G U A R D", "Autonomous Security Engine for AI-Built Applications", version="v2.1.
|
|
167
|
+
print(card_header("🛡️ T O R U S G U A R D", "Autonomous Security Engine for AI-Built Applications", version="v2.1.3"))
|
|
168
168
|
print()
|
|
169
169
|
|
|
170
170
|
|
|
@@ -172,13 +172,13 @@ def print_step_1_assets(file_count):
|
|
|
172
172
|
"""Print the enhanced Step 1 asset unpacking card."""
|
|
173
173
|
print(card_border_top("Step 1/3 ─── Unpacking Governance Assets"))
|
|
174
174
|
print(card_line(""))
|
|
175
|
-
print(card_line(f"{GREEN}✔{RESET} Canonical security rules {DIM}
|
|
175
|
+
print(card_line(f"{GREEN}✔{RESET} Canonical security rules {DIM}88 rules across 22 families{RESET}"))
|
|
176
176
|
print(card_line(f"{GREEN}✔{RESET} JSON validation schemas {DIM}8 formal schemas{RESET}"))
|
|
177
177
|
print(card_line(f"{GREEN}✔{RESET} Specialist agent specifications {DIM}5 isolated agents{RESET}"))
|
|
178
|
-
print(card_line(f"{GREEN}✔{RESET}
|
|
179
|
-
print(card_line(f"{GREEN}✔{RESET} Framework reference guides {DIM}
|
|
178
|
+
print(card_line(f"{GREEN}✔{RESET} Governed workflow templates {DIM}25 commands & 13 MCP tools{RESET}"))
|
|
179
|
+
print(card_line(f"{GREEN}✔{RESET} Framework reference guides {DIM}22 architectural guides{RESET}"))
|
|
180
180
|
print(card_line(""))
|
|
181
|
-
print(card_line(f"{BOLD}{WHITE}{file_count} files unpacked{RESET}"))
|
|
181
|
+
print(card_line(f"{BOLD}{WHITE}{file_count} files unpacked into .torusguard/{RESET}"))
|
|
182
182
|
print(card_border_bottom())
|
|
183
183
|
|
|
184
184
|
|
|
@@ -186,13 +186,18 @@ def print_step_2_profile(detected_stack=None):
|
|
|
186
186
|
"""Print the security profile & coverage card (in-process stack alignment)."""
|
|
187
187
|
print(card_border_top("Step 2/3 ─── Security Profile & Coverage"))
|
|
188
188
|
print(card_line(""))
|
|
189
|
-
print(card_line(f"{BOLD}Rule Families:{RESET}"))
|
|
190
|
-
print(card_line(f" {YELLOW}TG-SEC{RESET} Secrets &
|
|
191
|
-
print(card_line(f" {YELLOW}TG-
|
|
192
|
-
print(card_line(f" {YELLOW}TG-
|
|
193
|
-
print(card_line(f" {YELLOW}TG-
|
|
194
|
-
print(card_line(f" {YELLOW}TG-
|
|
195
|
-
print(card_line(f" {YELLOW}TG-
|
|
189
|
+
print(card_line(f"{BOLD}Rule Families (88 Rules Across 22 Families):{RESET}"))
|
|
190
|
+
print(card_line(f" {YELLOW}TG-SEC{RESET} Secrets & Tokens {YELLOW}TG-AUTH{RESET} Authentication"))
|
|
191
|
+
print(card_line(f" {YELLOW}TG-DB{RESET} Database Isolation {YELLOW}TG-INPUT{RESET} Input Sanitization"))
|
|
192
|
+
print(card_line(f" {YELLOW}TG-RATE{RESET} Rate Limiting {YELLOW}TG-AGENT{RESET} AI Prompt Injection"))
|
|
193
|
+
print(card_line(f" {YELLOW}TG-SSRF{RESET} Server-Side Request {YELLOW}TG-WEBHOOK{RESET} Webhook Signature"))
|
|
194
|
+
print(card_line(f" {YELLOW}TG-WS{RESET} WebSocket Safety {YELLOW}TG-CSRF{RESET} Cross-Site Request"))
|
|
195
|
+
print(card_line(f" {YELLOW}TG-GQL{RESET} GraphQL Introspection {YELLOW}TG-SUPPLY{RESET} Supply Chain Health"))
|
|
196
|
+
print(card_line(f" {YELLOW}TG-BIZ{RESET} Business Logic Limits {YELLOW}TG-CACHE{RESET} Cache Poisoning"))
|
|
197
|
+
print(card_line(f" {YELLOW}TG-CLIENT{RESET} Client Bundle Secrets {YELLOW}TG-PLATFORM{RESET}Platform Hardening"))
|
|
198
|
+
print(card_line(f" {YELLOW}TG-DIFF{RESET} Polyglot Bypass Guard {YELLOW}TG-EDGE{RESET} Edge & Serverless"))
|
|
199
|
+
print(card_line(f" {YELLOW}TG-CONT{RESET} Container Hardening {YELLOW}TG-GIT{RESET} Git Secret Mining"))
|
|
200
|
+
print(card_line(f" {YELLOW}TG-REDOS{RESET} ReDoS Complexity Guard {YELLOW}TG-RAG{RESET} RAG & Vector Scoping"))
|
|
196
201
|
print(card_line(""))
|
|
197
202
|
print(card_line(f"{BOLD}Supported Stacks:{RESET}"))
|
|
198
203
|
print(card_line(f" {GREEN}Python{RESET} Django · FastAPI · Flask · DRF · SQLAlchemy"))
|
|
@@ -227,7 +232,7 @@ def print_success_card():
|
|
|
227
232
|
print(card_line("", border="║", border_color=GREEN))
|
|
228
233
|
print(card_line(f"{BOLD}Next Steps:{RESET}", border="║", border_color=GREEN))
|
|
229
234
|
print(card_line("", border="║", border_color=GREEN))
|
|
230
|
-
print(card_line(f" {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard
|
|
235
|
+
print(card_line(f" {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard audit{RESET} or {WHITE}/torusguard status{RESET}", border="║", border_color=GREEN))
|
|
231
236
|
print(card_line(f" {CYAN}2.{RESET} In Terminal {WHITE}npx torusguard status{RESET}", border="║", border_color=GREEN))
|
|
232
237
|
print(card_line(f" {CYAN}3.{RESET} In CI/CD {WHITE}npx torusguard audit{RESET}", border="║", border_color=GREEN))
|
|
233
238
|
print(card_line("", border="║", border_color=GREEN))
|
|
@@ -238,16 +243,21 @@ def print_success_card():
|
|
|
238
243
|
|
|
239
244
|
|
|
240
245
|
def print_already_initialized(target_root, cfg):
|
|
241
|
-
"""Print the already-initialized status card."""
|
|
246
|
+
"""Print the already-initialized status card with dynamic width alignment."""
|
|
242
247
|
print()
|
|
243
248
|
top = f" {CYAN}╭{'─' * 71}╮{RESET}"
|
|
244
249
|
bottom = f" {CYAN}╰{'─' * 71}╯{RESET}"
|
|
245
|
-
|
|
250
|
+
title_text = f"{BOLD}{WHITE}🛡️ TORUSGUARD WORKSPACE{RESET}"
|
|
251
|
+
status_text = f"{GREEN}[Active]{RESET}"
|
|
252
|
+
title_vis = get_visual_width("🛡️ TORUSGUARD WORKSPACE")
|
|
253
|
+
status_vis = get_visual_width("[Active]")
|
|
254
|
+
pad_count = max(1, 67 - title_vis - status_vis)
|
|
255
|
+
title_line = card_line(f"{title_text}{' ' * pad_count}{status_text}")
|
|
246
256
|
print(f"{top}\n{title_line}\n{bottom}")
|
|
247
257
|
print(f"""
|
|
248
258
|
{BOLD}▸ Project Root:{RESET} {GREEN}{target_root}{RESET}
|
|
249
259
|
{BOLD}▸ Workspace:{RESET} {GREEN}.torusguard/{RESET} {DIM}(Already Initialized){RESET}
|
|
250
|
-
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '2.1.
|
|
260
|
+
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '2.1.3')}{RESET}
|
|
251
261
|
{BOLD}▸ Severity Floor:{RESET} {YELLOW}{cfg.get('severity_threshold', 'medium')}{RESET}
|
|
252
262
|
|
|
253
263
|
{DIM}To refresh templates or re-scaffold, run:{RESET}
|
|
@@ -454,53 +464,10 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
454
464
|
3. Follow the phase execution steps defined in the workflow.
|
|
455
465
|
"""
|
|
456
466
|
|
|
457
|
-
#
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
#
|
|
461
|
-
agents_wf = target_root / ".agents" / "workflows"
|
|
462
|
-
agents_wf.mkdir(parents=True, exist_ok=True)
|
|
463
|
-
(agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
464
|
-
dest_workflow_dirs.append(agents_wf)
|
|
465
|
-
registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
|
|
466
|
-
|
|
467
|
-
# 2. Tribunal Agent Kit (.agent/)
|
|
468
|
-
agent_wf = target_root / ".agent" / "workflows"
|
|
469
|
-
agent_wf.mkdir(parents=True, exist_ok=True)
|
|
470
|
-
(agent_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
471
|
-
dest_workflow_dirs.append(agent_wf)
|
|
472
|
-
registered_ides.append("Tribunal Agent Kit .agent/workflows/torusguard.md")
|
|
473
|
-
|
|
474
|
-
# Unpack Skills into .agents/skills and .agent/skills for full IDE resolution
|
|
475
|
-
src_skills = torusguard_target / "skills"
|
|
476
|
-
if src_skills.is_dir():
|
|
477
|
-
for dest_base in [target_root / ".agents" / "skills", target_root / ".agent" / "skills"]:
|
|
478
|
-
dest_base.mkdir(parents=True, exist_ok=True)
|
|
479
|
-
for skill_dir in src_skills.iterdir():
|
|
480
|
-
if skill_dir.is_dir():
|
|
481
|
-
target_skill_dir = dest_base / skill_dir.name
|
|
482
|
-
if not target_skill_dir.exists():
|
|
483
|
-
try:
|
|
484
|
-
shutil.copytree(skill_dir, target_skill_dir)
|
|
485
|
-
except Exception:
|
|
486
|
-
pass
|
|
487
|
-
|
|
488
|
-
# When full_commands is requested (e.g. via NPM package npx torusguard init),
|
|
489
|
-
# unlock and register all individual slash commands
|
|
490
|
-
if full_commands:
|
|
491
|
-
src_wf = torusguard_target / "workflows"
|
|
492
|
-
if src_wf.is_dir():
|
|
493
|
-
count = 0
|
|
494
|
-
for wf_file in src_wf.glob("*.md"):
|
|
495
|
-
if wf_file.name == "torusguard.md":
|
|
496
|
-
continue
|
|
497
|
-
cmd_filename = f"torusguard-{wf_file.name}"
|
|
498
|
-
for d in dest_workflow_dirs:
|
|
499
|
-
shutil.copy2(wf_file, d / cmd_filename)
|
|
500
|
-
count += 1
|
|
501
|
-
registered_ides.append(f"{count} Slash Commands /torusguard-audit, -harden, -apply, ...")
|
|
502
|
-
|
|
503
|
-
# Claude Code (.claude/commands)
|
|
467
|
+
# Core workspace governance is self-contained in .torusguard/
|
|
468
|
+
registered_ides.append("Workspace Core .torusguard/ (Workflows & Skills)")
|
|
469
|
+
|
|
470
|
+
# Claude Code (.claude/commands) - only if .claude exists
|
|
504
471
|
claude_dir = target_root / ".claude"
|
|
505
472
|
if claude_dir.exists():
|
|
506
473
|
claude_commands = claude_dir / "commands"
|
|
@@ -508,7 +475,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
508
475
|
(claude_commands / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
509
476
|
registered_ides.append("Claude Code .claude/commands/torusguard.md")
|
|
510
477
|
|
|
511
|
-
# Cursor (.cursor/rules)
|
|
478
|
+
# Cursor (.cursor/rules) - only if .cursor exists
|
|
512
479
|
cursor_dir = target_root / ".cursor"
|
|
513
480
|
if cursor_dir.exists():
|
|
514
481
|
cursor_rules = cursor_dir / "rules"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: torusguard-review
|
|
3
|
+
description: Differential PR and Git diff incremental security review — detects newly introduced vulnerabilities between Git branches or commits with net security score deltas.
|
|
4
|
+
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
+
version: 2.1.3
|
|
6
|
+
last-updated: 2026-10-01
|
|
7
|
+
skills:
|
|
8
|
+
- torusguard
|
|
9
|
+
- torusguard-audit
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# TorusGuard Review — Differential Incremental PR Review
|
|
13
|
+
|
|
14
|
+
TorusGuard Review performs rapid, surgical security review on Git changes (e.g. against `HEAD~1`, `main`, or PR target branch), analyzing only modified lines to prevent introducing security regressions.
|
|
15
|
+
|
|
16
|
+
## Invocation
|
|
17
|
+
|
|
18
|
+
- **Mode A (Terminal CLI):** `torusguard review [--diff <ref>]`
|
|
19
|
+
- **Mode B (AI Chat Slash Command):** `/torusguard review` or `/torusguard-review`
|
|
20
|
+
- **Mode C (Native MCP Tool):** `torusguard_review(target=".", diff_ref="HEAD~1")`
|
|
21
|
+
|
|
22
|
+
## Core Capabilities
|
|
23
|
+
|
|
24
|
+
1. **Sub-300ms Turnaround:** Only parses and checks modified/added lines in Git diffs.
|
|
25
|
+
2. **Net Security Score Delta:** Tracks introduced vs. resolved vulnerabilities (`+0 Introduced, -2 Resolved`).
|
|
26
|
+
3. **PR Gate Decision:** Blocks CI/CD pipelines if Critical or High severity flaws are introduced.
|
|
27
|
+
4. **Alibaba OpenCodeReview Parity:** Outputs ready-to-post pull request inline review comments.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: torusguard-threatmodel
|
|
3
|
+
description: Synthesizes an architectural STRIDE threat model, interactive Mermaid Data Flow Diagram (DFD), and trust boundary register into SECURITY_THREAT_MODEL.md.
|
|
4
|
+
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
+
version: 2.1.3
|
|
6
|
+
last-updated: 2026-10-01
|
|
7
|
+
skills:
|
|
8
|
+
- torusguard
|
|
9
|
+
- torusguard-audit
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# TorusGuard Threat Model — STRIDE & DFD Synthesizer
|
|
13
|
+
|
|
14
|
+
TorusGuard Threat Model automatically maps routes, trust boundaries, datastores, and egress sinks to construct an architectural Data Flow Diagram and formal STRIDE threat model.
|
|
15
|
+
|
|
16
|
+
## Invocation
|
|
17
|
+
|
|
18
|
+
- **Mode A (Terminal CLI):** `torusguard threatmodel`
|
|
19
|
+
- **Mode B (AI Chat Slash Command):** `/torusguard threatmodel` or `/torusguard-threatmodel`
|
|
20
|
+
- **Mode C (Native MCP Tool):** `torusguard_threatmodel(target=".")`
|
|
21
|
+
|
|
22
|
+
## Core Capabilities
|
|
23
|
+
|
|
24
|
+
1. **Automated DFD Generation:** Renders interactive Mermaid diagram showing Zones 1–4 (Clients, Gateways, Core Services, Datastores).
|
|
25
|
+
2. **STRIDE Risk Ledger:** Evaluates threats across Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, and Elevation of Privilege.
|
|
26
|
+
3. **Multi-Modal Vision Integration:** Discovers architectural diagrams and verifies that visual trust boundaries match code execution paths.
|
|
27
|
+
4. **Living Compliance Artifact:** Emits `SECURITY_THREAT_MODEL.md` at workspace root.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# TorusGuard Review Workflow (`/torusguard review`)
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Executes differential incremental Git diff security review against a reference branch or commit (default: `HEAD~1`).
|
|
5
|
+
Inspects changed lines for new security regressions, evaluates net security score deltas, and outputs pull request review comments.
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
1. Determine reference branch or commit (e.g. `HEAD~1` or `origin/main`).
|
|
9
|
+
2. Run differential scan via `torusguard review [--diff <ref>]` or native MCP tool `torusguard_review`.
|
|
10
|
+
3. Check PR Gate Decision (`PASSED` or `BLOCKED`).
|
|
11
|
+
4. If blocked, review newly introduced violations and formulate surgical Ponytail fixes via `/torusguard harden`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# TorusGuard Threat Model Workflow (`/torusguard threatmodel`)
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Synthesizes architectural STRIDE threat models, interactive Mermaid Data Flow Diagrams (DFDs), and trust boundary registers directly into `SECURITY_THREAT_MODEL.md`.
|
|
5
|
+
|
|
6
|
+
## Steps
|
|
7
|
+
1. Execute `torusguard threatmodel` or native MCP tool `torusguard_threatmodel`.
|
|
8
|
+
2. Inspect `SECURITY_THREAT_MODEL.md` to verify identified entrypoints, data stores, and trust boundaries.
|
|
9
|
+
3. Align STRIDE risk controls against corresponding TorusGuard security invariants (`TG-AUTH`, `TG-DB`, `TG-RATE`, `TG-SSRF`).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: torusguard-review
|
|
3
|
+
description: Differential PR and Git diff incremental security review — detects newly introduced vulnerabilities between Git branches or commits with net security score deltas.
|
|
4
|
+
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
+
version: 2.1.3
|
|
6
|
+
last-updated: 2026-10-01
|
|
7
|
+
skills:
|
|
8
|
+
- torusguard
|
|
9
|
+
- torusguard-audit
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# TorusGuard Review — Differential Incremental PR Review
|
|
13
|
+
|
|
14
|
+
TorusGuard Review performs rapid, surgical security review on Git changes (e.g. against `HEAD~1`, `main`, or PR target branch), analyzing only modified lines to prevent introducing security regressions.
|
|
15
|
+
|
|
16
|
+
## Invocation
|
|
17
|
+
|
|
18
|
+
- **Mode A (Terminal CLI):** `torusguard review [--diff <ref>]`
|
|
19
|
+
- **Mode B (AI Chat Slash Command):** `/torusguard review` or `/torusguard-review`
|
|
20
|
+
- **Mode C (Native MCP Tool):** `torusguard_review(target=".", diff_ref="HEAD~1")`
|
|
21
|
+
|
|
22
|
+
## Core Capabilities
|
|
23
|
+
|
|
24
|
+
1. **Sub-300ms Turnaround:** Only parses and checks modified/added lines in Git diffs.
|
|
25
|
+
2. **Net Security Score Delta:** Tracks introduced vs. resolved vulnerabilities (`+0 Introduced, -2 Resolved`).
|
|
26
|
+
3. **PR Gate Decision:** Blocks CI/CD pipelines if Critical or High severity flaws are introduced.
|
|
27
|
+
4. **Alibaba OpenCodeReview Parity:** Outputs ready-to-post pull request inline review comments.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: torusguard-threatmodel
|
|
3
|
+
description: Synthesizes an architectural STRIDE threat model, interactive Mermaid Data Flow Diagram (DFD), and trust boundary register into SECURITY_THREAT_MODEL.md.
|
|
4
|
+
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
+
version: 2.1.3
|
|
6
|
+
last-updated: 2026-10-01
|
|
7
|
+
skills:
|
|
8
|
+
- torusguard
|
|
9
|
+
- torusguard-audit
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# TorusGuard Threat Model — STRIDE & DFD Synthesizer
|
|
13
|
+
|
|
14
|
+
TorusGuard Threat Model automatically maps routes, trust boundaries, datastores, and egress sinks to construct an architectural Data Flow Diagram and formal STRIDE threat model.
|
|
15
|
+
|
|
16
|
+
## Invocation
|
|
17
|
+
|
|
18
|
+
- **Mode A (Terminal CLI):** `torusguard threatmodel`
|
|
19
|
+
- **Mode B (AI Chat Slash Command):** `/torusguard threatmodel` or `/torusguard-threatmodel`
|
|
20
|
+
- **Mode C (Native MCP Tool):** `torusguard_threatmodel(target=".")`
|
|
21
|
+
|
|
22
|
+
## Core Capabilities
|
|
23
|
+
|
|
24
|
+
1. **Automated DFD Generation:** Renders interactive Mermaid diagram showing Zones 1–4 (Clients, Gateways, Core Services, Datastores).
|
|
25
|
+
2. **STRIDE Risk Ledger:** Evaluates threats across Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, and Elevation of Privilege.
|
|
26
|
+
3. **Multi-Modal Vision Integration:** Discovers architectural diagrams and verifies that visual trust boundaries match code execution paths.
|
|
27
|
+
4. **Living Compliance Artifact:** Emits `SECURITY_THREAT_MODEL.md` at workspace root.
|