
SkillSpector v2.11.1
AI 에이전트 스킬용 보안 스캐너. 설치 전에 Claude Code, Codex 및 MCP 스킬에서 취약점, 악성 패턴, 보안 위험, 프롬프트 인젝션, 데이터 유출 및 공급망 위험을 탐지합니다.
SkillSpector
AI 에이전트 스킬용 보안 스캐너. 에이전트 스킬을 설치하기 전에 취약점, 악성 패턴, 보안 위험을 탐지합니다.
개요
AI 에이전트 스킬(Claude Code, Codex CLI, Gemini CLI 등에서 사용)은 암묵적 신뢰와 최소한의 검증만으로 실행됩니다. 연구에 따르면 스킬의 26.1%에 취약점이 포함되어 있고 5.2%는 악성 의도 가능성을 보입니다.
SkillSpector는 다음 질문에 답하는 데 도움을 줍니다: "이 스킬을 설치해도 안전한가?"
SkillSpector는 NVIDIA Verified Skills 파이프라인의 일부로, 게시 전에 에이전트 스킬을 스캔, 평가, 서명합니다. 통과한 스킬은 NVIDIA 스킬 카탈로그에 게시됩니다.
문서
- 설치 전 에이전트 스킬 스캔 — 호스팅 가이드: 스캔 시점, 보고서 읽는 방법, 설치 게이트 방법.
- 개발 가이드 — 아키텍처, 패키지 구조, 분석기 파이프라인 확장 방법.
- 분석 리소스 한도 — Fail-closed 번들, 파서, 중첩 아티팩트, 원장, 발견 항목 상한.
- Pi 확장 — 에이전트 세션 내부에서 스킬을 스캔할 수 있도록 SkillSpector를 Pi 도구로 설치.
기능
- 다중 형식 입력: Git 저장소, URL, zip 파일, 디렉터리 또는 단일 파일 스캔
- 17개 범주에 걸친 71가지 취약점 패턴: 프롬프트 인젝션, 데이터 유출, 권한 상승, 공급망, 과도한 에이전시, 출력 처리, 시스템 프롬프트 유출, 메모리 중독, 도구 오용, rogue agent, 거부 방지, 트리거 남용, 위험 코드(AST), taint 추적, YARA 시그니처, MCP 최소 권한, MCP 도구 중독
- 2단계 분석: 빠른 정적 분석 + 선택적 LLM 의미론적 평가
- 실시간 취약점 조회: SC4가 OSV.dev에 쿼리하여 실시간 CVE 데이터를 제공하며 자동 오프라인 폴백 지원
- 다중 출력 형식: 터미널, JSON, Markdown, SARIF 보고서
- 위험 점수: 심각도 라벨과 명확한 권장 사항이 포함된 0-100 점수
- 기준선 / 오탐 억제: glob 규칙 또는 지문 기준선을 통해 알려진 발견 항목을 수락하여 재스캔 시 새로운 문제만 표시 (문서)
빠른 시작
설치
오픈소스 소프트웨어 고지: 이 프로젝트는 추가 타사 오픈소스 소프트웨어 프로젝트를 다운로드하여 설치합니다. 사용 전에 이러한 오픈소스 프로젝트의 라이선스 조건을 검토하십시오.
먼저 가상 환경을 생성하고 활성화하십시오(모든 make 대상은 venv가 활성화된 상태를 가정합니다). uv 또는 pip를 사용하십시오. Makefile은 uv가 있으면 uv를, 그렇지 않으면 pip를 사용합니다.
uv를 사용한 빠른 설치(CLI 전용):```bash uv tool install git+https://github.com/NVIDIA/skillspector.git
Update later: uv tool update skillspector
`skillspector mcp`를 실행할 계획이라면, 설치 시 MCP 추가 기능을 함께 설치하세요:```bash
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
From source:```bash
Clone the repository
git clone https://github.com/NVIDIA/skillspector.git cd skillspector
Create and activate virtual environment
uv venv .venv && source .venv/bin/activate
or: python3 -m venv .venv && source .venv/bin/activate
Install for production use
make install
Or install with development dependencies
make install-dev
### Docker (Python 불필요)
포함된 [Dockerfile](https://github.com/nvidia/skillspector/blob/main/Dockerfile)을 로컬에서 빌드하여 Python을 설치하지 않고도 SkillSpector를 실행할 수 있습니다. 이미지는 Docker 공식 Python `3.12-slim-bookworm` 이미지를 기반으로 합니다.
**이미지 빌드:**```bash
make docker-build
# or: docker build -t skillspector .
로컬 디렉터리 스캔 — 현재 디렉터리를 /scan(컨테이너의 작업 디렉터리)에 마운트하여 수행합니다:```bash
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
**LLM 분석으로 스캔**하려면 로컬 `.env` 파일로 자격 증명을 전달하세요:```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.```bash
docker run --rm
-v "$PWD:/scan"
--env-file .env
skillspector scan ./my-skill/
Or pass credentials directly from your shell environment:```bash
docker run --rm \
-v "$PWD:/scan" \
-e SKILLSPECTOR_PROVIDER=anthropic \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
skillspector scan ./my-skill/
호스트 파일시스템에 보고서 작성은 마운트된 디렉터리에 쓰는 방식으로 수행합니다:```bash
docker run --rm
-v "$PWD:/scan"
skillspector scan ./my-skill/ --no-llm --format json --output report.json
**반복 정적 스캔을 위한 선택적 별칭(Optional alias):**```bash
alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector'
skillspector-docker scan ./my-skill/ --no-llm
기본 사용법```bash
Scan a local skill directory
skillspector scan ./my-skill/
Scan a single SKILL.md file
skillspector scan ./SKILL.md
Scan a Git repository
skillspector scan https://github.com/user/my-skill
Scan a zip file
skillspector scan ./my-skill.zip
#### 크기 제한
SkillSpector는 대용량 다운로드와 zip 폭탄의 영향을 제한하기 위해 원격 입력 및 아카이브 입력에 두 가지 독립적인 상한을 적용합니다:
- **수집당 상한**: `INGEST_MAX_BYTES` (100 MiB) — 스트리밍 URL 다운로드, zip 아카이브의 총 압축 해제 크기, Git 저장소의 클론 후 디스크 사용량에 적용됩니다.
- **Zip 항목 상한**: `INGEST_MAX_ZIP_MEMBERS` (10,000) — 단일 zip의 항목 수를 제한합니다.
파일당 1MB 분석 상한(`MAX_FILE_BYTES`)은 별도의 다운스트림 제한으로, 이미 수집된 디렉터리에서 개별 분석기가 읽어낼 내용의 범위를 제한합니다. 위의 수집 상한은 콘텐츠가 처음부터 디스크에 저장될 수 있는 양을 제한합니다. 두 수집 상한 중 하나라도 위반되면 `IngestLimitExceededError`와 함께 안전하게 차단됩니다.
### 출력 형식```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
일괄 스캔
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
다국어 감지(zh/ja/ko) 및 터미널/JSON/Markdown 출력을 지원합니다.
더 높은 동시성을 위한 LLM 스캔에서는
[`.env.example`](https://github.com/nvidia/skillspector/blob/main/contrib/batch_scan/.env.example)에 따라 여러 API 키를 구성하세요. 키가 계정 수준의 속도 제한을 공유하지 않는 한, 풀은 처리량과 복원력을 향상시킵니다.
자세한 내용은 [contrib 가이드](https://github.com/nvidia/skillspector/blob/main/contrib/batch_scan/docs)를 참조하세요.
> **LLM 지원 참고 사항:** 기본 구성은 가장 저렴한 공개 옵션으로 DeepSeek를 대상으로 합니다. DeepSeek-Chat은
> [서비스 종료 예정](https://api-docs.deepseek.com/)이며, 기여자는 로컬 모델을 테스트할 하드웨어가 없습니다. 배치 스캐너는
> 원래 OpenAI 호환 엔드포인트로 테스트되었습니다. DeepSeek의
> 구조화된 출력 미지원으로 인해 수동 JSON 파싱 패치가 필요했습니다. 더 범용적인 백엔드(Ollama, vLLM 또는 다른 제공업체)를
> 기여할 수 있다면 PR은 언제든 환영합니다.
### 오탐 억제(기준선)
알려졌거나 수용된 발견 사항을 억제하여 위험 점수가 미분류된
문제만 반영하고 재스캔 시 *새로운* 발견 사항만 표시되도록 합니다. 전체 참조는
[억제 가이드](https://github.com/nvidia/skillspector/blob/main/docs/SUPPRESSION.md)를 참조하세요.```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
기준선은 드리프트 허용 glob 규칙(규칙 ID, 파일 경로 또는 메시지 기준)을 사용할 수도 있습니다 — .skillspector-baseline.example.yaml 참조.
정확한 지문 기준선은 증거 기반입니다: 스캔 대상 소스 또는 SkillSpector 버전을 변경해도 해당 발견 항목은 다시 검토될 때까지 활성 상태로 유지됩니다.
선택된 기준선 또는 기준선 출력이 스킬 디렉터리 내부에 저장되면, SkillSpector는 해당 정확한 파일을 콘텐츠 분석에서 제외하므로 그 억제 텍스트가 발견 항목을 생성하거나 재생성된 지문에 포함될 수 없습니다; 형제 파일은 정상 스캔 범위에 유지됩니다.
LLM 분석
최상의 결과를 얻으려면 OpenAI 호환 LLM 엔드포인트를 의미론적 분석용으로 구성하세요. SKILLSPECTOR_PROVIDER로 공급자를 선택하세요; 호스팅 공급자는 번들 기본 모델을 제공하며, CLI 공급자는 SKILLSPECTOR_MODEL이 설정되지 않은 경우 로컬 런타임의 기본 모델로 대체됩니다. SkillSpector는 로컬 OpenAI 호환 서버(Ollama, vLLM, llama.cpp) 및 관리형 추론 게이트웨이에서도 작동합니다.
공급자 (SKILLSPECTOR_PROVIDER) | 자격 증명 환경 변수 | 엔드포인트 | 기본 모델 |
|---|---|---|---|
openai | OPENAI_API_KEY (+ 선택적 OPENAI_BASE_URL) | api.openai.com (또는 모든 OpenAI 호환 URL) | gpt-5.4 |
anthropic | ANTHROPIC_API_KEY | api.anthropic.com | claude-opus-4-6 |
anthropic_proxy | ANTHROPIC_PROXY_API_KEY + ANTHROPIC_PROXY_ENDPOINT_URL | 모든 Vertex 스타일 raw-predict 프록시 | claude-sonnet-4-6 |
bedrock | AWS_PROFILE (선택적) + AWS_REGION — boto3를 통한 SigV4 | 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 | (없음 — 로컬 CLI 인증 사용) | 로컬 claude 바이너리 | 로컬 Claude 런타임 대체, 또는 SKILLSPECTOR_MODEL |
codex_cli | (없음 — 로컬 CLI 인증 사용) | 로컬 codex 바이너리 | 로컬 Codex 런타임 대체, 또는 SKILLSPECTOR_MODEL |
Stock OpenAI
export SKILLSPECTOR_PROVIDER=openai export OPENAI_API_KEY=sk-... skillspector scan ./my-skill/
Anthropic
export SKILLSPECTOR_PROVIDER=anthropic export ANTHROPIC_API_KEY=sk-ant-... skillspector scan ./my-skill/
Anthropic via Vertex-style proxy (corporate gateways, GCP Vertex AI)
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/
AWS Bedrock (Claude via SigV4)
export SKILLSPECTOR_PROVIDER=bedrock
Optional: select an AWS named profile. When unset, the standard
boto3 credential chain (env vars, instance metadata, SSO, etc.) resolves.
export AWS_PROFILE=my-profile
export AWS_REGION=us-west-2 # default if unset
Default model: us.anthropic.claude-sonnet-4-6-20250915-v1:0
Override with any Bedrock model ID, cross-region inference-profile
ID, or your own application-inference-profile ARN:
export SKILLSPECTOR_MODEL=us.anthropic.claude-opus-4-6-20250915-v1:0
skillspector scan ./my-skill/
NVIDIA build.nvidia.com
export SKILLSPECTOR_PROVIDER=nv_build export NVIDIA_INFERENCE_KEY=nvapi-... skillspector scan ./my-skill/
Local Claude CLI — no API key; uses your existing claude auth login session
Requires: claude CLI installed and authenticated (claude auth login)
export SKILLSPECTOR_PROVIDER=claude_cli
Uses the local Claude CLI runtime fallback unless SKILLSPECTOR_MODEL is set.
export SKILLSPECTOR_MODEL=claude-sonnet-4-6
skillspector scan ./my-skill/
Local Codex CLI — no API key; uses your existing codex login session
Requires: codex CLI installed and authenticated
export SKILLSPECTOR_PROVIDER=codex_cli skillspector scan ./my-skill/
Local Ollama or any OpenAI-compatible endpoint
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/
Override the provider's default model
export SKILLSPECTOR_MODEL=gpt-5.2 skillspector scan ./my-skill/
Skip LLM analysis (faster, static analysis only)
skillspector scan ./my-skill/ --no-llm
### MCP 서버
SkillSpector를 [Model Context Protocol](https://modelcontextprotocol.io)
서버로 실행하여 MCP를 지원하는 모든 에이전트(Claude Code, Codex CLI, Gemini CLI) 또는 원격
런타임이 스캔을 도구로 호출하고 **결과에 따라 스킬/MCP 설치를 게이트**할 수 있게 합니다.
즉, SkillSpector를 별도의 감사 단계가 아닌 런타임 가드레일로 전환합니다.
`skillspector mcp`는 `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
stdio transport는 로컬 CLI 에이전트를 위한 현재 FastMCP 경로이며, issue #199에서 보고된 initialize 중단 문제는 여전히 해당 경로에 적용됩니다.
서버는 단일 도구를 노출합니다:
scan_skill(target, use_llm=true, output_format="json")— Git URL, 파일 URL,.zip,.md파일 또는 디렉터리를 스캔하고 구조화된 판정을 반환합니다:risk_score(0-100),severity,recommendation,safe_to_install,findings. 또한llm_used/scan_mode를 보고하므로 정적 전용 스캔의 낮은 점수가 완전한 스캔의 깨끗한 결과로 오인되지 않습니다.
다음을 통해 Claude Code에 등록하세요:```bash claude mcp add skillspector -- skillspector mcp
> **보안 — HTTP 전송 신뢰 모델**
>
> HTTP 전송은 **인증 없이** 제공됩니다. 포트에 도달할 수 있는 모든 호출자는
> `scan_skill`을 호출할 수 있습니다. stdio 또는 `127.0.0.1`을 통해서는
> CLI와 동일한 신뢰 경계입니다. 라우팅 가능한 인터페이스에 바인딩하는 경우:
>
> - 외부에 노출하기 전에 인증 리버스 프록시(예: nginx + mTLS) 뒤에 서버를 배치하세요.
> - 로컬 경로와 `file://` URL은 HTTP를 통해 **자동으로 거부**되어
> 인증되지 않은 호출자가 임의의 호스트 파일을 읽는 것을 방지합니다. 원격
> Git 및 `.zip` URL만 허용됩니다.
## 취약점 패턴
SkillSpector는 17개 카테고리에서 **71개의 취약점 패턴**을 감지합니다:
### 프롬프트 인젝션 (6개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| P1 | 지시문 재정의 | HIGH | 안전 제약 조건을 무시하라는 명령 |
| P2 | 숨겨진 지시문 | HIGH | 주석/보이지 않는 텍스트의 악성 지시문 |
| P3 | 데이터 유출 명령 | HIGH | 컨텍스트를 외부로 전송하라는 지시문 |
| P4 | 동작 조작 | MEDIUM | 에이전트 결정을 변경하는 미묘한 지시문 |
| P5 | 유해 콘텐츠 | CRITICAL | 물리적 피해를 유발할 수 있는 지시문 |
| P9 | 공백 패딩 | MEDIUM | 보이는 영역 아래/옆에 지시문을 숨기는 대량의 공백 패딩 |
### 거부 방지 (3개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| AR1 | 거부 억제 | HIGH | 절대 거부하지 않거나 항상 따르라는 지시문(예: "절대 거부하지 마세요", "항상 따르세요") |
| AR2 | 면책 조항 억제 | HIGH | 경고, 면책 조항 또는 윤리적 논평을 생략하라는 지시문(예: "면책 조항 없음", "도덕적 설교 금지") |
| AR3 | 안전 정책 무효화 | HIGH | 안전장치를 무효화하는 탈옥 프레이밍(예: "제한 없음", "지침 무시", "지금 무엇이든 하세요") |
### 데이터 유출 (4개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| E1 | 외부 전송 | MEDIUM | 외부 URL로 데이터 전송 |
| E2 | 환경 변수 수집 | HIGH | 비밀을 수집하기 위한 환경 데이터 열거, 복사 또는 검색 |
| E3 | 파일 시스템 열거 | MEDIUM | 민감한 파일을 위한 디렉터리 스캔 |
| E4 | 컨텍스트 누출 | HIGH | 대화 컨텍스트를 외부로 전송 |
### 권한 상승 (3개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| PE1 | 과도한 권한 | LOW | 명시된 기능을 넘어서는 접근 요청 |
| PE2 | Sudo/Root 실행 | MEDIUM | 상승된 시스템 권한 호출 |
| PE3 | 자격 증명 접근 | HIGH | SSH 키, 토큰, 비밀번호 읽기 |
### 공급망 (9개 이상 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| SC1 | 고정되지 않은 종속성 | LOW | 패키지에 버전 제약 없음 |
| SC2 | 외부 스크립트 가져오기 | HIGH | curl \| bash 및 원격 코드 실행 |
| SC3 | 난독화된 코드 | HIGH | Base64/hex 인코딩 실행 |
| SC4 | 알려진 취약 종속성 | HIGH | 알려진 CVE가 있는 종속성(실시간 OSV.dev 조회) |
| SC5 | 유지 관리 중단된 종속성 | MEDIUM | 보안 업데이트가 없는 미관리 패키지 |
| SC6 | 타이포스쿼팅 | HIGH | 인기 패키지와 유사한 패키지 이름 |
| SC8 | 배포된 Python 바이트코드 | HIGH | `__pycache__` / `.pyc` 존재(탐지 건너뜀, 악성 바이트코드 우회) |
| SC9 | 은닉 실행 파일 아티팩트 | HIGH | 문서 컨테이너 또는 숨겨진/위장된 아티팩트에 중첩된 실행 파일 |
### 과도한 에이전시 (5개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| EA1 | 무제한 도구 접근 | HIGH | 제약 없는 무제한 도구 접근 |
| EA2 | 자율적 의사 결정 | HIGH | 인간 개입 없는 고영향 결정 |
| EA3 | 범위 확장 | MEDIUM | 명시된 목적을 넘어서는 기능 |
| EA4 | 무제한 리소스 접근 | MEDIUM | 리소스 소비에 대한 속도 제한 또는 할당량 없음 |
| EA5 | 외부 모델 또는 공급자 선택 | MEDIUM/HIGH | 청구 계정을 전환할 수 있는 모델/공급자 고정 또는 코딩-CLI 셸 아웃 |
### 출력 처리 (3개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| OH1 | 검증되지 않은 출력 인젝션 | HIGH | 정화 없이 사용되는 모델 출력 |
| OH2 | 교차 컨텍스트 출력 | MEDIUM | 검증 없이 신뢰 경계를 넘어 흐르는 출력 |
| OH3 | 무제한 출력 | MEDIUM | 출력 크기 또는 생성 속도에 대한 제한 없음 |
### 시스템 프롬프트 누출 (3개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| P6 | 직접 누출 | HIGH | 시스템 프롬프트 또는 내부 규칙을 노출하는 지시문 |
| P7 | 간접 추출 | MEDIUM | 재구성, 번역 또는 사이드 채널을 통한 추출 |
| P8 | 도구 기반 유출 | HIGH | 파일 쓰기 또는 네트워크 요청을 통해 유출되는 시스템 프롬프트 |
### 메모리 오염 (3개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| MP1 | 지속적 컨텍스트 인젝션 | HIGH | 상호작용 간 지속되도록 설계된 콘텐츠 |
| MP2 | 컨텍스트 창 채우기 | MEDIUM | 안전 제약 조건을 대체하는 채우기 콘텐츠 |
| MP3 | 메모리 조작 | HIGH | 에이전트 메모리 또는 저장된 상태 변조 |
### 도구 오용 (3개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| TM1 | 도구 매개변수 남용 | HIGH | 의도하지 않은 동작을 위한 조작된 매개변수(shell=True, --force) |
| TM2 | 체이닝 남용 | HIGH | 개별 안전 검사를 우회하는 도구 체인 |
| TM3 | 안전하지 않은 기본값 | MEDIUM | 과도하게 허용적인 기본값(TLS 비활성화, 인증 없음) |
### 불량 에이전트 (2개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| RA1 | 자체 수정 | CRITICAL | 런타임 시 자체 코드 또는 구성 수정 |
| RA2 | 세션 지속성 | HIGH | cron 작업 또는 시작 스크립트를 통한 무단 지속성 |
### 트리거 남용 (3개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| TR1 | 과도하게 광범위한 트리거 | MEDIUM | 일반적인 단어와 일치하는 트리거 패턴 |
| TR2 | 섀도우 명령 트리거 | HIGH | 내장 명령 또는 다른 스킬을 가리는 트리거 |
| TR3 | 키워드 미끼 트리거 | MEDIUM | 활성화를 극대화하도록 설계된 일반 트리거 |
### 동작 AST (9개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| AST1 | exec() 호출 | CRITICAL | 임의 코드 실행을 가능하게 하는 직접 exec() |
| AST2 | eval() 호출 | HIGH | 임의 표현식을 평가하는 직접 eval() |
| AST3 | 동적 가져오기 | HIGH | 런타임 시 임의 모듈을 로드하는 \_\_import\_\_() |
| AST4 | subprocess 호출 | HIGH | subprocess를 통한 외부 명령 실행 |
| AST5 | os.system / exec 계열 | HIGH | os 모듈을 통한 셸 명령 |
| AST6 | compile() 호출 | MEDIUM | 문자열에서 코드 객체 생성 |
| AST7 | 동적 getattr() | MEDIUM | 비리터럴 이름으로 임의 속성 접근 |
| AST8 | 위험한 실행 체인 | CRITICAL | 동적 소스(네트워크, 인코딩된 데이터)와 결합된 exec/eval |
| AST9 | 반사적 getattr() 싱크 | HIGH | AST1/AST5를 우회하는 `getattr(os,'system')` / `getattr(builtins,'exec')`를 통한 반사적 exec |
### 오염 추적 (5개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| TT1 | 직접 오염 흐름 | HIGH | 데이터가 정화 없이 소스에서 싱크로 직접 흐름 |
| TT2 | 변수 매개 오염 흐름 | MEDIUM | 데이터가 중간 변수를 통해 소스에서 싱크로 흐름 |
| TT3 | 자격 증명 유출 체인 | CRITICAL | 자격 증명(환경 변수, 비밀)이 네트워크 출력 싱크로 흐름 |
| TT4 | 파일 읽기에서 네트워크 유출 | HIGH | 파일 내용이 네트워크 출력 싱크로 흐름 |
| TT5 | 외부 입력에서 코드 실행 | CRITICAL | 네트워크 또는 사용자 입력이 exec/eval/subprocess 싱크로 흐름 |
### YARA 시그니처 (4개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| YR1 | 악성코드 일치 | CRITICAL | 알려진 악성코드 시그니처에 대한 YARA 규칙 일치 |
| YR2 | 웹셸 일치 | CRITICAL | 웹셸 패턴에 대한 YARA 규칙 일치 |
| YR3 | 암호화폐 채굴기 일치 | HIGH | 암호화폐 채굴 지표에 대한 YARA 규칙 일치 |
| YR4 | 해킹 도구 / 익스플로잇 일치 | HIGH | 해킹 도구 또는 익스플로잇 코드에 대한 YARA 규칙 일치 |
### MCP 최소 권한 (4개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| LP1 | 미선언 기능 | HIGH | 선언된 권한에 나열되지 않은 기능을 사용하는 코드 |
| LP2 | 와일드카드 권한 | MEDIUM | 권한 목록에 와일드카드(\*, all, full, any) 포함 |
| LP3 | 누락된 권한 선언 | MEDIUM | 권한 필드가 없지만 코드에 감지 가능한 기능이 있음 |
| LP4 | 과다 선언 권한 | LOW | 권한이 선언되었지만 해당 코드 기능이 발견되지 않음 |
### MCP 도구 오염 (4개 패턴)
| ID | 패턴 | 심각도 | 설명 |
|----|---------|----------|-------------|
| TP1 | 숨겨진 지시문 | HIGH | 메타데이터의 숨겨진 지시문(HTML 주석, 제로 너비 문자, base64, 데이터 URI) |
| TP2 | 유니코드 사기 | HIGH | 도구 메타데이터의 호모글리프, RTL 오버라이드, 혼합 스크립트 식별자 |
| TP3 | 매개변수 설명 인젝션 | MEDIUM | 매개변수 정의의 인젝션 패턴(재정의, 시스템 토큰, 악성 기본값) |
| TP4 | 설명-동작 불일치 | MEDIUM | 선언된 도구 설명이 실제 코드 동작과 일치하지 않음(LLM 기반) |
감지된 모든 패턴은 위 표에 나열되어 있습니다.
## 위험 점수
### 점수 계산
- **CRITICAL 문제**: +50점
- **HIGH 문제**: +25점
- **MEDIUM 문제**: +10점
- **LOW 문제**: +5점
- **실행 가능한 스크립트**: 1.3배 승수
### 심각도 수준
| 점수 | 심각도 | 권장 사항 |
|-------|----------|----------------|
| 0-20 | LOW | 안전 |
| 21-50 | MEDIUM | 주의 |
| 51-80 | HIGH | 설치 금지 |
| 81-100 | CRITICAL | 설치 금지 |
## 출력 예시
### 터미널 출력```
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.
구성
환경 변수
| 변수 | 설명 | 필수 여부 |
|---|---|---|
SKILLSPECTOR_PROVIDER | 활성 LLM 공급자: openai, anthropic, anthropic_proxy, bedrock, nv_build, claude_cli, codex_cli 또는 gemini_cli. 호스팅 공급자는 번들된 model_registry.yaml 기본값을 사용합니다. claude_cli 및 codex_cli는 SKILLSPECTOR_MODEL이 설정되지 않은 경우 로컬 CLI 런타임의 기본 모델로 대체됩니다. 기본값은 nv_build입니다. | 선택 사항 |
NVIDIA_INFERENCE_KEY | nv_build 공급자(build.nvidia.com)용 자격 증명. | SKILLSPECTOR_PROVIDER=nv_build일 때 LLM 분석에 필요 |
OPENAI_API_KEY | OpenAI 공급자(SKILLSPECTOR_PROVIDER=openai)용 자격 증명. 활성 공급자가 자격 증명을 반환하지 않을 때 자격 증명 폴백 체인의 2단계 대체 수단으로도 사용됩니다. | SKILLSPECTOR_PROVIDER=openai일 때 LLM 분석에 필요 |
OPENAI_BASE_URL | OpenAI 엔드포인트 재정의(예: Ollama를 가리키도록). | 선택 사항 |
SKILLSPECTOR_REASONING_EFFORT | 선택적인 공급자 및 모델 종속 추론 노력 설정. 비어 있지 않은 값은 트리밍되어 변경 없이 전달됩니다. 설정되지 않거나 비어 있으면 공급자 기본 동작이 유지됩니다. | 선택 사항 |
SKILLSPECTOR_OUTPUT_LANGUAGE | 사람이 읽을 수 있는 LLM 결과 텍스트(메시지, 설명, 수정 사항 등)용 짧은 한 줄 언어 레이블(문자, 숫자, 공백, _ 또는 -, 최대 64자). 규칙 ID, 심각도 값, 경로, 코드 및 기타 기계 판독 가능 값은 변경되지 않습니다. 설정되지 않았거나, 비어 있거나, 잘못된 값은 기본 출력 언어를 유지합니다. | 선택 사항 |
SKILLSPECTOR_TEMPERATURE | 호스팅 공급자용 선택적 샘플링 온도 0~1. 설정되지 않거나 비어 있으면 공급자 기본값이 유지됩니다. 낮은 값은 실행 간 변동을 줄일 수 있지만 동일한 출력을 보장하지는 않습니다. | 선택 사항 |
SKILLSPECTOR_SEED | OpenAI 호환 및 Azure OpenAI 공급자용 선택적 정수 샘플링 시드. 다른 호스팅 공급자 및 CLI 공급자는 이를 수신하지 않습니다. 공급자 지원은 모델에 따라 달라집니다. | 선택 사항 |
ANTHROPIC_API_KEY | Anthropic 공급자(SKILLSPECTOR_PROVIDER=anthropic)용 자격 증명. | SKILLSPECTOR_PROVIDER=anthropic일 때 LLM 분석에 필요 |
ANTHROPIC_BASE_URL | 기본 Anthropic 엔드포인트 재정의(기본값: https://api.anthropic.com). | 선택 사항 |
ANTHROPIC_PROXY_ENDPOINT_URL | Anthropic 프록시 공급자(Vertex 스타일 raw-predict)용 전체 엔드포인트 URL. | SKILLSPECTOR_PROVIDER=anthropic_proxy일 때 필요 |
ANTHROPIC_PROXY_API_KEY | Anthropic 프록시 공급자용 Bearer 토큰. | SKILLSPECTOR_PROVIDER=anthropic_proxy일 때 필요 |
ANTHROPIC_PROXY_API_VERSION | 요청 본문에 전송되는 anthropic_version 값(기본값: vertex-2023-10-16). | 선택 사항 |
AWS_PROFILE | Bedrock 공급자용 명명된 AWS 프로필 — boto3를 통해 SigV4로 인증합니다. 설정되지 않은 경우 표준 boto3 자격 증명 체인(환경 변수, 인스턴스 메타데이터, SSO 등)이 해석합니다. | 선택 사항(SKILLSPECTOR_PROVIDER=bedrock일 때 사용) |
AWS_REGION | Bedrock Runtime 엔드포인트용 AWS 리전. 기본값은 us-west-2입니다. | 선택 사항(SKILLSPECTOR_PROVIDER=bedrock일 때 사용) |
SKILLSPECTOR_MODEL | 활성 공급자 모델 재정의. 호스팅 공급자의 경우 LLM 분석 표의 번들 기본값을 대체합니다. claude_cli 및 codex_cli의 경우 로컬 CLI 런타임 대체를 사용하는 대신 --model로 전달됩니다. | 선택 사항 |
SKILLSPECTOR_MODEL_REGISTRY | 번들된 공급자별 YAML 레지스트리(src/skillspector/providers/<provider>/model_registry.yaml)를 사용자 지정 경로로 재정의. | 선택 사항 |
SKILLSPECTOR_LOG_LEVEL | 로그 수준: DEBUG, INFO, WARNING, ERROR(기본값: WARNING). | 선택 사항 |
CLI 공급자(
claude_cli,codex_cli): API 키가 필요하지 않습니다. 인증은 에이전트 CLI 자체의 로그인 세션(claude auth login/codex login)에 의해 완전히 관리됩니다. SkillSpector는 이러한 공급자가 활성화된 경우 API 키를 읽거나 전달하지 않습니다. 하위 프로세스는 강화된 샌드박스에서 실행됩니다: 도구 비활성화, MCP 없음, 읽기 전용 샌드박스 모드(codex), 신뢰할 수 없는 스킬 콘텐츠는 stdin을 통해서만 전달됩니다.
CLI 옵션```bash
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
Generate a baseline of all current findings (see docs/SUPPRESSION.md)
skillspector baseline [-o FILE] [--no-llm] [--reason TEXT]
## SkillSpector 통합
SkillSpector는 다른 도구(CI 파이프라인, 설치 게이트, 편집기 통합)에 의해 구동되도록 설계되었습니다. 종료 코드와 JSON 출력은 안정적인 계약입니다.
### 종료 코드
`skillspector scan`은 다음으로 종료됩니다:
| 코드 | 의미 |
|------|---------|
| `0` | 스캔 완료, `risk_score` ≤ 50 (권장 사항 `SAFE` 또는 `CAUTION`) |
| `1` | 스캔 완료, `risk_score` > 50 (권장 사항 `DO_NOT_INSTALL`) |
| `2` | 오류 (잘못된 입력, 읽을 수 없는 소스, 내부 실패) |
> 종료 코드는 `SAFE`와 `CAUTION`을 `0`으로 축소합니다. 이들을 다르게 처리하려면(예: `CAUTION`에서는 *경고*, `DO_NOT_INSTALL`에서는 *차단*), 종료 코드에 의존하지 말고 JSON 출력에서 `recommendation` 필드를 읽으십시오.
### 기계 판독 가능 출력
`--format json`은 JSON 보고서를 생성합니다. `--output`/`-o`가 없으면 stdout에 기록됩니다:```bash
skillspector scan ./my-skill/ --format json
The top-level shape is (this example shows a full LLM-backed scan; with --no-llm, metadata.llm_requested is 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`, 심각도에서 매핑됨: `LOW → SAFE`, `MEDIUM → CAUTION`, `HIGH`/`CRITICAL → DO_NOT_INSTALL`.
- `metadata.llm_error`는 LLM 분석이 요청되었지만 사용할 수 없을 때만 나타납니다.
- `metadata.inference_usage`는 공급자가 토큰 카운터를 노출할 때 LLM 응답당 정리된 레코드 하나를 포함합니다. 사용량을 사용할 수 없으면 빈 목록입니다. SkillSpector는 누락된 토큰을 추정하지 않습니다. 프롬프트 합계는 캐시 읽기 및 쓰기를 포함하므로 다운스트림 가격 책정이 해당 파티션을 안전하게 분리할 수 있습니다.
`model_source`는 독립적으로 식별된 공급자 모델과 응답 ID가 없거나 모호할 때 사용된 정확한 요청 모델을 구분합니다.
SkillSpector는 현재 Anthropic 프롬프트 캐시 제어를 보내지 않으므로 스캔 요청이 별도의 5분 또는 1시간 캐시 쓰기 계층을 선택할 수 없습니다. TTL별 응답 필드는 방어적으로 집계 캐시 쓰기 카운터로 정규화됩니다.
- 전체 출처, 캐시 회계, 개인정보 보호, 실패 시 폐쇄 수집, 다운스트림 가격 책정 계약에 대한 자세한 내용은 [추론 사용량 원격 측정](https://github.com/nvidia/skillspector/blob/main/docs/INFERENCE_USAGE.md)을 참조하세요.
- 문제별 전체 형태는 [models.py](https://github.com/nvidia/skillspector/blob/main/src/skillspector/models.py)의 `Finding.to_dict()`로 정의됩니다. 위 필드에 의존하고 추가 필드는 최선의 노력으로 처리하세요.
CI/IDE 도구의 경우 `--format sarif`는 SARIF 2.1.0을 출력합니다.
### 권장 게이트 매핑
SkillSpector를 설치 게이트로 사용할 때 권장 사항을 작업에 매핑하세요:
| `recommendation` | 제안된 작업 |
|------------------|------------------|
| `SAFE` | 허용 |
| `CAUTION` | 사용자에게 프롬프트/경고 |
| `DO_NOT_INSTALL` | 차단 |
SkillSpector는 점수 대역과 권장 사항을 계산합니다. 게이트가 얼마나 엄격한지(예: CI에서 `CAUTION`이 차단하는지 여부)는 통합 도구의 정책 결정입니다.
## 개발
### 설정
모든 `make` 대상은 가상 환경이 이미 생성되고 활성화되었다고 가정합니다. Makefile은 사용 가능한 경우 **uv**를 사용하고, 그렇지 않으면 **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는 2단계 탐지 파이프라인을 사용합니다:
1단계: 정적 분석
- 11개의 정적 분석기를 대상으로 한 빠른 정규식 기반 패턴 매칭
- 위험한 호출(exec, eval, subprocess 등)을 탐지하는 AST 기반 동작 분석
- OSV.dev를 통한 의존성의 알려진 CVE 실시간 취약점 조회
- 스킬 내 분석 대상 파일 전체 스캔
- 높은 재현율(대부분의 문제 포착)
- 중간 수준의 정밀도(일부 오탐 포함)
유효한 루트 수준 OpenSSF Model Signing 서명(skill.oms.sig)은 컴포넌트 인벤토리에 oms_signature 유형으로 보존되지만, 정적 및 LLM 콘텐츠 분석에서는 제외됩니다. OMS 번들에는 필연적으로 긴 base64 인코딩 페이로드, 서명 및 인증서 필드가 포함됩니다. 일반적인 난독화 코드 검사는 이러한 필드를 숨겨진 실행 콘텐츠로 잘못 분류할 수 있습니다. 인식기는 최소한의 OMS DSSE/in-toto 구조를 확인하며, 서명, 인증서 체인, 투명성 로그 항목 또는 서명자 신원은 검증하지 않습니다. 유효하지 않거나 인식되지 않는 서명 파일은 정상적으로 스캔됩니다.
2단계: LLM 의미 분석(선택 사항)
- 컨텍스트와 의도를 평가
- 오탐 필터링
- 사람이 읽을 수 있는 설명 제공
- 정밀도를 약 87%로 향상
LLM 프롬프트에는 악성 스킬이 분석을 조작하는 것을 방지하기 위한 안티-탈옥 보호 기능이 포함되어 있습니다.
실시간 취약점 조회(SC4)
SC4는 OSV.dev API를 사용하여 전체 오픈소스 취약점 데이터베이스(PyPI 및 npm의 수만 개 권고사항 포함)에 대해 의존성을 확인합니다.
- API 키 불필요 — OSV.dev는 무료이며 인증이 필요 없습니다.
- 일괄 쿼리 — 모든 의존성이 단일 HTTP 호출로 확인됩니다.
- 자동 폴백 — OSV.dev에 연결할 수 없는 경우(에어갭/오프라인), 소규모 내장 폴백 목록이 사용됩니다.
- 캐싱 — 세션 중 중복 API 호출을 방지하기 위해 결과가 메모리에 1시간 동안 캐시됩니다.
이 도구는 실시간 취약점 데이터를 위해 api.osv.dev에 대한 아웃바운드 HTTPS 접근이 필요합니다. 이를 사용할 수 없는 경우, 발견 결과는 정적 폴백 목록으로 제한됩니다.
신뢰 모델 및 데이터 유출
SkillSpector는 심층 방어(Defense-in-depth)이지 샌드박스가 아닙니다. 이 도구에 의존하기 전에 무엇을 하고 무엇을 하지 않는지 파악하세요:
- 스캔된 스킬을 절대 실행하지 않습니다. 모든 분석은 정적(정규식, Python AST, YARA)이며 선택적 LLM 평가는 파일 콘텐츠에 대해서만 수행됩니다 — 스킬의 코드는 절대 실행되지 않습니다.
- LLM 분석은 분석 대상 파일 콘텐츠를 구성된 공급자에게 전송합니다. LLM 분석이 활성화된 경우(기본값), 파일 콘텐츠가 활성
SKILLSPECTOR_PROVIDER엔드포인트로 전송됩니다. 인식된 OMS 서명 파일은 제외됩니다.--no-llm을 사용하여 콘텐츠를 로컬에 유지하세요(정적 분석만). - SC4는 의존성 이름을 OSV.dev로 전송합니다. 공급망 검사는 스킬이 선언한 패키지 이름과 버전으로 OSV.dev에 쿼리하여 알려진 CVE를 조회합니다. 이는 검사의 핵심 기능이며
--no-llm이 있어도 실행됩니다. 의존성 좌표(파일 콘텐츠 아님)를 전송하며, API 키가 필요 없고, OSV.dev에 연결할 수 없을 때 번들 목록으로 폴백합니다. - 호스트를 샌드박싱하지 않습니다. SkillSpector는 스킬을 설치하기 전에 위험한 패턴을 표시합니다. 설치하기로 선택한 스킬을 격리하거나 차단하지 않습니다.
제한 사항
- 비영어 콘텐츠: 다른 언어의 패턴을 놓칠 수 있음
- 이미지 기반 공격: 이미지 내 텍스트를 분석할 수 없음
- 암호화/바이너리 코드: 컴파일되거나 암호화된 콘텐츠를 분석할 수 없음
- 런타임 동작: 정적 분석만 수행, 동적 실행 없음
- 오프라인 SC4:
api.osv.dev에 대한 네트워크 접근이 없으면 SC4는 소규모 정적 폴백 목록을 사용
연구 배경
"Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale"(Liu 외, 2026) 연구를 기반으로 함:
- 데이터셋: 주요 마켓플레이스의 42,447개 스킬
- 취약 비율: 26.1%가 최소 하나 이상의 취약점 포함
- 고심각도: 5.2%가 악성 의도 가능성 표시
- 주요 발견: 실행 가능한 스크립트가 있는 스킬은 취약할 가능성이 2.12배 높음
Python API 통합```python
from skillspector import graph
Invoke the LangGraph workflow
result = graph.invoke({ "input_path": "/path/to/skill", "output_format": "json", # terminal, json, markdown, or sarif "use_llm": True, # False for static-only analysis })
Access results
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']}")
## 라이선스
Apache License 2.0 - 자세한 내용은 [LICENSE](https://github.com/nvidia/skillspector/blob/main/LICENSE)를 참조하세요.
## 기여
기여를 환영합니다! 기여 지침을 읽고 풀 리퀘스트를 제출해 주세요.
## 지원
- **이슈**: [GitHub Issues](https://github.com/NVIDIA/skillspector/issues)