Files
SkillSpector-Web/README.md
T

187 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SkillSpector Web
Eine schlanke Web-Oberfläche für [NVIDIA SkillSpector](https://github.com/NVIDIA/SkillSpector) –
prüft AI-Agent-Skills (Claude Code, Codex, MCP) auf Sicherheitsrisiken wie
Prompt-Injection, Daten-Exfiltration, Supply-Chain-Probleme oder gefährlichen
Code, **bevor** sie installiert werden.
**Live:** _(hier deine Subdomain eintragen, z. B. https://skillspector.obraasch.de/)_
---
## Was macht das Tool?
1. Du gibst die URL eines Git-Repositorys (oder eine ZIP-Datei) mit einem
AI-Agent-Skill an.
2. Im Hintergrund läuft `skillspector scan` – reine statische Analyse
(Regex, Python-AST, YARA-Signaturen), optional ergänzt durch eine
LLM-Bewertung der Dateiinhalte.
3. Du bekommst einen Risk Score (0–100) mit Einstufung `SAFE` / `CAUTION` /
`DO_NOT_INSTALL` sowie eine Liste der gefundenen Probleme.
Der gescannte Skill wird dabei **zu keinem Zeitpunkt ausgeführt**.
## Nutzung
Formular öffnen → Git-URL eintragen oder ZIP hochladen → "Scan starten".
Fertig. Kein Account nötig (sofern der Betreiber den öffentlichen Modus
aktiviert hat, siehe unten).
---
## Selbst betreiben: Setup mit Gitea + Portainer
### 1. Repository klonen/forken
Dieses Repository enthält alles, was für ein eigenständiges Deployment
nötig ist: `Dockerfile`, `requirements.txt`, `app.py`, `docker-compose.yml`.
### 2. Stack in Portainer anlegen
1. **Stacks → Add stack → Build method: Repository**
- Repository URL: die URL dieses Repos
- Reference: `refs/heads/main`
- Compose path: `docker-compose.yml`
2. **Environment variables** im Portainer-UI setzen (niemals ins Repo
committen):
| Variable | Zweck | Beispiel |
|---|---|---|
| `REQUIRE_AUTH` | `true` = privat mit Login, `false` = öffentlich ohne Login | `false` |
| `WEBUI_USER` / `WEBUI_PASSWORD` | Nur relevant wenn `REQUIRE_AUTH=true` | – |
| `HOST_PORT` | Host-Port, falls der Standard (8010) belegt ist | `8011` |
| `MAX_SCANS_PER_HOUR_PER_IP` | Rate-Limit pro IP | `10` |
| `MAX_CONCURRENT_SCANS` | Wie viele Scans gleichzeitig laufen dürfen | `2` |
| `ENABLE_LLM_OPTION` | Schaltet die LLM-Checkbox für Nutzer frei | `false` |
| `OPENROUTER_API_KEY` | Nur wenn `ENABLE_LLM_OPTION=true` | `sk-or-...` |
| `OPENROUTER_MODEL` | Modell-Slug bei OpenRouter | `anthropic/claude-sonnet-4.5` |
3. **Deploy the stack**.
### 3. Port-Konflikt beheben ("bind: address already in use")
Diese Fehlermeldung heißt: Ein anderer Container/Prozess auf deinem Server
belegt den Port bereits. Zwei Wege:
- **Anderen Port wählen** (empfohlen): Umgebungsvariable `HOST_PORT` in
Portainer setzen, z. B. `8010`, `8011` … Der Compose-Datei ist das schon
vorbereitet (`127.0.0.1:${HOST_PORT:-8010}:8000`).
- **Belegenden Prozess finden**: auf dem Server `sudo ss -tlnp | grep 8000`
(oder `docker ps` – oft ist es ein anderer Stack, der ebenfalls Port 8000
nutzt).
### 4. Automatische Updates
Im `Dockerfile` ist SkillSpector **ohne Versions-Pin** installiert
(`git+https://github.com/NVIDIA/skillspector.git`). Jeder Image-Rebuild holt
also automatisch die aktuellste Version. Damit das regelmäßig passiert:
1. Stack öffnen → **GitOps updates** aktivieren
2. Mechanismus **Polling**, Intervall z. B. `24h`
3. **Force redeployment** und **Re-pull image** aktivieren
→ Portainer baut das Image alle 24 h neu, auch ohne Änderung an diesem
Repo, und zieht damit automatisch die neueste SkillSpector-Version.
Falls deine Portainer-Version das nicht anbietet: den Stack gelegentlich
manuell über "Pull and redeploy" neu bauen.
---
## LLM-Analyse über OpenRouter einrichten
SkillSpector unterstützt LLM-Analyse über jeden OpenAI-kompatiblen Endpunkt.
[OpenRouter](https://openrouter.ai) ist genau das – daher funktioniert es mit:
```
SKILLSPECTOR_PROVIDER=openai
OPENAI_API_KEY=<dein-openrouter-key>
OPENAI_BASE_URL=https://openrouter.ai/api/v1
SKILLSPECTOR_MODEL=anthropic/claude-sonnet-4.5 # oder ein anderes Modell-Slug
```
Das ist im `docker-compose.yml` bereits vorbereitet (`OPENROUTER_API_KEY` /
`OPENROUTER_MODEL` setzen, `ENABLE_LLM_OPTION=true`). Zwei Dinge zu beachten:
- **Kosten/Abuse**: Ohne `ENABLE_LLM_OPTION=true` ist die LLM-Checkbox für
Nutzer gar nicht sichtbar – dein OpenRouter-Guthaben ist also standardmäßig
nicht angreifbar, selbst im öffentlichen Modus. Das Rate-Limit
(`MAX_SCANS_PER_HOUR_PER_IP`) begrenzt zusätzlich, wie oft ein einzelner
Nutzer die LLM-Analyse überhaupt anstoßen kann.
- **Nicht jedes Modell liefert zuverlässig strukturierte JSON-Antworten.**
Falls die LLM-Analyse mit einem Fehler abbricht, zuerst ein bekanntes,
instruction-following-starkes Modell testen (z. B. ein aktuelles
Claude- oder GPT-Modell über OpenRouter); im Zweifel bleibt `--no-llm`
(Standard) immer als zuverlässiger Fallback.
---
## Sicherheitsarchitektur
**Container-Ebene** (schützt deinen Server):
- Kein Docker-Socket-Mount – der Container kann weder andere Container noch
den Host steuern.
- `read_only: true` – Root-Dateisystem unveränderlich, nur `/tmp` und das
Scan-Verzeichnis sind flüchtiger RAM-Speicher (`tmpfs`).
- `cap_drop: ALL` und `no-new-privileges` – keine erweiterten Linux-Rechte.
- Ressourcenlimits (`mem_limit`, `cpus`) – ein hängender oder böswilliger
Scan kann den restlichen Server nicht belasten.
- Port nur auf `127.0.0.1` gebunden – öffentliche Erreichbarkeit ausschließlich
über deinen Reverse Proxy (TLS, eigene Subdomain).
**Anwendungs-Ebene** (schützt vor Missbrauch durch Fremdnutzer, relevant seit
öffentlichem Betrieb):
- **SSRF-Schutz**: Ziel-URLs werden aufgelöst und abgelehnt, wenn sie auf
private/interne/Loopback-Adressen zeigen (verhindert, dass jemand über das
Formular dein internes Netzwerk abscannt).
- **Rate-Limiting**: maximal `MAX_SCANS_PER_HOUR_PER_IP` Scans pro IP und
Stunde.
- **Concurrency-Limit**: maximal `MAX_CONCURRENT_SCANS` Scans gleichzeitig,
weitere Anfragen werden abgewiesen statt den Server zu überlasten.
- **Zeitlimit** je Scan (`SCAN_TIMEOUT_SECONDS`).
- **LLM-Analyse ist ein bewusstes Opt-in** des Betreibers, nicht der Nutzer.
- SkillSpector führt den gescannten Skill nie aus – nur statische Analyse
plus optionale LLM-Bewertung von Dateiinhalten.
- Jeder Scan läuft in einem eigenen, danach gelöschten Temp-Ordner. Nichts
wird dauerhaft gespeichert.
---
## Rechtliches für den öffentlichen Betrieb
Ein öffentlich erreichbares Angebot in Deutschland braucht ein Impressum
(§ 5 DDG) und eine Datenschutzerklärung. Falls du dieses Tool wie deine
anderen Werkzeuge über `software.obraasch.de` einbindest, kannst du die dort
vorhandenen Vorlagen (`impressum.html`, `datenschutz.html` aus dem
[Software-Uebersicht](https://git.obraasch.de/olli1986/Software-Uebersicht)-Repo)
weiterverwenden und um einen Hinweis ergänzen, dass bei aktivierter
LLM-Analyse Nutzereingaben an einen externen Anbieter (OpenRouter bzw. das
dort gewählte Modell) übertragen werden. Die WebUI selbst weist Nutzer direkt
im Formular darauf hin.
Diese Angaben sind nach bestem Wissen erstellt, ersetzen aber keine
Rechtsberatung.
---
## Lizenz
Dieser Web-Wrapper (`Dockerfile`, `app.py`, `requirements.txt`,
`docker-compose.yml`, diese README) steht unter der **MIT-Lizenz**, siehe
[`LICENSE`](./LICENSE).
Er installiert beim Bauen des Images das externe Paket **SkillSpector**
(NVIDIA, Apache License 2.0) – siehe [`THIRD_PARTY_NOTICES.md`](./THIRD_PARTY_NOTICES.md).
SkillSpector selbst ist nicht Teil dieses Repositories und bleibt vollständig
unter der Lizenz des Originalprojekts.
## Haftungsausschluss
Diese Software wird "wie sie ist" bereitgestellt, ohne jegliche Garantie.
Ein niedriger Risk Score ist keine Sicherheitsgarantie – SkillSpector ist ein
Hilfsmittel zur Risikoeinschätzung, keine vollständige Sicherheitsprüfung.
Für gescannte Inhalte, die von Nutzern eingereicht werden, wird keine
Verantwortung übernommen.