canlix 0.1.0__tar.gz
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.
- canlix-0.1.0/.env.example +10 -0
- canlix-0.1.0/.github/workflows/canlix-scan.yml +24 -0
- canlix-0.1.0/.github/workflows/ci.yml +30 -0
- canlix-0.1.0/.gitignore +11 -0
- canlix-0.1.0/CLAUDE.md +107 -0
- canlix-0.1.0/Dockerfile +15 -0
- canlix-0.1.0/PKG-INFO +537 -0
- canlix-0.1.0/README.md +498 -0
- canlix-0.1.0/action.yml +70 -0
- canlix-0.1.0/canlix/__init__.py +1 -0
- canlix-0.1.0/canlix/analyzers/__init__.py +42 -0
- canlix-0.1.0/canlix/analyzers/deps.py +135 -0
- canlix-0.1.0/canlix/analyzers/python_ast.py +3300 -0
- canlix-0.1.0/canlix/analyzers/ts_regex.py +3492 -0
- canlix-0.1.0/canlix/cli.py +310 -0
- canlix-0.1.0/canlix/engine.py +80 -0
- canlix-0.1.0/canlix/models.py +107 -0
- canlix-0.1.0/canlix/parsers/__init__.py +19 -0
- canlix-0.1.0/canlix/parsers/claude.py +72 -0
- canlix-0.1.0/canlix/parsers/cursor.py +41 -0
- canlix-0.1.0/canlix/parsers/generic.py +14 -0
- canlix-0.1.0/canlix/parsers/vscode.py +54 -0
- canlix-0.1.0/canlix/probes/__init__.py +15 -0
- canlix-0.1.0/canlix/probes/active.py +123 -0
- canlix-0.1.0/canlix/probes/base.py +46 -0
- canlix-0.1.0/canlix/probes/metadata.py +213 -0
- canlix-0.1.0/canlix/probes/runner.py +44 -0
- canlix-0.1.0/canlix/probes/transport.py +164 -0
- canlix-0.1.0/canlix/reporters/__init__.py +15 -0
- canlix-0.1.0/canlix/reporters/json_report.py +96 -0
- canlix-0.1.0/canlix/reporters/sarif.py +178 -0
- canlix-0.1.0/canlix/reporters/terminal.py +191 -0
- canlix-0.1.0/canlix/rules/__init__.py +9 -0
- canlix-0.1.0/canlix/rules/base.py +13 -0
- canlix-0.1.0/canlix/rules/config.py +82 -0
- canlix-0.1.0/canlix/rules/cross_server.py +235 -0
- canlix-0.1.0/canlix/rules/execution.py +115 -0
- canlix-0.1.0/canlix/rules/network.py +140 -0
- canlix-0.1.0/canlix/rules/permissions.py +81 -0
- canlix-0.1.0/canlix/rules/secrets.py +108 -0
- canlix-0.1.0/canlix/runtime/__init__.py +6 -0
- canlix-0.1.0/canlix/runtime/detectors.py +290 -0
- canlix-0.1.0/canlix/runtime/proxy.py +170 -0
- canlix-0.1.0/canlix/runtime/redact.py +55 -0
- canlix-0.1.0/canlix/runtime/sse_server.py +159 -0
- canlix-0.1.0/canlix/saas_client.py +61 -0
- canlix-0.1.0/docker-compose.yml +14 -0
- canlix-0.1.0/docs/adr/0001-saas-architecture.md +71 -0
- canlix-0.1.0/pyproject.toml +65 -0
- canlix-0.1.0/saas/__init__.py +1 -0
- canlix-0.1.0/saas/app.py +578 -0
- canlix-0.1.0/saas/auth.py +42 -0
- canlix-0.1.0/saas/diff.py +25 -0
- canlix-0.1.0/saas/ingest.py +101 -0
- canlix-0.1.0/saas/integrations.py +172 -0
- canlix-0.1.0/saas/migrate.py +168 -0
- canlix-0.1.0/saas/pg_store.py +447 -0
- canlix-0.1.0/saas/portal.html +537 -0
- canlix-0.1.0/saas/report.py +167 -0
- canlix-0.1.0/saas/security.py +28 -0
- canlix-0.1.0/saas/store.py +265 -0
- canlix-0.1.0/tests/__init__.py +0 -0
- canlix-0.1.0/tests/fixtures/clean_config.json +17 -0
- canlix-0.1.0/tests/fixtures/deps/package_risky.json +13 -0
- canlix-0.1.0/tests/fixtures/deps/package_safe.json +13 -0
- canlix-0.1.0/tests/fixtures/deps/requirements_pinned.txt +6 -0
- canlix-0.1.0/tests/fixtures/deps/requirements_unpinned.txt +7 -0
- canlix-0.1.0/tests/fixtures/fake_mcp_server.py +26 -0
- canlix-0.1.0/tests/fixtures/source/clean_server.py +23 -0
- canlix-0.1.0/tests/fixtures/source/clean_server.ts +49 -0
- canlix-0.1.0/tests/fixtures/source/vulnerable_server.py +1067 -0
- canlix-0.1.0/tests/fixtures/source/vulnerable_server.ts +895 -0
- canlix-0.1.0/tests/fixtures/vulnerable_config.json +31 -0
- canlix-0.1.0/tests/integration/__init__.py +0 -0
- canlix-0.1.0/tests/integration/test_pg_store.py +369 -0
- canlix-0.1.0/tests/test_analyzers.py +3292 -0
- canlix-0.1.0/tests/test_cross_server.py +98 -0
- canlix-0.1.0/tests/test_deps_analyzer.py +203 -0
- canlix-0.1.0/tests/test_integrations.py +236 -0
- canlix-0.1.0/tests/test_probes.py +373 -0
- canlix-0.1.0/tests/test_push.py +182 -0
- canlix-0.1.0/tests/test_report.py +99 -0
- canlix-0.1.0/tests/test_rules.py +266 -0
- canlix-0.1.0/tests/test_runtime.py +240 -0
- canlix-0.1.0/tests/test_saas_core.py +299 -0
- canlix-0.1.0/tests/test_saas_http.py +621 -0
- canlix-0.1.0/tests/test_sarif.py +220 -0
- canlix-0.1.0/tests/test_sse.py +373 -0
- canlix-0.1.0/tests/test_ts_analyzer.py +3316 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Canlix SaaS — environment variables
|
|
2
|
+
# Copy to .env and fill in values before running.
|
|
3
|
+
|
|
4
|
+
# PostgreSQL connection string.
|
|
5
|
+
# Leave unset to use the in-memory store (unit tests, local CLI).
|
|
6
|
+
CANLIX_DATABASE_URL=postgresql://canlix:canlix@localhost:5435/canlix
|
|
7
|
+
|
|
8
|
+
# Trust X-Forwarded-For from reverse proxy (Caddy, nginx).
|
|
9
|
+
# Set to 1 only when the proxy unconditionally overwrites XFF before forwarding.
|
|
10
|
+
CANLIX_TRUST_PROXY=0
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Canlix self-scan
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
schedule:
|
|
8
|
+
- cron: "0 6 * * 1"
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
security-events: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
scan:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Scan the Canlix source with Canlix
|
|
21
|
+
uses: ./
|
|
22
|
+
with:
|
|
23
|
+
path: canlix
|
|
24
|
+
fail-on: CRITICAL
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
|
|
23
|
+
- name: Install
|
|
24
|
+
run: pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Lint
|
|
27
|
+
run: ruff check . && ruff format --check .
|
|
28
|
+
|
|
29
|
+
- name: Test
|
|
30
|
+
run: pytest tests/ -v --tb=short
|
canlix-0.1.0/.gitignore
ADDED
canlix-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# CLAUDE.md — Canlix
|
|
2
|
+
|
|
3
|
+
Scanner de sécurité open source pour serveurs MCP et agents IA. Analyse statique (CFG/SRC), tests actifs (XSV), runtime (RUN), avec une couche SaaS multi-tenant optionnelle.
|
|
4
|
+
|
|
5
|
+
Langue de travail : français. Code, identifiants, commits, commentaires : anglais.
|
|
6
|
+
|
|
7
|
+
## 0. Protocole de session
|
|
8
|
+
|
|
9
|
+
1. Lire ce fichier, identifier la première tâche non cochée dans la section 7.
|
|
10
|
+
2. Annoncer en trois lignes : tâche, plan, sous-agents utilisés. Exécuter sans redemander.
|
|
11
|
+
3. Fin de tâche : tests passants, `py_compile` OK, `ruff check/format` propre, cocher `[x]` avec date et note.
|
|
12
|
+
4. Commit systématique après chaque tâche complète.
|
|
13
|
+
5. Fin de session : résumé six points (✅ Fait, ⏭ Suivant, 🔴 Bloqué, ❓ Décisions, 📝 À retenir, 📋 Proposals).
|
|
14
|
+
|
|
15
|
+
## 1. Commandes
|
|
16
|
+
|
|
17
|
+
Répertoire : `/home/kali/mcpprobe/`
|
|
18
|
+
|
|
19
|
+
| Commande | Description |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `python -m pytest tests/ --ignore=tests/integration -q` | Tests unitaires (sans DB) |
|
|
22
|
+
| `CANLIX_DATABASE_URL=... pytest tests/integration/ -v` | Tests d'intégration PgStore |
|
|
23
|
+
| `.venv/bin/ruff check . && .venv/bin/ruff format --check .` | Lint |
|
|
24
|
+
| `python -m saas.migrate` | Appliquer les migrations PostgreSQL |
|
|
25
|
+
| `uvicorn saas.app:app --reload` | Démarrer le SaaS (port 8000) |
|
|
26
|
+
| `docker compose up -d db` | PostgreSQL local (port 5435) |
|
|
27
|
+
| `canlix scan <path>` | Scan statique CLI |
|
|
28
|
+
| `canlix watch --http 7700` | Runtime proxy + SSE |
|
|
29
|
+
|
|
30
|
+
## 2. Architecture
|
|
31
|
+
|
|
32
|
+
Monolithe modulaire. Pas de microservices.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
canlix/ CLI et règles (CFG, SRC, XSV, RUN)
|
|
36
|
+
saas/ Couche SaaS FastAPI
|
|
37
|
+
app.py Routes HTTP (20+ endpoints)
|
|
38
|
+
store.py Store in-memory (tests unitaires)
|
|
39
|
+
pg_store.py Store PostgreSQL (production)
|
|
40
|
+
migrate.py Migrations idempotentes (0001-0004)
|
|
41
|
+
integrations.py Slack / PagerDuty / Jira dispatch
|
|
42
|
+
report.py Rapport HTML auto-suffisant
|
|
43
|
+
portal.html Dashboard web (login, projets, scans, intégrations)
|
|
44
|
+
auth.py scrypt email/password
|
|
45
|
+
security.py Tokens SHA-256 cnx_*
|
|
46
|
+
tests/
|
|
47
|
+
test_saas_http.py Tests HTTP (client FastAPI)
|
|
48
|
+
test_saas_core.py Tests Store in-memory
|
|
49
|
+
test_integrations.py Tests dispatch + Store CRUD
|
|
50
|
+
test_report.py Tests rendu HTML
|
|
51
|
+
integration/
|
|
52
|
+
test_pg_store.py Tests PgStore PostgreSQL (skip sans DB)
|
|
53
|
+
docs/adr/
|
|
54
|
+
0001-saas-architecture.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 3. Stack
|
|
58
|
+
|
|
59
|
+
- **CLI** : Python pur, zéro dépendance externe obligatoire
|
|
60
|
+
- **SaaS** : FastAPI + psycopg[binary,pool] + pydantic v2
|
|
61
|
+
- **DB** : PostgreSQL 16 + RLS (org_id sur projects/scans/findings/integrations)
|
|
62
|
+
- **Auth** : scrypt stdlib (email/password) + tokens SHA-256 256 bits
|
|
63
|
+
- **Dispatch** : urllib.request stdlib, threads daemon, timeout 8s — aucune dépendance réseau externe
|
|
64
|
+
|
|
65
|
+
## 4. Sécurité — règles non négociables
|
|
66
|
+
|
|
67
|
+
- `org_id` dérivé du jeton, jamais lu dans le corps ou l'URL
|
|
68
|
+
- Ressource d'un autre tenant → 404, pas 403
|
|
69
|
+
- `Integration.config` (webhook URLs, routing keys, tokens) : jamais loggué, jamais retourné dans les réponses API (`IntegrationOut` omet `config`)
|
|
70
|
+
- Clés et secrets : variables d'environnement, jamais commités
|
|
71
|
+
- Tout code d'authentification ou de crypto : relu par `security-reviewer` avant fusion
|
|
72
|
+
|
|
73
|
+
## 5. Variables d'environnement
|
|
74
|
+
|
|
75
|
+
| Variable | Description |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `CANLIX_DATABASE_URL` | URL PostgreSQL (optionnel — in-memory sans ça) |
|
|
78
|
+
| `CANLIX_SAAS_TOKEN_TTL_DAYS` | TTL des jetons (optionnel) |
|
|
79
|
+
|
|
80
|
+
## 6. État au 2026-11-12
|
|
81
|
+
|
|
82
|
+
- **1237 tests unitaires** passants · **24 tests PgStore** (skip sans `CANLIX_DATABASE_URL`)
|
|
83
|
+
- Ruff propre · HEAD `aa4d73c` sur `github.com/robkira01-max/canlix`
|
|
84
|
+
- Migration en prod : `python -m saas.migrate` à relancer après chaque déploiement
|
|
85
|
+
|
|
86
|
+
Livrables présents :
|
|
87
|
+
- Règles : CFG/SRC (config + source), XSV-001..004 (inter-serveurs), RUN-001..007 (runtime)
|
|
88
|
+
- Runtime Analyzer : proxy stdio, `canlix watch` / `canlix replay` / `canlix watch --http PORT`
|
|
89
|
+
- Action GitHub composite `action.yml` (SARIF) + workflow d'auto-scan
|
|
90
|
+
- SaaS HTTP : `/orgs`, `/auth/register`, `/auth/login`, `/portal`, `/orgs/me/integrations` (CRUD), `/projects/{id}/scans/{id}/report`
|
|
91
|
+
- Portal web : dashboard complet (token, projets, scans, intégrations Slack/PD/Jira, liens rapports)
|
|
92
|
+
- Migration 0004 : table `integrations` (config JSONB, isolation org)
|
|
93
|
+
- PgStore : parité complète avec Store in-memory + dispatch alertes sur `add_scan`
|
|
94
|
+
|
|
95
|
+
## 7. Tâches
|
|
96
|
+
|
|
97
|
+
### Backlog technique
|
|
98
|
+
- [x] **T-TM** 2026-11-12 — Vérification marque CIPO/USPTO/EUIPO toutes classes : 0 résultat. Publiable sur PyPI.
|
|
99
|
+
|
|
100
|
+
### Backlog business
|
|
101
|
+
- [ ] **M9** — Pilotes commerciaux : contacter 2-3 équipes sécurité, valider tarifs 29-99 USD/mois (hors code)
|
|
102
|
+
|
|
103
|
+
### Proposals (hors plan actuel)
|
|
104
|
+
- Portal : onglet « Membres » pour inviter des collègues (multi-utilisateur par org)
|
|
105
|
+
- CLI : `canlix ci` pour détecter automatiquement le runner CI et générer la config
|
|
106
|
+
- SaaS : endpoints d'administration (stats globales, désactivation d'org)
|
|
107
|
+
- Webhooks entrants : recevoir les résultats de scan depuis GitHub Actions directement
|
canlix-0.1.0/Dockerfile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
|
|
6
|
+
|
|
7
|
+
COPY pyproject.toml README.md ./
|
|
8
|
+
COPY canlix/ canlix/
|
|
9
|
+
COPY saas/ saas/
|
|
10
|
+
|
|
11
|
+
RUN pip install --no-cache-dir ".[saas]"
|
|
12
|
+
|
|
13
|
+
USER appuser
|
|
14
|
+
|
|
15
|
+
CMD ["uvicorn", "saas.app:app", "--host", "0.0.0.0", "--port", "8000"]
|