Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

egremap

Read-only network egress mapper for Claude / Cursor / Codex Agent Skill directories.

egremap scans a skill folder locally, extracts every URL, domain, IP address, and network call pattern, and builds a complete egress map that traces each host back to the exact file and line where it appears. It then compares discovered hosts against a declaration file (.network.example or SKILL.md frontmatter) and reports undeclared endpoints.

It never uploads your files, never makes network requests, and never executes code inside the scanned directory.

Status: open-source MVP for validation. Not a SaaS. Not a paid-demand claim.

What problem does this solve?

Agent Skills (Claude Code, Cursor, Codex) are distributed as directories containing SKILL.md, scripts, and config files. These skills routinely contact external hosts via curl, urllib, SDK calls, and hardcoded URLs. Before installing or publishing a skill, you want to know:

  • Every host the skill can contact -- not just the obvious ones in curl commands, but also SDK imports (from openai import OpenAI implies api.openai.com), bare domain references in config files, and hardcoded IP addresses.
  • Whether any host can be overridden by an environment variable (SSRF / redirect risk).
  • Whether the skill contacts hosts that are not declared in a .network.example allowlist.

egremap answers all three in one pass.

Requirements

  • Python 3.9+
  • No third-party runtime dependencies

Quick start

git clone https://github.com/Jiangki/egremap.git
cd egremap

# Demo fixtures
python3 -m egremap scan fixtures/clean-skill      # exit 0
python3 -m egremap scan fixtures/noisy-skill      # exit 1 (undeclared hosts)
python3 -m egremap scan fixtures/hostile-skill    # exit 1 (env override + hardcoded IP)

# Scan your own skill
python3 -m egremap scan /path/to/your-skill
python3 -m egremap scan /path/to/your-skill --format json
python3 -m egremap scan /path/to/your-skill --format markdown --output report.md

# List all unique hosts
python3 -m egremap list /path/to/your-skill

# Trace why a specific host was flagged
python3 -m egremap why /path/to/your-skill api.github.com

Optional install as a console script:

pip install -e .
egremap scan /path/to/your-skill

Exit codes

Code Meaning
0 No error-level findings (warnings and info allowed)
1 One or more error-level findings, or warnings when --fail-on warn
2 Invalid path / operational error

Rules

ID Severity Check
NET001 info Egress inventory: every discovered host with file/line references
NET002 warning Network call code (curl, urllib, requests, fetch, git clone, ...) without a resolvable URL in the same file
NET003 error Host not declared in .network.example or SKILL.md frontmatter
NET004 error Host URL can be overridden by an environment variable (SSRF / redirect risk)
NET005 warning Hardcoded IP address or non-HTTPS egress
NET006 info API key read in a file that also makes network calls

Declaring allowed hosts

Create a .network.example file in the root of your skill directory:

# Declare every host this skill is allowed to contact.
api.github.com
codeload.github.com

Or declare them in SKILL.md frontmatter:

---
name: my-skill
description: Does something useful.
network:
  allowed_hosts:
    - api.github.com
    - codeload.github.com
---

egremap compares declared hosts against discovered hosts. Any host not in the declaration triggers NET003.

If no declaration exists at all, NET003 is downgraded to a warning (so the first run guides you to create one rather than flooding with errors).

What egremap extracts

Extractor What it finds
URL Full http:// / https:// URLs in any text file
Bare host Domain references in config/docs (.md, .yaml, .json, .example, ...)
IP address IPv4 addresses (public and private)
Network call curl, wget, urllib, requests, httpx, aiohttp, fetch(), git clone, ssh, nc
SDK import from openai import, import anthropic, from google.generativeai import -- implies a fixed endpoint
Env override HOST="${HOST:-https://...}" patterns where a host can be redirected
API key os.getenv("XXX_API_KEY") in files that also make network calls

Safety boundary

egremap only lists directories, reads regular files, and inspects metadata. It does not:

  • import or execute files from the scanned directory
  • run shell commands from the skill
  • follow symlinks into/out of the tree
  • make network requests or verify host reachability
  • write into the scanned directory

CI example

# .github/workflows/egress-check.yml
name: Egress audit
on: [pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - run: git clone https://github.com/Jiangki/egremap.git ../egremap
      - run: python -m egremap scan ./my-skill --fail-on warn
        working-directory: ${{ github.workspace }}
        env:
          PYTHONPATH: ../egremap

Development

python3 tests/test_egremap.py
# or
PYTHONPATH=. python3 -m unittest discover -s tests -v

License

MIT - see LICENSE.

Origin

Extracted from the github-hot-tracker experiment pipeline (open-source-first idea -> pre-release MVP).

About

Read-only network egress mapper for Claude/Cursor/Codex Agent Skill directories

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages