How to Scan Skills from Git URLs or Compressed Archives with NVIDIA SkillSpector
SkillSpector accepts Git repository URLs, ZIP archives, direct file URLs, and local directories, automatically normalizing them to local paths before analysis.
NVIDIA SkillSpector is an open-source security analysis tool that evaluates AI skill bundles for potential vulnerabilities. Whether your skills reside in a remote Git repository, a downloadable ZIP archive, or a local directory, the tool's InputHandler class transparently manages the ingestion process. This article explains how to scan skills from Git URLs or compressed archives using the specific implementation details found in the NVIDIA/SkillSpector repository.
Input Detection and Normalization
The InputHandler class in src/skillspector/input_handler.py serves as the entry point for all source ingestion. It examines the supplied path, normalizes it to a local directory, and passes that directory to the LangGraph-based analysis pipeline.
Detecting Git URLs
The _is_git_url() method checks whether the supplied string matches known Git hosting patterns. It supports github.com, gitlab.com, bitbucket.org, or any URL ending with .git.
Cloning Repositories
When a Git URL is detected, the handler delegates to _clone_git(). This method performs a shallow git clone --depth 1 into a temporary directory created by _get_temp_dir(). The clone result is returned as a Path object with the source type "git" recorded for provenance tracking.
Handling ZIP Archives
For paths ending with .zip, the handler calls _extract_zip(). The archive unpacks into a temporary directory. If the ZIP contains a single top-level folder, that folder is returned directly; otherwise, the entire extraction directory is used.
Downloading File URLs
For non-Git HTTP(S) URLs, _download_file() retrieves the content via httpx. If the response indicates a ZIP file (by extension or Content-Type), the download routes through _extract_zip(). Otherwise, the file saves into a temporary directory and the temp dir path is returned.
CLI Integration and Workflow
The scan command in src/skillspector/cli.py orchestrates the entire workflow. It builds an initial graph state (_scan_state) containing the raw input_path. The graph immediately invokes InputHandler.resolve(), which returns the resolved local path fed to the rest of the analysis workflow.
Automatic Cleanup
After the LangGraph pipeline finishes execution, temporary directories are removed via InputHandler.cleanup(). The CLI indirectly triggers this through _cleanup_result(), ensuring cloned repositories and extracted archives do not persist on disk.
Practical Examples
Scan a Public Git Repository
skillspector scan https://github.com/example/my-skill
The CLI passes the URL to InputHandler. The _is_git_url() method recognizes the pattern, triggering _clone_git() to perform a shallow clone into a temporary folder before analysis begins.
Scan a Remote ZIP Archive
skillspector scan https://example.com/archives/my-skill.zip --format json --output report.json
The URL routes to _download_file(), which detects the ZIP format and delegates to _extract_zip(). The extracted contents are analyzed and results written to report.json.
Scan a Local ZIP File
skillspector scan ./downloads/my-skill.zip -f sarif -o findings.sarif
Because the path ends with .zip, InputHandler.resolve() calls _extract_zip() directly without network traffic. The archive unpacks locally and the scan proceeds.
Scan a Single Markdown File
skillspector scan ./my-skill/SKILL.md --no-llm
Single files are wrapped in a temporary folder via internal handling so downstream nodes treat them as directories. The --no-llm flag disables LLM-based analysis, running only static checks.
Summary
- InputHandler in
src/skillspector/input_handler.pyautomatically detects Git URLs, ZIP archives, and file URLs, normalizing all inputs to local directories. - Git repositories are cloned with
--depth 1for efficiency using_clone_git(). - ZIP archives extract into temporary directories via
_extract_zip(), with smart handling of single-root archives. - The
scancommand insrc/skillspector/cli.pymanages the workflow through_scan_stateand ensures cleanup via_cleanup_result(). - All temporary files are removed after analysis completes, preventing disk pollution.
Frequently Asked Questions
Does SkillSpector support private Git repositories?
Currently, the _clone_git() method performs shallow clones of public repositories. For private repositories, you must clone them manually to a local directory and scan that path instead, as the current implementation does not handle authentication tokens in the URL.
What archive formats are supported besides ZIP?
According to the source code in src/skillspector/input_handler.py, the _extract_zip() method specifically handles .zip extensions. Other formats like .tar.gz or .7z are not natively supported and should be extracted manually before scanning.
How does SkillSpector handle large ZIP files downloaded from URLs?
The _download_file() method uses httpx for streaming downloads, writing content to a temporary directory. Large files are supported as long as sufficient disk space exists in the system's temp directory, though the tool does not implement specific size limits in the current codebase.
Where are temporary files stored during analysis?
Temporary directories are created using _get_temp_dir(), which utilizes the system's standard temporary directory location. These directories are automatically removed by InputHandler.cleanup() after the LangGraph analysis pipeline completes, regardless of success or failure.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →