How the resolve_input Node Normalizes Input Sources in SkillSpector
The resolve_input node converts diverse skill sources—Git repositories, ZIP archives, URLs, or local files—into a standardized local directory path while enforcing security checks against SSRF and zip-slip attacks.
The resolve_input node serves as the entry point for NVIDIA's SkillSpector analysis pipeline. Located in src/skillspector/nodes/resolve_input.py, this node transforms whatever input the user provides into a predictable local directory structure that downstream nodes can scan. It handles the complexity of remote cloning, downloading, and extraction so the rest of the graph works with a normalized skill_path.
Core Functionality and Data Flow
State-Based Input Processing
The node accepts a SkillspectorState object (defined in src/skillspector/state.py) containing an input_path field. According to the implementation in resolve_input.py lines 34-71, the function signature is:
def resolve_input(state: SkillspectorState) -> dict[str, object]:
When input_path is present, the node instantiates an InputHandler and calls its resolve() method (lines 46-50). This handler determines whether the input is a Git URL, raw file URL, ZIP archive, single file, or existing directory.
Return Value Structure
The node returns a dictionary containing two critical keys:
- **
skill_path**: The absolute path to the prepared directory ready for analysis - **
temp_dir_for_cleanup**: The temporary directory path for post-analysis cleanup, orNoneif the input was already local
As implemented in lines 50-56 of resolve_input.py, the node captures temporary directories created during resolution to ensure proper cleanup later.
Input Type Resolution and Security Architecture
Supported Source Types
The InputHandler.resolve() method in src/skillspector/input_handler.py (lines 89-119) categorizes inputs and performs specific operations:
- Git URLs: Shallow clone into a temporary directory
- Raw file URLs: Download and optionally unzip into a temp directory
- ZIP files: Safe extraction into a temporary workspace
- Single files: Copy into a temporary directory
- Directories: Resolve to absolute path without copying
Security Safeguards
Before any filesystem operations, the handler enforces three security layers:
- Allowed Hosts Whitelist: Only approved Git hosts (
github.com,gitlab.com,bitbucket.org) and download sources (raw.githubusercontent.com,huggingface.co) are permitted - SSRF Protection: The
_is_private_ipcheck (lines 61-78 ininput_handler.py) resolves hostnames and rejects private, loopback, link-local, or reserved IP addresses - Zip-Slip Mitigation: Each entry in ZIP archives is validated to stay within the extraction directory before writing (lines 38-45 in
input_handler.py)
Practical Usage Examples
Direct Node Invocation
from skillspector.state import SkillspectorState
from skillspector.nodes.resolve_input import resolve_input
# Scan a public Git repository
state = SkillspectorState({"input_path": "https://github.com/example/my-skill.git"})
result = resolve_input(state)
# Returns: {"skill_path": "/tmp/skillspector_abcdef/repo",
# "temp_dir_for_cleanup": "/tmp/skillspector_abcdef"}
Handling Local Archives
# Process a local ZIP file
state = SkillspectorState({"input_path": "/home/user/my_skill.zip"})
result = resolve_input(state)
print(result["skill_path"])
# Output: "/tmp/skillspector_12345/extracted"
Pipeline Integration
When used within the full SkillSpector graph orchestrated by src/skillspector/graph.py, the node automatically handles the first transformation step:
from skillspector.graph import run_graph
state = {"input_path": "https://huggingface.co/datasets/example_skill.zip"}
output = run_graph(state) # Internally calls resolve_input first
print(output["skill_path"])
Summary
- The
resolve_inputnode insrc/skillspector/nodes/resolve_input.pyserves as the unified entry point for all skill sources in the SkillSpector pipeline - It delegates actual resolution logic to the
InputHandlerclass insrc/skillspector/input_handler.py - The node returns a normalized
skill_pathand tracks temporary directories viatemp_dir_for_cleanupfor proper resource management - Security checks including host whitelisting, SSRF prevention, and zip-slip protection run before any filesystem modifications
- The implementation handles Git clones, URL downloads, ZIP extraction, and local directory resolution through a single consistent interface
Frequently Asked Questions
What happens if the input_path is missing or empty?
If the state lacks an input_path but contains a skill_path, the node normalizes the existing path to an absolute path using Path(skill_path).resolve() (lines 60-66 in resolve_input.py). If neither field is present, the node returns {"skill_path": None, "temp_dir_for_cleanup": None}, allowing downstream nodes like build_context to raise user-friendly error messages.
How does SkillSpector prevent malicious ZIP files from overwriting system files?
The InputHandler implements zip-slip mitigation by validating each entry path in input_handler.py lines 38-45. Before extraction, it resolves the absolute path of each ZIP entry and verifies it remains within the intended extraction directory, preventing directory traversal attacks that attempt to write to parent directories or system paths.
Can resolve_input handle private Git repositories or internal URLs?
The current implementation restricts remote sources to whitelisted hosts including github.com, gitlab.com, bitbucket.org, and specific download domains. As implemented in input_handler.py lines 61-78, the code performs SSRF checks that block private IP ranges, meaning internal or private Git repositories would require modification of the allowed hosts list or use of local directory inputs instead.
Is the temporary directory automatically cleaned up after analysis?
The resolve_input node returns the temporary directory path via temp_dir_for_cleanup (lines 50-56 in resolve_input.py), but the cleanup responsibility lies with the graph orchestrator or the calling code. The node ensures the path is available for cleanup operations but does not perform the deletion itself, allowing downstream nodes to complete their analysis before resources are released.
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 →