
Scanneur de sécurité pour les compétences des agents IA. Détectez les vulnérabilités, les schémas malveillants, les risques de sécurité, les injections de prompt, l'exfiltration de données et les risques liés à la chaîne d'approvisionnement dans les compétences Claude Code, Codex et MCP avant de les installer.
Scanner de sécurité pour les compétences d'agents IA. Détectez les vulnérabilités, les schémas malveillants et les risques de sécurité avant d'installer des compétences d'agents IA.
Les compétences d'agents IA (utilisées par Claude Code, Codex CLI, Gemini CLI, etc.) s'exécutent avec une confiance implicite et une vérification minimale. Les recherches montrent que 26,1 % des compétences contiennent des vulnérabilités et 5,2 % présentent une probable intention malveillante.
SkillSpector vous aide à répondre à la question : « Cette compétence est-elle sûre à installer ? »
SkillSpector fait partie du pipeline NVIDIA Verified Skills, qui analyse, évalue et signe les compétences d'agents avant leur publication. Les compétences qui réussissent sont publiées dans le catalogue de compétences NVIDIA.
Avis sur les logiciels open source : Ce projet téléchargera et installera des projets logiciels open source tiers supplémentaires. Examinez les conditions de licence de ces projets open source avant toute utilisation.
Créez et activez d'abord un environnement virtuel (toutes les cibles make supposent que le venv est actif). Utilisez uv ou pip ; le Makefile utilise uv si disponible, sinon pip.
Installation rapide avec uv (CLI uniquement) :```bash uv tool install git+https://github.com/NVIDIA/skillspector.git
Si vous prévoyez d'exécuter `skillspector mcp`, installez l'extra MCP lors de l'installation:```bash
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
À partir de la source :```bash
git clone https://github.com/NVIDIA/skillspector.git cd skillspector
uv venv .venv && source .venv/bin/activate
make install
make install-dev
### Docker (Python non requis)
Exécutez SkillSpector sans installer Python en le construisant localement à partir du [Dockerfile](https://github.com/nvidia/skillspector/blob/HEAD/Dockerfile) inclus. L'image est basée sur l'image officielle Docker Python `3.12-slim-bookworm`.
**Construire l'image :**```bash
make docker-build
# or: docker build -t skillspector .
Analyser un répertoire local en montant votre répertoire actuel dans /scan, le répertoire de travail du conteneur :```bash
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
**Scan avec analyse LLM** en passant les identifiants via un fichier `.env` local :```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
No input content was provided in the message. Please provide the chunk text to translate.```bash
docker run --rm
-v "$PWD:/scan"
--env-file .env
skillspector scan ./my-skill/
Ou passez les identifiants directement depuis votre environnement shell :```bash
docker run --rm \
-v "$PWD:/scan" \
-e SKILLSPECTOR_PROVIDER=anthropic \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
skillspector scan ./my-skill/
Écrivez un rapport dans le système de fichiers de l'hôte en écrivant dans le répertoire monté:```bash
docker run --rm
-v "$PWD:/scan"
skillspector scan ./my-skill/ --no-llm --format json --output report.json
**Alias facultatif** pour les analyses statiques répétées :```bash
alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector'
skillspector-docker scan ./my-skill/ --no-llm
skillspector scan ./my-skill/
skillspector scan ./SKILL.md
skillspector scan https://github.com/user/my-skill
skillspector scan ./my-skill.zip
#### Limites de taille
SkillSpector impose deux limites indépendantes sur les entrées distantes et les archives afin de borner l'impact des téléchargements surdimensionnés et des bombes zip :
- **Limite par ingestion** : `INGEST_MAX_BYTES` (100 MiB) — appliquée aux téléchargements d'URL en flux, à la taille totale non compressée des archives zip et à l'utilisation disque des dépôts Git après clonage.
- **Limite de membres zip** : `INGEST_MAX_ZIP_MEMBERS` (10 000) — limite le nombre d'entrées dans un seul zip.
Notez que la limite d'analyse de 1 Mo par fichier (`MAX_FILE_BYTES`) est une limite distincte et en aval : elle borne ce que les analyseurs individuels liront à partir d'un répertoire déjà ingéré. Les limites d'ingestion ci-dessus bornent la quantité de contenu qui peut atterrir sur le disque en premier lieu. Toute violation de l'une ou l'autre de ces limites d'ingestion échoue en mode fermé avec une `IngestLimitExceededError`.
### Formats de sortie```bash
# Terminal output (default) - pretty formatted
skillspector scan ./my-skill/
# JSON output - machine readable
skillspector scan ./my-skill/ --format json --output report.json
# Markdown output - for documentation
skillspector scan ./my-skill/ --format markdown --output report.md
# SARIF output - for CI/CD integration and IDE tooling
skillspector scan ./my-skill/ --format sarif --output report.sarif
Scannez des répertoires entiers de compétences en parallèle à partir de contrib/batch_scan/ :```bash
python -m contrib.batch_scan.batch_scan ./my-skills/ --no-llm
python -m contrib.batch_scan.batch_scan ./my-skills/ --workers 20 -f json -o report.json
python -m contrib.batch_scan.batch_scan ./tests/fixtures/ -f terminal --workers 20
Prend en charge la détection multilingue (zh/ja/ko) et la sortie terminal/JSON/Markdown.
Pour les scans LLM avec une concurrence plus élevée, configurez plusieurs clés API en suivant
[`.env.example`](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/.env.example) — le pool améliore le débit
et la résilience, à condition que les clés ne partagent pas une limite de débit au niveau du compte.
Consultez le [guide contrib](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/docs/) pour plus de détails.
> **Note sur la prise en charge des LLM :** La configuration par défaut cible DeepSeek comme
> l'option publique la moins chère. DeepSeek-Chat est
> [prévu pour être retiré](https://api-docs.deepseek.com/), et le contributeur
> ne dispose pas de matériel pour tester avec des modèles locaux. Le scanner par lot a été
> initialement testé avec des endpoints compatibles OpenAI — le manque de
> prise en charge de sortie structurée de DeepSeek a nécessité des correctifs manuels d'analyse JSON. Si vous pouvez
> contribuer à un backend plus universel (Ollama, vLLM, ou un autre fournisseur),
> les PR sont très bienvenues.
### Suppression des faux positifs (baseline)
Supprimez les résultats connus/acceptés afin que le score de risque reflète uniquement les
problèmes non triés et que les nouvelles analyses ne révèlent que de *nouveaux* résultats. Consultez le
[guide de suppression](https://github.com/nvidia/skillspector/blob/HEAD/docs/SUPPRESSION.md) pour la référence complète.```bash
# Accept all current findings into a baseline (run once), then commit it.
skillspector baseline ./my-skill/ -o .skillspector-baseline.yaml
# Scan against the baseline — only NEW findings are reported and scored.
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml
# Review what was suppressed (still excluded from the score).
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml --show-suppressed
Une baseline peut également utiliser des règles glob tolérantes à la dérive (par identifiant de règle, chemin de fichier ou
message) — voir .skillspector-baseline.example.yaml.
Les baselines à empreinte exacte sont liées aux preuves : modifier la source analysée ou
la version de SkillSpector maintient le constat actif jusqu'à ce qu'il soit réexaminé.
Lorsqu'une baseline sélectionnée ou sa sortie est stockée dans le répertoire de compétence
SkillSpector exclut ce fichier exact de l'analyse de contenu afin que son
texte de suppression ne puisse pas créer de constats ni être inclus dans les empreintes régénérées ;
les fichiers frères restent dans le périmètre d'analyse normal.
Pour de meilleurs résultats, configurez un endpoint LLM compatible OpenAI pour
l'analyse sémantique. Choisissez un fournisseur avec SKILLSPECTOR_PROVIDER ; les fournisseurs hébergés fournissent des modèles par défaut intégrés, tandis que les fournisseurs CLI se rabattent sur le modèle par défaut du runtime local, sauf si SKILLSPECTOR_MODEL est défini. SkillSpector fonctionne également avec
les serveurs locaux compatibles OpenAI (Ollama, vLLM, llama.cpp) et les
passerelles d'inférence gérées.
export SKILLSPECTOR_PROVIDER=openai export OPENAI_API_KEY=sk-... skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=anthropic export ANTHROPIC_API_KEY=sk-ant-... skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=anthropic_proxy export ANTHROPIC_PROXY_ENDPOINT_URL=https://my-gateway.example.com/models/claude-sonnet-4-6:streamRawPredict export ANTHROPIC_PROXY_API_KEY=your-bearer-token export SKILLSPECTOR_MODEL=claude-sonnet-4-6 skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=bedrock
export AWS_REGION=us-west-2 # default if unset
skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=nv_build export NVIDIA_INFERENCE_KEY=nvapi-... skillspector scan ./my-skill/
claude auth login sessionexport SKILLSPECTOR_PROVIDER=claude_cli
skillspector scan ./my-skill/
codex login sessionexport SKILLSPECTOR_PROVIDER=codex_cli skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=openai export OPENAI_API_KEY=ollama export OPENAI_BASE_URL=http://localhost:11434/v1 export SKILLSPECTOR_MODEL=llama3.1:8b skillspector scan ./my-skill/
export SKILLSPECTOR_MODEL=gpt-5.2 skillspector scan ./my-skill/
skillspector scan ./my-skill/ --no-llm
### Serveur MCP
Exécutez SkillSpector en tant que serveur [Model Context Protocol](https://modelcontextprotocol.io) afin que n'importe quel agent compatible MCP (Claude Code, Codex CLI, Gemini CLI) ou runtime distant puisse appeler l'analyse comme un outil et **conditionner les installations de skills/MCP au résultat** — transformant SkillSpector en garde-fou d'exécution plutôt qu'en étape d'audit hors bande.
`skillspector mcp` nécessite `skillspector[mcp]`.```bash
# Install, or reinstall if you already used the CLI-only path
uv tool install --force 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
# FastMCP stdio transport for local CLI agents
skillspector mcp
# streamable HTTP/SSE transport for remote / A2A callers
skillspector mcp --transport http --host 127.0.0.1 --port 8000
Le transport stdio est le chemin FastMCP actuel pour les agents CLI locaux, et le blocage d'initialisation signalé dans le problème #199 s'y applique toujours.
Le serveur expose un seul outil:
scan_skill(target, use_llm=true, output_format="json") — analyse une URL
Git, une URL de fichier, un fichier .zip .md, ou un répertoire et renvoie un
verdict structuré : risk_score (0-100), severity, recommendation,
safe_to_install et findings. Il signale également llm_used / scan_mode
afin qu'un score faible provenant d'une analyse statique uniquement ne soit
jamais confondu avec une analyse complète propre.Enregistrez-le avec Claude Code via:```bash claude mcp add skillspector -- skillspector mcp
> **Sécurité — modèle de confiance du transport HTTP**
>
> Le transport HTTP fonctionne **sans authentification**. Tout appelant pouvant
> atteindre le port peut invoquer `scan_skill`. Via stdio ou `127.0.0.1`, il s'agit
> de la même frontière de confiance que pour la CLI. Si vous écoutez sur une interface routable :
>
> - Placez le serveur derrière un proxy inverse authentifiant (par exemple nginx + mTLS)
> avant de l'exposer à l'extérieur.
> - Les chemins locaux et les URL `file://` sont **automatiquement rejetés** via HTTP afin
> d'empêcher des appelants non authentifiés de lire des fichiers arbitraires de l'hôte. Seules
> les URL Git distantes et `.zip` sont acceptées.
## Patterns de vulnérabilité
SkillSpector détecte **68 patterns de vulnérabilité** répartis dans 17 catégories :
### Injection de prompt (5 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| P1 | Remplacement d'instructions | ÉLEVÉ | Commandes visant à ignorer les contraintes de sécurité |
| P2 | Instructions cachées | ÉLEVÉ | Directives malveillantes dans les commentaires/texte invisible |
| P3 | Commandes d'exfiltration | ÉLEVÉ | Instructions visant à transmettre le contexte à l'extérieur |
| P4 | Manipulation du comportement | MOYEN | Instructions subtiles modifiant les décisions de l'agent |
| P5 | Contenu nuisible | CRITIQUE | Instructions pouvant causer des dommages physiques |
### Anti-refus (3 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| AR1 | Suppression du refus | ÉLEVÉ | Instructions pour ne jamais refuser ou toujours obéir (par exemple "ne jamais refuser", "toujours obéir") |
| AR2 | Suppression des avertissements | ÉLEVÉ | Instructions visant à omettre les avertissements, les mentions légales ou les commentaires éthiques (par exemple "pas de mentions", "ne moralisez pas") |
| AR3 | Annulation de la politique de sécurité | ÉLEVÉ | Formulation de jailbreak qui annule les garde-fous (par exemple "vous n'avez aucune restriction", "ignorez vos directives", "faites n'importe quoi maintenant") |
### Exfiltration de données (4 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| E1 | Transmission externe | MOYEN | Envoi de données vers des URL externes |
| E2 | Collecte de variables d'environnement | ÉLEVÉ | Énumération, copie ou recherche de données d'environnement pour collecter des secrets |
| E3 | Énumération du système de fichiers | MOYEN | Analyse des répertoires à la recherche de fichiers sensibles |
| E4 | Fuite de contexte | ÉLEVÉ | Transmission du contexte de conversation à l'extérieur |
### Élévation de privilèges (3 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| PE1 | Permissions excessives | FAIBLE | Demande d'accès au-delà des fonctionnalités déclarées |
| PE2 | Exécution sudo/root | MOYEN | Invocation de privilèges système élevés |
| PE3 | Accès aux identifiants | ÉLEVÉ | Lecture de clés SSH, jetons et mots de passe |
### Chaîne d'approvisionnement (6 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| SC1 | Dépendances non épinglées | FAIBLE | Absence de contraintes de version sur les paquets |
| SC2 | Récupération de script externe | ÉLEVÉ | curl \| bash et exécution de code à distance |
| SC3 | Code obfusqué | ÉLEVÉ | Exécution encodée en Base64/hexadécimal |
| SC4 | Dépendances vulnérables connues | ÉLEVÉ | Dépendances présentant des CVE connues (recherche en direct sur OSV.dev) |
| SC5 | Dépendances abandonnées | MOYEN | Paquets non maintenus sans mises à jour de sécurité |
| SC6 | Typosquatting | ÉLEVÉ | Noms de paquets similaires à ceux de paquets populaires |
### Agentivité excessive (4 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| EA1 | Accès illimité aux outils | ÉLEVÉ | Accès aux outils sans entraves ni contraintes |
| EA2 | Prise de décision autonome | ÉLEVÉ | Décisions à fort impact sans intervention humaine |
| EA3 | Dépassement de périmètre | MOYEN | Capacités allant au-delà de l'objectif déclaré |
| EA4 | Accès illimité aux ressources | MOYEN | Absence de limites de débit ou de quotas sur la consommation des ressources |
### Gestion des sorties (3 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| OH1 | Injection de sortie non validée | ÉLEVÉ | Sortie du modèle utilisée sans assainissement |
| OH2 | Sortie inter-contextes | MOYEN | Sortie traversant les frontières de confiance sans validation |
| OH3 | Sortie illimitée | MOYEN | Aucune limite sur la taille ou le débit de génération des sorties |
### Fuite du prompt système (3 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| P6 | Fuite directe | ÉLEVÉ | Instructions qui exposent les prompts système ou les règles internes |
| P7 | Extraction indirecte | MOYEN | Extraction via reformulation, traduction ou canaux secondaires |
| P8 | Exfiltration par outil | ÉLEVÉ | Prompts système exfiltrés via des écritures de fichiers ou des requêtes réseau |
### Empoisonnement de la mémoire (3 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| MP1 | Injection de contexte persistante | ÉLEVÉ | Contenu conçu pour persister à travers les interactions |
| MP2 | Remplissage de la fenêtre de contexte | MOYEN | Contenu de remplissage qui déplace les contraintes de sécurité |
| MP3 | Manipulation de la mémoire | ÉLEVÉ | Altération de la mémoire de l'agent ou de l'état stocké |
### Mauvais usage des outils (3 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| TM1 | Abus de paramètres d'outil | ÉLEVÉ | Paramètres conçus pour un comportement non intentionnel (shell=True, --force) |
| TM2 | Abus de chaînage | ÉLEVÉ | Chaînes d'outils qui contournent les vérifications de sécurité individuelles |
| TM3 | Valeurs par défaut non sûres | MOYEN | Valeurs par défaut trop permissives (TLS désactivé, aucune authentification) |
### Agent voyou (2 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| RA1 | Auto-modification | CRITIQUE | Modification de son propre code ou de sa configuration à l'exécution |
| RA2 | Persistance de session | ÉLEVÉ | Persistance non autorisée via des tâches cron ou des scripts de démarrage |
### Abus de déclencheurs (3 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| TR1 | Déclencheur trop large | MOYEN | Motifs de déclenchement correspondant à des mots courants |
| TR2 | Déclencheur de commande fantôme | ÉLEVÉ | Déclencheurs qui se substituent aux commandes intégrées ou à d'autres compétences |
| TR3 | Déclencheur appât par mots-clés | MOYEN | Déclencheurs génériques conçus pour maximiser l'activation |
### AST comportemental (9 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| AST1 | Appel à exec() | CRITIQUE | exec() direct permettant l'exécution de code arbitraire |
| AST2 | Appel à eval() | ÉLEVÉ | eval() direct évaluant des expressions arbitraires |
| AST3 | Import dynamique | ÉLEVÉ | \_\_import\_\_() chargeant des modules arbitraires à l'exécution |
| AST4 | Appel à subprocess | ÉLEVÉ | Exécution de commandes externes via subprocess |
| AST5 | os.system / famille exec | ÉLEVÉ | Commandes shell via le module os |
| AST6 | Appel à compile() | MOYEN | Création d'objets code à partir de chaînes |
| AST7 | getattr() dynamique | MOYEN | Accès arbitraire aux attributs avec des noms non littéraux |
| AST8 | Chaîne d'exécution dangereuse | CRITIQUE | exec/eval combinés à une source dynamique (réseau, données encodées) |
| AST9 | Puits getattr() réflexif | ÉLEVÉ | exec réflexif via `getattr(os,'system')` / `getattr(builtins,'exec')` qui contourne AST1/AST5 |
### Taint Tracking (5 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| TT1 | Flux de données direct | ÉLEVÉ | Les données circulent directement d'une source vers un puits sans assainissement |
| TT2 | Flux via variable intermédiaire | MOYEN | Les données circulent de la source vers le puits à travers des variables intermédiaires |
| TT3 | Chaîne d'exfiltration d'identifiants | CRITIQUE | Les identifiants (variables d'environnement, secrets) circulent vers des puits de sortie réseau |
| TT4 | Lecture de fichier vers exfiltration réseau | ÉLEVÉ | Le contenu des fichiers circule vers des puits de sortie réseau |
| TT5 | Entrée externe vers exécution de code | CRITIQUE | L'entrée réseau ou utilisateur circule vers des puits exec/eval/subprocess |
### Signatures YARA (4 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| YR1 | Correspondance de malware | CRITIQUE | Correspondance de règle YARA pour des signatures de malwares connus |
| YR2 | Correspondance de webshell | CRITIQUE | Correspondance de règle YARA pour des motifs de webshell |
| YR3 | Correspondance de cryptomineur | ÉLEVÉ | Correspondance de règle YARA pour des indicateurs de minage de crypto-monnaie |
| YR4 | Correspondance d'outil de piratage / exploit | ÉLEVÉ | Correspondance de règle YARA pour des outils de piratage ou du code d'exploitation |
### Moindre privilège MCP (4 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| LP1 | Capacité sous-déclarée | ÉLEVÉ | Le code utilise des capacités non listées dans les permissions déclarées |
| LP2 | Permission générique (wildcard) | MOYEN | La liste des permissions contient des jokers (\*, all, full, any) |
| LP3 | Déclaration de permission manquante | MOYEN | Aucun champ permissions mais le code possède des capacités détectables |
| LP4 | Permission sur-déclarée | FAIBLE | Permission déclarée mais aucune capacité de code correspondante trouvée |
### Empoisonnement d'outils MCP (4 patterns)
| ID | Pattern | Sévérité | Description |
|----|---------|----------|-------------|
| TP1 | Instructions cachées | ÉLEVÉ | Directives cachées dans les métadonnées (commentaires HTML, caractères de largeur nulle, base64, URI de données) |
| TP2 | Supercherie Unicode | ÉLEVÉ | Homoglyphes, surcharges RTL, identifiants à écritures mixtes dans les métadonnées d'outil |
| TP3 | Injection dans la description des paramètres | MOYEN | Motifs d'injection dans les définitions de paramètres (remplacements, jetons système, valeurs par défaut malveillantes) |
| TP4 | Inadéquation description-comportement | MOYEN | La description d'outil déclarée ne correspond pas au comportement réel du code (basé sur LLM) |
Tous les patterns détectés sont listés dans les tableaux ci-dessus.
## Score de risque
### Calcul du score
- **Problèmes critiques** : +50 points
- **Problèmes élevés** : +25 points
- **Problèmes moyens** : +10 points
- **Problèmes faibles** : +5 points
- **Scripts exécutables** : multiplicateur 1.3x
### Niveaux de gravité
| Score | Sévérité | Recommandation |
|-------|----------|----------------|
| 0-20 | FAIBLE | SÛR |
| 21-50 | MOYEN | PRUDENCE |
| 51-80 | ÉLEVÉ | NE PAS INSTALLER |
| 81-100 | CRITIQUE | NE PAS INSTALLER |
## Exemple de sortie
### Sortie terminal```
SkillSpector Security Report v2.0.0
Skill: suspicious-skill
Source: ./suspicious-skill/
Scanned: 2026-01-29 10:30:00 UTC
Risk Assessment
Metric Value
Score 78/100
Severity HIGH
Recommendation DO NOT INSTALL
Components (3)
File Type Lines Executable
SKILL.md markdown 142 No
scripts/sync.py python 87 Yes
requirements.txt text 3 No
Issues (2)
HIGH: Env Variable Harvesting (E2)
Location: scripts/sync.py:23
Finding: for key, val in os.environ.items():...
Confidence: 94%
Explanation: This code collects environment variables containing
API keys and secrets, then sends them to an external server.
HIGH: External Transmission (E1)
Location: scripts/sync.py:45
Finding: requests.post("https://api.skill.io/env"...
Confidence: 89%
Explanation: Data is being sent to an external server. Combined
with env harvesting above, this indicates credential exfiltration.
Fournisseurs CLI (
claude_cli,codex_cli) : aucune clé API n'est nécessaire. L'authentification est gérée entièrement par la session de connexion propre à l'agent CLI (claude auth login/codex login). SkillSpector ne lit ni ne transmet jamais de clés API lorsque ces fournisseurs sont actifs. Le sous-processus est exécuté dans un bac à sable renforcé : outils désactivés, pas de MCP, mode sandbox en lecture seule (codex) et le contenu non fiable des compétences n'est transmis que via stdin.
skillspector scan --help
Options: -f, --format [terminal|json|markdown|sarif] Output format [default: terminal] -o, --output PATH Output file path --no-llm Skip LLM analysis (static only) --yara-rules-dir PATH Extra YARA rules directory -b, --baseline PATH Suppress findings listed in a baseline --show-suppressed List baseline-suppressed findings -V, --verbose Show detailed progress --help Show this message and exit
skillspector baseline [-o FILE] [--no-llm] [--reason TEXT]
## Intégrer SkillSpector
SkillSpector est conçu pour être piloté par d'autres outils (pipelines CI, points de contrôle d'installation, intégrations d'éditeur). Son code de sortie et sa sortie JSON constituent un contrat stable.
### Codes de sortie
`skillspector scan` se termine avec :
| Code | Signification |
|------|---------|
| `0` | Analyse terminée, `risk_score` ≤ 50 (recommandation `SAFE` ou `CAUTION`) |
| `1` | Analyse terminée, `risk_score` > 50 (recommandation `DO_NOT_INSTALL`) |
| `2` | Erreur (entrée invalide, source illisible, défaillance interne) |
> Le code de sortie regroupe `SAFE` et `CAUTION` en `0`. Pour les traiter différemment (par ex. *avertir* pour `CAUTION` mais *bloquer* pour `DO_NOT_INSTALL`), lisez le champ `recommendation` dans la sortie JSON plutôt que de vous fier au code de sortie.
### Sortie lisible par machine
`--format json` produit un rapport JSON ; sans `--output`/`-o`, il est écrit sur stdout :```bash
skillspector scan ./my-skill/ --format json
La forme de premier niveau est (cet exemple montre une analyse complète assistée par LLM ; avec --no-llm, metadata.llm_requested est false) :```json
{
"skill": { "name": "...", "source": "...", "scanned_at": "<ISO 8601>" },
"risk_assessment": { "score": 0, "severity": "LOW", "recommendation": "SAFE" },
"components": [ { "path": "...", "type": "...", "lines": 0, "executable": false, "size_bytes": 0 } ],
"issues": [ { "id": "...", "category": "...", "severity": "...", "confidence": 0.0, "location": { "file": "...", "start_line": 0 } } ],
"metadata": {
"has_executable_scripts": false,
"skillspector_version": "...",
"llm_requested": true,
"llm_available": true,
"inference_usage": [
{
"node": "semantic_security_discovery",
"request_kind": "structured_output",
"provider": "nv_inference",
"model": "azure/anthropic/claude-opus-4-6",
"model_source": "provider_response",
"usage_source": "provider_response",
"prompt_tokens": 1000,
"completion_tokens": 100,
"cached_tokens": 400,
"cache_write_tokens": 50,
"total_tokens": 1100
}
]
}
}
- `risk_assessment.severity` ∈ `LOW | MEDIUM | HIGH | CRITICAL`.
- `risk_assessment.recommendation` ∈ `SAFE | CAUTION | DO_NOT_INSTALL`, selon la sévérité : `LOW → SAFE`, `MEDIUM → CAUTION`, `HIGH`/`CRITICAL → DO_NOT_INSTALL`.
- `metadata.llm_error` n'apparaît que lorsque l'analyse LLM a été demandée mais était indisponible.
- `metadata.inference_usage` contient un enregistrement assaini par réponse LLM lorsque le
fournisseur expose des compteurs de jetons. Il s'agit d'une liste vide lorsque l'utilisation est indisponible ;
SkillSpector n'estime jamais les jetons manquants. Les totaux de prompt incluent les lectures
et écritures de cache afin que la facturation en aval puisse séparer ces partitions en toute sécurité.
`model_source` distingue un modèle de fournisseur identifié indépendamment du
modèle exact demandé utilisé lorsque l'identité de la réponse est absente ou ambiguë.
SkillSpector n'envoie actuellement pas de contrôles de cache de prompt Anthropic, donc ses
requêtes d'analyse ne peuvent pas sélectionner les niveaux séparés d'écriture de cache de 5 minutes ou 1 heure ;
les champs de réponse spécifiques au TTL sont normalisés de manière défensive dans le compteur
agrégé d'écritures de cache.
- Voir [Inference usage telemetry](https://github.com/nvidia/skillspector/blob/HEAD/docs/INFERENCE_USAGE.md) pour le contrat complet
de provenance, de comptabilité de cache, de confidentialité, d'ingestion fail-closed et de facturation
en aval.
- La structure complète de chaque constat est définie par `Finding.to_dict()` dans [models.py](https://github.com/nvidia/skillspector/blob/HEAD/src/skillspector/models.py) ; fiez-vous aux champs ci-dessus et traitez tout champ supplémentaire comme best-effort.
Pour les outils CI/IDE, `--format sarif` émet du SARIF 2.1.0.
### Correspondance de contrôle recommandée
Lors de l'utilisation de SkillSpector comme contrôle d'installation, faites correspondre la recommandation à une action :
| `recommendation` | Action suggérée |
|------------------|------------------|
| `SAFE` | autoriser |
| `CAUTION` | inviter / avertir l'utilisateur |
| `DO_NOT_INSTALL` | bloquer |
SkillSpector calcule la plage de score et la recommandation ; le degré de sévérité du contrôle (par exemple, si `CAUTION` bloque en CI) est une décision de politique pour l'outil intégrateur.
## Développement
### Configuration
Toutes les cibles `make` supposent qu'un environnement virtuel est déjà créé et activé. Le Makefile utilise **uv** s'il est disponible, sinon **pip**.```bash
# Clone, create venv, activate, install dev dependencies
git clone https://github.com/NVIDIA/skillspector.git
cd skillspector
uv venv .venv && source .venv/bin/activate
# or: python3 -m venv .venv && source .venv/bin/activate
make install-dev
# Run tests
make test
# Run tests with coverage
make test-cov
# Run linting
make lint
# Format code
make format
SkillSpector utilise un pipeline de détection en deux étapes :
Une signature OpenSSF Model Signing valide au niveau racine (skill.oms.sig) est conservée dans l'
inventaire des composants comme type oms_signature, mais exclue de l'analyse statique et de l'analyse de contenu LLM.
Les bundles OMS contiennent nécessairement de longs champs de charge utile, de signature et de certificat encodés en base64 ;
les contrôles génériques de code obscurci pourraient sinon classer à tort ces champs comme contenu exécutable caché.
Le reconnaisseur vérifie la structure minimale OMS DSSE/in-toto ; il ne vérifie pas la signature,
la chaîne de certificats, l'entrée du journal de transparence ni l'identité du signataire. Les fichiers de signature invalides ou non reconnus
sont analysés normalement.
Le prompt LLM inclut des protections anti-jailbreak pour empêcher les compétences malveillantes de manipuler l'analyse.
SC4 utilise l'API OSV.dev pour vérifier les dépendances par rapport à la base de données Open Source Vulnerabilities complète — couvrant des dizaines de milliers d'avis de sécurité sur PyPI et npm.
L'outil nécessite un accès HTTPS sortant vers api.osv.dev pour les données de vulnérabilités en direct. Lorsque cela n'est pas disponible, les résultats sont limités à la liste de repli statique.
SkillSpector est une défense en profondeur, pas un bac à sable. Sachez ce qu'il fait et ne fait pas avant de vous y fier :
SKILLSPECTOR_PROVIDER actif. Les fichiers de signature OMS reconnus sont exclus. Utilisez --no-llm pour garder le contenu local (analyse statique uniquement).--no-llm. Il envoie les coordonnées des dépendances (pas le contenu des fichiers), ne nécessite aucune clé API et revient à une liste groupée lorsque OSV.dev est inaccessible.api.osv.dev, SC4 utilise une petite liste de repli statiqueBasé sur la recherche « Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale » (Liu et al., 2026) :
from skillspector import graph
result = graph.invoke({ "input_path": "/path/to/skill", "output_format": "json", # terminal, json, markdown, or sarif "use_llm": True, # False for static-only analysis })
print(f"Risk Score: {result['risk_score']}/100") print(f"Severity: {result['risk_severity']}") print(f"Recommendation: {result['risk_recommendation']}")
for finding in result["filtered_findings"]: print(f"[{finding['severity']}] {finding['rule_id']}: {finding['message']}")
## Licence
Apache License 2.0 - voir [LICENSE](https://github.com/nvidia/skillspector/blob/HEAD/LICENSE) pour plus de détails.
## Contribution
Les contributions sont les bienvenues ! Merci de lire nos directives de contribution et de soumettre des pull requests.
## Support
**Issues** : [GitHub Issues](https://github.com/NVIDIA/skillspector/issues)
Fournisseur (SKILLSPECTOR_PROVIDER) | Variable d'environnement d'identification | Endpoint | Modèle par défaut |
|---|
openai | OPENAI_API_KEY (+ facultatif OPENAI_BASE_URL) | api.openai.com (ou toute URL compatible OpenAI) | gpt-5.4 |
anthropic | ANTHROPIC_API_KEY | api.anthropic.com | claude-opus-4-6 |
anthropic_proxy | ANTHROPIC_PROXY_API_KEY + ANTHROPIC_PROXY_ENDPOINT_URL | N'importe quel proxy raw-predict de type Vertex | claude-sonnet-4-6 |
bedrock | AWS_PROFILE (facultatif) + AWS_REGION — SigV4 via boto3 | AWS Bedrock Runtime | us.anthropic.claude-sonnet-4-6-20250915-v1:0 |
nv_build | NVIDIA_INFERENCE_KEY | build.nvidia.com | deepseek-ai/deepseek-v4-flash |
claude_cli | (aucun — utilise l'authentification CLI locale) | binaire local claude | repli sur le runtime local de Claude, ou SKILLSPECTOR_MODEL |
codex_cli | (aucun — utilise l'authentification CLI locale) | binaire local codex | repli sur le runtime local de Codex, ou SKILLSPECTOR_MODEL |
| Variable | Description | Requis |
|---|
SKILLSPECTOR_PROVIDER | Fournisseur LLM actif : openai, anthropic, anthropic_proxy, bedrock, nv_build, claude_cli, codex_cli ou gemini_cli. Les fournisseurs hébergés utilisent les valeurs par défaut du model_registry.yaml inclus ; claude_cli et codex_cli reviennent au modèle par défaut du runtime CLI local, sauf si SKILLSPECTOR_MODEL est défini. Par défaut : nv_build. | Facultatif |
NVIDIA_INFERENCE_KEY | Clé d'authentification pour le fournisseur nv_build (build.nvidia.com). | Requis pour l'analyse LLM lorsque SKILLSPECTOR_PROVIDER=nv_build |
OPENAI_API_KEY | Clé d'authentification pour le fournisseur OpenAI (SKILLSPECTOR_PROVIDER=openai). Sert également de repli de niveau 2 dans la cascade d'identification lorsque le fournisseur actif ne renvoie aucune information d'authentification. | Requis pour l'analyse LLM lorsque SKILLSPECTOR_PROVIDER=openai |
OPENAI_BASE_URL | Remplace le point de terminaison OpenAI (par ex. pour pointer vers Ollama). | Facultatif |
SKILLSPECTOR_REASONING_EFFORT | Réglage facultatif de l'effort de raisonnement, dépendant du fournisseur et du modèle. Les valeurs non vides sont nettoyées (espaces superflus supprimés) et transmises telles quelles ; une valeur non définie ou vide préserve le comportement par défaut du fournisseur. | Facultatif |
ANTHROPIC_API_KEY | Clé d'authentification pour le fournisseur Anthropic (SKILLSPECTOR_PROVIDER=anthropic). | Requis pour l'analyse LLM lorsque SKILLSPECTOR_PROVIDER=anthropic |
ANTHROPIC_BASE_URL | Remplace le point de terminaison Anthropic natif (par défaut : https://api.anthropic.com). | Facultatif |
ANTHROPIC_PROXY_ENDPOINT_URL | URL complète du point de terminaison pour le fournisseur proxy Anthropic (raw-predict de style Vertex). | Requis lorsque SKILLSPECTOR_PROVIDER=anthropic_proxy |
ANTHROPIC_PROXY_API_KEY | Jeton Bearer pour le fournisseur proxy Anthropic. | Requis lorsque SKILLSPECTOR_PROVIDER=anthropic_proxy |
ANTHROPIC_PROXY_API_VERSION | Valeur anthropic_version envoyée dans le corps de la requête (par défaut : vertex-2023-10-16). | Facultatif |
AWS_PROFILE | Profil AWS nommé pour le fournisseur Bedrock — authentifie via SigV4 par l'intermédiaire de boto3. Lorsqu'il n'est pas défini, la chaîne d'identification boto3 standard (variables d'environnement, métadonnées d'instance, SSO, etc.) est utilisée. | Facultatif (utilisé lorsque SKILLSPECTOR_PROVIDER=bedrock) |
AWS_REGION | Région AWS pour le point de terminaison Bedrock Runtime. Par défaut : us-west-2. | Facultatif (utilisé lorsque SKILLSPECTOR_PROVIDER=bedrock) |
SKILLSPECTOR_MODEL | Remplace le modèle du fournisseur actif. Pour les fournisseurs hébergés, ceci remplace la valeur par défaut incluse dans le tableau d'analyse LLM. Pour claude_cli et codex_cli, ceci est transmis comme --model au lieu d'utiliser le repli du runtime CLI local. | Facultatif |
SKILLSPECTOR_MODEL_REGISTRY | Remplace le registre YAML inclus par fournisseur (src/skillspector/providers/<provider>/model_registry.yaml) par un chemin personnalisé. | Facultatif |
SKILLSPECTOR_LOG_LEVEL | Niveau de journalisation : DEBUG, INFO, WARNING, ERROR (par défaut : WARNING). | Facultatif |