Skip to content

Commit 33ae45e

Browse files
committed
!
1 parent 66bbbc6 commit 33ae45e

13 files changed

Lines changed: 478 additions & 134 deletions

File tree

.oaignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ coverage/
1212
.venv/
1313
env/
1414
venv/
15-
tests/fixtures/
15+
tests/
1616
*.log

memory_bank.md

Lines changed: 57 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,57 @@
1-
# OpenAuditKit Memory Bank
2-
3-
## 🧠 Project Context
4-
**OpenAuditKit** is an open-source, CLI-based security audit tool designed to scan codebases for secrets and configuration vulnerabilities. It mimics the functionality of tools like "TruffleHog" or "Gitleaks" but with a modular, Python-native design.
5-
6-
## 🏗 Architecture
7-
We adopted a **Feature-Based Architecture** to ensure scalability and ease of future backend/dashboard integration.
8-
9-
### Structure
10-
- **`openaudit.core`**: Contains the domain models (`Finding`, `Rule`, `ScanContext`) and interfaces (`ScannerProtocol`). This layer is pure python, has no CLI dependencies, and is ready for use in a web API.
11-
- **`openaudit.features`**: Contains the business logic, organized by domain (e.g., `secrets`, `config`).
12-
- **`features.secrets`**: Implements regex and entropy-based secret detection.
13-
- **`openaudit.interface.cli`**: The Typer-based CLI application. It orchestrates the core and features.
14-
- **`openaudit.reporters`**: Handles output formatting (currently Rich Console).
15-
16-
### Key Decisions
17-
1. **Decoupling**: The scanner logic (`SecretScanner`) returns Pydantic models (`Finding`), not printed strings. This allows the same logic to feed a JSON API or a database in the future.
18-
2. **Offline-First**: The tool works entirely locally without external API calls.
19-
3. **Extensible Rules**: Rules are defined in YAML (`rules/secrets.yaml`), making it easy for users to add new patterns without changing code.
20-
21-
## 🛠 Implemented Features (v0.1.0)
22-
### 1. Core System
23-
- **Rules Engine**: Loads detection rules from YAML files.
24-
- **Domain Models**: Defined `Finding` with fields for file path, line number, and mocked secret.
25-
26-
### 2. Secret Scanner (`openaudit.features.secrets`)
27-
- **Regex Matching**: Compiles patterns from rules.
28-
- **Entropy Check**: Calculates Shannon entropy to reduce false positives (e.g., detecting random high-entropy strings).
29-
- **Masking**: Automatically masks detected secrets (e.g., `AKIA****************`) to prevent leakage in logs.
30-
31-
### 3. Config Scanner (`openaudit.features.config`)
32-
- **Infrastructure Code**: specific checks for `.env`, `Dockerfile`, and `docker-compose.yml`.
33-
- **Masking**: Enhanced masking for config values (keeping keys visible).
34-
35-
### 4. Developer Experience & CLI (DX)
36-
- **Smart Ignores**: Supports `.oaignore` (and `.gitignore` syntax) via `pathspec`.
37-
- **UX**: Progress bars, scan duration, and colored severity legends.
38-
- **Duration**: Timings displayed for performance visibility.
39-
40-
### 5. Rule System v2
41-
- **Confidence Scoring**: Rules now have `confidence` (LOW, MEDIUM, HIGH) to better triage findings.
42-
- **Validation**: RulesEngine validates regex and schema on load.
43-
- **Documentation**: Comprehensive `rules/README.md` for contributors.
44-
45-
### 6. CI/CD & Reporting
46-
- **CI Mode**: `--ci` flag for non-interactive runs with strict exit codes.
47-
- **Formats**: Supports `JSON` and `Rich Console` outputs.
48-
- **GitHub Actions**: Ready-to-use workflow template.
49-
50-
### 7. Packaging & Distribution
51-
- **PyPI Ready**: Configured with `pyproject.toml` and `setuptools`.
52-
- **Standalone**: Can be installed via `pip install .` and run as `openaudit`.
53-
- **Bundled Rules**: Default security rules are packaged with the library.
54-
55-
## 📊 Status
56-
- [x] Project Skeleton Created
57-
- [x] Core Domain & Protocols Implemented
58-
- [x] Rules Engine (YAML) Implemented
59-
- [x] Secret Scanner (Regex + Entropy) Implemented
60-
- [x] Config Scanner (.env, Dockerfile, docker-compose) Implemented
61-
- [x] CLI (Typer + Rich) Implemented
62-
- [x] Reporting System (JSON + Console) Implemented
63-
- [x] CI Mode & Exit Codes Implemented
64-
- [x] Manual Verification (Verified CI flags and Exit Codes)
65-
- [x] Test Suite Implemented (Core, Secrets, Config, CI Coverage > 90%)
66-
- [x] Rule System v2 Upgrade (Confidence field, Validation, Community Docs)
67-
- [x] Developer Experience (DX) Improvements (Ignore System, README Polish, CLI UX)
68-
- [x] Release & Distribution (Packaging, pyproject.toml, Entry Points)
69-
70-
## 🔮 Next Steps
71-
- Implement Inline Comments Support (e.g., `# openaudit:ignore`).
72-
- Plugin System for third-party scanners.
73-
- Dashboard Integration / HTML Report.
1+
# 🧠 OpenAuditKit Memory Bank
2+
3+
## 📅 Status: Active Development
4+
**Last Update**: 2025-12-21
5+
**Version**: 0.1.1+"Vibe"
6+
7+
## 🚀 Recent Major Changes (The "Vibe" Update)
8+
9+
### 1. VibeGuard (Technical Debt Scanner)
10+
- **Objective**: Catch "vibecoding" leftovers and non-engineering practices.
11+
- **Implementation**: `openaudit.features.debt.scanner.TechDebtScanner`
12+
- **Capabilities**:
13+
- 🏷️ **Annotations**: Detects `TODO`, `FIXME`, `BUG`, `HACK`.
14+
- 🐛 **Debug Leftovers**: Detects `print()`, `console.log()`, `debugger`, `pdb`.
15+
- 🔇 **Silent Failures**: Detects `except: pass`.
16+
- 🌐 **Hardcoded Values**: Detects IP addresses.
17+
18+
### 2. MCP Server Integration (Model Context Protocol) 🤖
19+
- **Objective**: Allow AI Agents (Claude, Cursor, etc.) to use OpenAuditKit as a tool.
20+
- **Implementation**: `openaudit.mcp.server` using `FastMCP`.
21+
- **Tools Exposed**:
22+
- `scan_workspace(path)`: Full security & quality scan.
23+
- `check_file(path)`: Single file analysis.
24+
- **Usage**: Run `openaudit mcp` to start the server.
25+
26+
### 3. UI/UX Overhaul 🎨
27+
- **Objective**: Make the CLI "fun" and modern.
28+
- **Implementation**: `openaudit.interface.cli.ui.UI` class.
29+
- **Features**:
30+
- ASCII Banner on startup.
31+
- Animated spinners (Dots, Earth, Weather).
32+
- Emoji-enriched, table-formatted reports.
33+
- "Scan Summary" verification panel.
34+
35+
## 🛠️ Known Technical Debt & TODOs
36+
37+
### 1. Windows Encoding Support
38+
- **Issue**: The new "fun" emojis (🔍, 🚀) cause `UnicodeEncodeError` on Windows (cp1254) terminals.
39+
- **Priority**: High (UX breaking).
40+
- **Fix**: Force UTF-8 encoding in `main.py` or strip emojis in legacy terminals.
41+
42+
### 2. Single File Scanning in MCP
43+
- **Issue**: `check_file` tool currently re-initializes full context or relies on disk presence.
44+
- **Improvement**: Allow passing file content directly in memory for true "pre-save" checks.
45+
46+
### 3. Project Self-Audit
47+
- **Status**: The project currently fails the self-audit (`openaudit scan .`).
48+
- **Issues Found**: 22 Total (1 Critical, 2 High).
49+
- **Details**:
50+
- **Tech Debt**: Multiple `TODO` and `Hack` annotations in `server.py` and `scanner.py`.
51+
- **Security**: Likely `except: pass` usage or similar high severity debt.
52+
- **Action**: Use VibeGuard to hunt them down in the next sprint.
53+
54+
## 🔮 Future Roadmap
55+
- [ ] **IDE Extensions**: VSCode extension using the MCP server.
56+
- [ ] **Git Hooks**: Pre-commit hook to run `openaudit scan --fail-on high`.
57+
- [ ] **Custom Rules**: Allow users to define custom "Vibe Checks" (rules).

openaudit/features/debt/__init__.py

Whitespace-only changes.

openaudit/features/debt/scanner.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from typing import List, Dict, Pattern
2+
import re
3+
import os
4+
from pathlib import Path
5+
from openaudit.core.domain import Finding, Severity, Confidence, ScanContext
6+
from openaudit.core.interfaces import ScannerProtocol
7+
8+
class TechDebtScanner(ScannerProtocol):
9+
"""
10+
Scans for technical debt, leftovers, and temporary code ("Vibe Checks").
11+
"""
12+
13+
def __init__(self, rules: Dict = None):
14+
self.patterns = {
15+
"ANNOTATION": {
16+
"pattern": re.compile(r"(TODO|FIXME|HACK|XXX|BUG):\s*(.*)", re.IGNORECASE),
17+
"severity": Severity.LOW,
18+
"desc": "Found code annotation"
19+
},
20+
"DEBUG_LEFTOVER": {
21+
"pattern": re.compile(r"^\s*(print\(|console\.log\(|debugger|import pdb; pdb.set_trace|import ipdb)", re.MULTILINE),
22+
"severity": Severity.MEDIUM,
23+
"desc": "Potential debug code left in production"
24+
},
25+
"SILENT_FAIL": {
26+
"pattern": re.compile(r"except\s*.*:\s*pass", re.MULTILINE),
27+
"severity": Severity.HIGH,
28+
"desc": "Silent exception handling (swallowed error)"
29+
},
30+
"HARDCODED_IP": {
31+
"pattern": re.compile(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"),
32+
"severity": Severity.MEDIUM,
33+
"desc": "Hardcoded IP address"
34+
}
35+
}
36+
37+
def _iterate_files(self, context: ScanContext):
38+
target = Path(context.target_path)
39+
if not target.exists():
40+
return
41+
42+
if target.is_file():
43+
yield target
44+
else:
45+
for root, dirs, files in os.walk(target):
46+
# Filter dirs in-place
47+
if context.ignore_manager:
48+
i = 0
49+
while i < len(dirs):
50+
d_path = Path(root) / dirs[i]
51+
if context.ignore_manager.is_ignored(d_path):
52+
del dirs[i]
53+
else:
54+
i += 1
55+
56+
if '.git' in dirs:
57+
dirs.remove('.git')
58+
59+
for file in files:
60+
file_path = Path(root) / file
61+
if context.ignore_manager and context.ignore_manager.is_ignored(file_path):
62+
continue
63+
yield file_path
64+
65+
def scan(self, context: ScanContext) -> List[Finding]:
66+
findings = []
67+
68+
for file_path in self._iterate_files(context):
69+
try:
70+
content = Path(file_path).read_text(encoding="utf-8", errors="ignore")
71+
lines = content.splitlines()
72+
73+
# Line-by-line scanning
74+
for i, line in enumerate(lines, 1):
75+
for key, rule in self.patterns.items():
76+
match = rule["pattern"].search(line)
77+
if match:
78+
# Skip if specific ignore comment is present
79+
if "noqa" in line or "@ignore" in line:
80+
continue
81+
82+
detail = match.group(0).strip()[:50] # truncated
83+
if key == "ANNOTATION":
84+
detail = match.group(2).strip() or "Untitled Task"
85+
86+
findings.append(Finding(
87+
rule_id=f"DEBT-{key}",
88+
description=f"{rule['desc']}: {detail}",
89+
file_path=str(Path(file_path).relative_to(context.target_path)),
90+
line_number=i,
91+
secret_hash=match.group(0).strip()[:20],
92+
severity=rule["severity"],
93+
confidence=Confidence.HIGH,
94+
category="technical_debt",
95+
remediation="Review and clean up code."
96+
))
97+
98+
except Exception:
99+
continue
100+
101+
return findings

openaudit/features/secrets/scanner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def _compile_rules(self):
1717
try:
1818
self.compiled_rules.append((rule, re.compile(rule.regex)))
1919
except re.error as e:
20-
print(f"Error compiling regex for rule {rule.id}: {e}")
20+
pass
2121

2222
def scan(self, context: ScanContext) -> List[Finding]:
2323
findings = []

openaudit/interface/cli/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import typer
2-
from .commands import scan_command, explain_command, config_app
2+
from .commands import scan_command, explain_command, config_app, mcp_command
33

44
app = typer.Typer(
55
name="OpenAuditKit",
@@ -16,5 +16,6 @@ def main_callback():
1616

1717
app.command(name="scan")(scan_command)
1818
app.command(name="explain")(explain_command)
19+
app.command(name="mcp")(mcp_command)
1920
app.add_typer(config_app, name="config")
2021

0 commit comments

Comments
 (0)