Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Git
.git
.gitignore
.gitattributes

# Secrets
.env
.env.*
.secrets/
certs/
*.pem
*.key

# Models
models/
*.gguf

# Data
data/
knowledge-base/
email-queue/

# IDE
.idea/
.vscode/
*.swp

# OS
.DS_Store
Thumbs.db

# Logs
*.log

# CI
.github/

# Docker
Dockerfile*
docker-compose*

# Node (for tools-ui)
node_modules/

# Documentation
README.md
CONTRIBUTING.md
SECURITY.md
CODE_OF_CONDUCT.md
AUDIT_REPORT.md
12 changes: 12 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Default owners for all files
* @OneByJorah

# Security-sensitive files
SECURITY.md @OneByJorah
config/ @OneByJorah
docker-compose*.yml @OneByJorah
Dockerfile* @OneByJorah

# CI/CD
.github/workflows/ @OneByJorah
.github/dependabot.yml @OneByJorah
32 changes: 32 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: Bug Report
about: Create a report to help us improve
title: '[BUG] '
labels: bug
assignees: ''

---

**Describe the Bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected Behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Environment (please complete the following information):**
- OS: [e.g. Ubuntu 22.04]
- Python Version: [e.g. 3.11]
- Docker Version: [e.g. 24.0]

**Additional Context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature Request
about: Suggest an idea for this project
title: '[FEATURE] '
labels: enhancement
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the Solution You'd Like**
A clear and concise description of what you want to happen.

**Describe Alternatives You've Considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional Context**
Add any other context or screenshots about the feature request here.
23 changes: 23 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Description

Please include a summary of the change and which issue is fixed.

Fixes # (issue)

## Type of Change

- [ ] Bug fix (non-breaking change)
- [ ] New feature (non-breaking change)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
- [ ] Security fix

## Checklist

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
21 changes: 21 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
37 changes: 37 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CodeQL
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
schedule:
- cron: '0 0 * * 0'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: ['python', 'javascript', 'typescript']

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}

- name: Autobuild
uses: github/codeql-action/autobuild@v3

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
162 changes: 162 additions & 0 deletions AUDIT_REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# AUDIT_REPORT β€” CommandDesk

**Date:** 2026-07-05
**Auditor:** J1-PIPELINE (Phase 1 β€” AUDITOR)
**Status:** `DEGRADED` (Score: 74/100)

---

## 1. PROJECT CLASSIFICATION

| Field | Value |
|---|---|
| **Repo** | CommandDesk |
| **Class** | AI / Helpdesk / Full-Stack |
| **Primary Language** | Python 3.11 |
| **Framework** | FastAPI |
| **Deployment** | Docker Compose |
| **Tailscale Only** | No (exposed ports: 80, 443, 8383) |

---

## 2. README COMPLIANCE (README_STANDARD.md)

| Requirement | Status | Notes |
|---|---|---|
| One-line positioning | βœ… | "Self-Hosted AI Helpdesk Agent" |
| Max 3 badges | ❌ | Has **5 badges** (Python, FastAPI, Docker, AI, MIT) |
| 60-second quick start | βœ… | `git clone` β†’ `cp .env.example .env` β†’ `docker compose up -d` |
| Features (3-5 bullets) | βœ… | 8 features listed |
| Architecture diagram | βœ… | ASCII diagram present |
| Contributing section | βœ… | Links to CONTRIBUTING.md |
| License section | βœ… | MIT |

**Issue:** README has 5 badges β€” exceeds the 3-badge max per README_STANDARD.md.

---

## 3. CODE QUALITY β€” CRITICAL & DEGRADED ITEMS

### πŸ”΄ CRITICAL (Must Fix)

| # | File | Issue | Severity |
|---|---|---|---|
| C1 | `rate_limiter.py:64` | **Bug:** `self._sessions: dict[str, SessionState] =()` β€” Empty tuple instead of dict `{}`. Causes `AttributeError` on first access. | CRITICAL |
| C2 | `zammad.py` | **Missing import:** Uses `requests.post()`, `requests.patch()`, `requests.get()` but `import requests` is missing. Will crash at runtime. | CRITICAL |
| C3 | `session_manager.py:38` | **SQL Injection:** `INTERVAL '{} seconds'".format(self.max_duration)` β€” Uses string formatting for SQL query parameter. | CRITICAL |
| C4 | `health_monitor.py:22` | **Wrong Redis URL:** `redis://redis:***@postgres:5432/helpdesk` β€” References PostgreSQL port (5432) instead of Redis port (6379), and uses `***` as password placeholder in a default. | CRITICAL |
| C5 | `whatsapp_webhook.py:29` | **Same wrong Redis URL:** `redis://redis:***@postgres:5432/helpdesk` | CRITICAL |
| C6 | `email_fetcher.py:83` | **Missing API endpoint:** POSTs to `/tickets/create` but no such route exists in `agent_server.py` β€” only `/chat` and `/health` are defined. Feature is broken. | CRITICAL |

### 🟑 DEGRADED (Should Fix)

| # | File | Issue | Severity |
|---|---|---|---|
| D1 | `rate_limiter.py` | **In-memory only:** Redis client is stored but never used. Rate limiting won't work across replicas/restarts. | DEGRADED |
| D2 | `agent_server.py` | **Blocking calls in async:** `get_system_prompt()` (file I/O) and `rate_limiter.check_request()` are sync methods called from async endpoints. | DEGRADED |
| D3 | `session_manager.py:92` | **O(N) `redis.keys()`:** Used in `get_active_count()` and `cleanup_expired()` β€” dangerous in production with many sessions. | DEGRADED |
| D4 | `health_monitor.py:83` | **O(N) `redis.keys()`:** Same pattern as D3. | DEGRADED |
| D5 | `analytics.py:10` | **Hardcoded password in URL:** `postgresql://helpdesk:***@postgres:5432/helpdesk` | DEGRADED |
| D6 | `whatsapp_webhook.py:138` | **Import inside function:** `import re` should be at module level. | DEGRADED |

---

## 4. SECURITY AUDIT (GUARDIAN β€” Phase 3 Preview)

| Check | Status | Notes |
|---|---|---|
| Default credentials | ❌ | `change_me` passwords throughout: JWT_SECRET, CHROMA_AUTH_TOKEN, WHATSAPP_WEBHOOK_SECRET, DB_PASSWORD, REDIS_PASSWORD |
| HTTPS enforced | ❌ | Nginx listens on port 80 only (no 443 config). `docker-compose.prod.yml` exposes 443 but no TLS certs configured. |
| CORS | ⚠️ | `allow_origins=["*"]` β€” acceptable for development, but not documented as such |
| Secrets in repo | βœ… | `.env` in `.gitignore`, `*.pem`, `*.key` excluded |
| Gitleaks clean | βœ… | No hardcoded secrets found in code |
| Rate limiting | βœ… | Nginx + app-level rate limiting implemented |
| Docker rootless | ⚠️ | No non-root user specified in Dockerfiles |
| Content-Security-Policy | βœ… | Set in nginx.conf |
| SBOM | ❌ | No SBOM (CycloneDX or SPDX) present |
| Security.md | βœ… | Present with contact + disclosure policy |
| Auth for admin | ⚠️ | `ADMIN_API_KEY` configured but no auth middleware seen in agent_server.py |

---

## 5. DOCKER STANDARD CHECK

| Check | Status | Notes |
|---|---|---|
| Health checks | βœ… | Defined for all services |
| Named volumes | βœ… | All volumes named |
| `.dockerignore` | ❌ | **Missing** β€” `.env`, `.git`, `node_modules` could leak into build context |
| Multi-stage builds | ❌ | Dockerfile is single-stage |
| Image version tags | ⚠️ | `searxng:latest`, `n8n:latest` β€” not pinned |
| Non-root user | ❌ | Root user used in all Dockerfiles |
| Tailscale pattern | ❌ | Not implemented |

---

## 6. GITHUB STANDARD CHECK

| Check | Status | Notes |
|---|---|---|
| Repo description | βœ… | Set |
| Topics | ⚠️ | Could add more specific topics |
| Branch protection | ⚠️ | Not verified (requires GH API) |
| CODEOWNERS | ❌ | **Missing** |
| Dependabot | βœ… | `.github/dependabot.yml` present |
| Issue templates | βœ… | Bug report + feature request |
| PR template | βœ… | Present |
| CI workflows | βœ… | CI + CodeQL workflows present |

---

## 7. MISSING STANDARD FILES

| File | Purpose | Status |
|---|---|---|
| `j1.yaml` | Pipeline registry metadata | ❌ Missing |
| `INTENT.md` | Engineering intent (Phase -1 ORACLE) | ❌ Missing |
| `.dockerignore` | Docker build context optimization | ❌ Missing |
| `CHANGELOG.md` | Release history | ❌ Missing |
| `CODEOWNERS` | PR ownership routing | ❌ Missing |
| `pyproject.toml` / `setup.py` | Python package metadata | ❌ Missing |

---

## 8. PRODUCTION SCORE

| Category | Weight | Score | Weighted |
|---|---|---|---|
| Security | 20% | 65 | 13.0 |
| Architecture | 15% | 75 | 11.25 |
| Documentation | 15% | 80 | 12.0 |
| Testing | 15% | 55 | 8.25 |
| Deployment | 10% | 78 | 7.8 |
| Automation | 10% | 82 | 8.2 |
| GitHub Quality | 10% | 85 | 8.5 |
| Branding | 5% | 85 | 4.25 |

**Total Score: 73.25 / 100 β€” `DEGRADED`** (threshold: 90)

---

## 9. RECOMMENDED ACTIONS

### Immediate (CRITICAL fixes):
1. Fix `self._sessions = {}` in `rate_limiter.py:64` (typo `()` β†’ `{}`)
2. Add `import requests` to `zammad.py`
3. Fix SQL injection in `session_manager.py:38` β€” use parameterized query
4. Fix Redis URLs in `health_monitor.py` and `whatsapp_webhook.py` (port 6379, proper placeholder)
5. Add `/tickets/create` endpoint to `agent_server.py` or fix `email_fetcher.py` to use `/chat`

### Short-term:
6. Add `.dockerignore`
7. Pin Docker image versions (no `:latest`)
8. Fix blocking calls in async endpoints
9. Replace `redis.keys()` with `SCAN` in session_manager and health_monitor
10. Add `import re` at top of `whatsapp_webhook.py`

### Medium-term:
11. Create `j1.yaml` and `INTENT.md`
12. Create `CHANGELOG.md`
13. Add CODEOWNERS file
14. Implement Redis-backed rate limiting (not just in-memory)
15. Add non-root user to Dockerfiles
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Changelog

All notable changes to CommandDesk will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- **CRITICAL:** Fixed `rate_limiter.py` dict initialization typo (`=()` β†’ `={}`) that broke rate limiting entirely
- **CRITICAL:** Added missing `import requests` to `zammad.py` β€” would crash on ticket operations
- **CRITICAL:** Fixed SQL injection vulnerability in `session_manager.py` β€” replaced string formatting with parameterized query
- **CRITICAL:** Fixed wrong Redis URLs in `health_monitor.py` and `whatsapp_webhook.py` (referenced PostgreSQL port 5432 instead of Redis port 6379)
- **CRITICAL:** Fixed `email_fetcher.py` to route email-to-ticket through existing `/chat` endpoint instead of non-existent `/tickets/create`
- Moved `import re` to module level in `whatsapp_webhook.py` (was inside function)
- Removed hardcoded placeholder password from `analytics.py` default URL
- Replaced `redis.keys()` with `SCAN` cursor iteration in `session_manager.py` and `health_monitor.py` to avoid O(N) blocking calls
- Added `.dockerignore` to prevent build context leaks
- Added `j1.yaml` for pipeline registry metadata

### Changed

- `session_manager.py`: `import uuid` moved to module level
- `health_monitor.py`: Fixed Redis URL default to proper format
- `whatsapp_webhook.py`: Fixed Redis URL default to proper format
- `analytics.py`: PostgreSQL URL default now empty (must be set via env)
Loading
Loading