SIGIT: a modular Python OSINT toolkit
Simple Information Gathering Toolkit
At a glance
- What is it?
- SIGIT is a Python open source intelligence framework that gathers public footprint data across domain, email, network, security and social services, with every tool exposed as a generated CLI subcommand. It suits scripted reconnaissance of systems you are authorised to assess, and it says nothing about the legal boundary around scanning third party infrastructure.
- Who is it for?
- Adopt SIGIT when you want one scriptable command per reconnaissance task, with typed parameters and JSON output you can pipe into other tools, and skip it when you need deeper control than a single scan per service provides, since each tool does one job with fixed parameters.
- Can I use it commercially?
- Yes. Unlicense is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 19 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One framework, fifteen reconnaissance services
SIGIT stands for Simple Information Gathering Toolkit and is described as a modular, high-performance open source intelligence framework in modern Python. The service catalogue divides it into six categories, and each service is a small object with a single job.
The domain category holds DNSRecon, which resolves A, MX, NS and TXT records over Google DNS over HTTPS, SubdomainScan, which enumerates common subdomain prefixes with concurrent DNS and HTTP requests, and WHOISLookup, which retrieves registration data through the system whois utility. The email category holds EmailRecon, which checks whether an address is registered across a large set of platforms, and MailFinder, which audits known registrations or generates permutations to probe a target.
The network category has IPLocation for geolocation, ASN, ISP and coordinates, PortScanner, a non-blocking asynchronous TCP scanner over configurable ports, and ReverseIP for discovering virtual hosts sharing an IP. The recon category adds PhoneInfo, which validates international numbering formats, country and carrier, and TechDetector, which inspects response headers and signatures for CMS, frameworks and CDNs.
The security category covers BreachChecker, which checks accounts against indexed public breaches, HeaderAnalyzer for HSTS, CSP and X-Frame-Options, and SSLChecker for certificate metadata and validity windows. The social category holds GitHubRecon for public user metrics and recent repository activity, and UserRecon for username availability across more than a hundred platforms.
The intended user is someone running structured collection against their own or an authorised asset, in a script or from a phone terminal, which is why the repository carries the termux topic and the name of the organisation behind it.
Pydantic schemas generate the CLI, the prompts and the output
The interesting engineering decision in SIGIT is that a service declares its parameters once, as a Pydantic model, and everything else follows from that declaration. The architecture section of the README lists core/base.py as holding the BaseService contract along with the Category, RenderType and ServiceResult types, and core/config.py as the central environment settings handled by pydantic-settings.
The CLI layer reads those schemas. cli/parser.py is described as a dynamic argparse generator derived from the Pydantic schemas, which is why every service gets a subcommand without anyone writing a parser by hand. cli/prompt.py is a schema-driven interactive prompt collector, so the terminal menu asks for exactly the fields the service needs and validates them as you type.
Output is the other half of that contract. cli/display.py handles table, panel and file output rendering, and the universal output rendering claim covers structured tables, key-value panels, lists, raw text and automated JSON export. The RenderType and ServiceResult types in the base module are what make that switchable, so a service returns a result and the rendering layer decides how it looks.
For a user, the visible effect is that every tool has the same shape. The same flags mean the same thing across fifteen services, and the JSON export path is identical everywhere, which is what makes the output pipeable.
Adding a service is a matter of dropping in a package
The registry in core/registry.py is described as a recursive package auto-discovery engine, and that is the mechanism behind the modularity claim. Services live in isolated tool packages under sigit/services/, partitioned by category, so the framework finds them by walking the package tree rather than by consulting a hardcoded list.
The extension procedure in the README matches that design. You create a dedicated tool directory under the appropriate category, for example sigit/services/network/my_scanner/, and continue with the remaining steps described in the guide. Because discovery is recursive, a new directory becomes available to the registry, and because the CLI generator works from the service schema, the new tool also arrives with its own subcommand and help text.
The service packages are listed in the tree with their module names, which shows how the naming works: domain/ contains dns_recon/, subdomain_scanner/ and whois/, email/ contains email_recon/ and mail_finder/, network/ contains ip_location/, port_scanner/ and reverse_ip/, recon/ contains phone_info/ and tech_detector/, security/ contains breach_checker/, header_analyzer/ and ssl_checker/, and social/ contains github_recon/ and user_recon/.
The practical caveat is that the discovery convention is a convention. A tool package has to follow the expected layout and expose a BaseService implementation, and the README's own guidance to check existing services and follow their pattern reflects how much of the contract is implicit.
Browser TLS impersonation through curl_cffi
Networking is handled by a shared AsyncSession in core/http.py, built on curl_cffi, with concurrency control applied on top. The README describes this as stealth asynchronous HTTP transport via browser TLS impersonation, and the capability list names browser fingerprint impersonation using JA3 and JA4 with bounded concurrency controls.
That is the difference between this toolkit and a requests-based one. A TLS fingerprint is the shape of the client's handshake, and many sites filter on it, so presenting a browser-like fingerprint reduces the number of requests that get challenged outright. The impersonation target is configurable, and the default shown in the configuration section is a specific Chrome build:
SIGIT_IMPERSONATE=chrome124Concurrency and timeout are configurable too, and so is a proxy:
SIGIT_TIMEOUT=15
SIGIT_MAX_CONCURRENCY=25
SIGIT_PROXY=http://127.0.0.1:8080Configuration can be passed through the environment or through a .env file in the project root, which is handled by pydantic-settings in core/config.py. Two optional external API keys are also defined, SIGIT_VERIPHONE_KEY and SIGIT_ISITAREALEMAIL_KEY, which belong to the phone number and email validation services.
The proxy option deserves a mention, because it changes the operational picture. Through a local proxy at 127.0.0.1:8080, all outbound traffic from the toolkit shares one egress address, which is also how you would point it at a monitoring setup of your own.
Installing with uv and getting the sigit executable
The prerequisites are Python 3.11 or higher, and uv as the recommended package and project manager, with standard pip as an alternative. The install path is a clone and a sync:
git clone https://github.com/termuxhackers-id/SIGIT.git
cd SIGIT
uv syncThat registers the sigit executable into the environment. A global install is also possible, either with uv or with pip:
uv tool install .
# or
pip install .The packaging is standard modern Python. The project is named sigit, version 0.2.1, requires Python 3.11 or later, and is built with hatchling, with the wheel target shipping the sigit package. The console script is declared as sigit = sigit.__main__:entrypoint, which is why the command name and the import name match.
Runtime dependencies are deliberately few: certifi for certificate authorities, curl-cffi for the impersonating transport, phonenumbers for the phone service, pydantic and pydantic-settings for the schema and settings layers, and rich for terminal rendering. Development tooling is grouped separately, with pyright, pytest and ruff, and the ruff configuration sets a line length of 100 and targets py311 with the E, F, I, UP and B rule sets selected.
The repository also keeps a main.py at the top level and a tests/ directory, with pytest configured to use the repository root on the path.
Scriptable subcommands and an interactive menu over the same services
SIGIT runs in two modes, and both go through the same service layer. The guided menu is started with the bare command:
sigit
# or with uv
uv run sigitFor scripting, every service is a subcommand, and help is available at two levels. The global help lists everything:
sigit --helpAnd each service exposes its own parameters, for example:
sigit port_scanner --help
sigit email_recon --help
sigit user_recon --helpThe execution examples in the README show the flags in use, including the JSON export switch:
sigit ip_location --ip 8.8.8.8
sigit email_recon --email [email protected]
sigit user_recon --username targetuser -o user_profiles.json
sigit dns_recon --domain google.com -o results_dns.json
sigit port_scanner --target 127.0.0.1 --ports 22,80,443 --timeout 1.0
sigit header_analyzer --url https://example.comThe -o flag writes structured output to a file, which is the feature that makes the toolkit composable. A scan result that lands in JSON can be read by the next tool in your pipeline instead of being copied by hand.
One detail to note is that the parameter names are uniform: --ip, --email, --username, --domain, --target, --ports, --timeout and --url. That consistency comes from the schema-driven parser, and it is the difference between learning one tool and learning fifteen.
The licence and the version history disagree with each other
Two inconsistencies in the project metadata are worth flagging before you build on it.
The first is the licence. The repository metadata reports the licence as Unlicense, while pyproject.toml declares license = { text = "MIT" }, the classifiers include the MIT licence classifier, and the LICENSE file sits at the root of the repository. The Unlicense is a public domain dedication, and MIT is a permissive licence with an attribution requirement, so those are not the same thing. If you need to state the licence in a distribution or in a compliance checklist, resolve this with the maintainers rather than guessing from the badge.
The second is the version sequence. The release history runs 1.0 on 2021-04-21, then 2.0 on 2026-05-12, then 0.2.1 on 2026-10-04, and the current pyproject version reads 0.2.1. A 2.0 followed by a 0.2.1 is unusual enough that you should treat the tag names as historical rather than as an ordering you can rely on for upgrade guidance.
The last push to main was on 2026-10-04, the same date as the 0.2.1 tag, so the work is current. There is no sign of an archive notice, and the README describes an active framework with a published service catalogue and a contribution path for new services.
Where SIGIT is the wrong tool
The clearest limitation is that each service does one fixed thing with fixed parameters, which is by design but limits depth. The port scanner takes a target, a port list and a timeout, and reports what answered. It does not attempt version fingerprinting, service detection or exploitation, and nothing in the service catalogue suggests otherwise. If your task is to go deeper than a single scan per service, you are outside what this toolkit does.
The second limitation is that several services depend on outside data sources whose behaviour you do not control. BreachChecker checks accounts against indexed public breaches, which means the coverage depends on that index. EmailRecon and UserRecon check registration across many platforms, and the README itself is inconsistent about how many: the catalogue says 100+ platforms for email_recon while the usage section describes email reconnaissance across 140+ platforms. GitHubRecon depends on public data that the platform may rate limit.
The third limitation is environmental. WHOISLookup retrieves data through the system whois utility, so it needs that binary present and behaving on the host, and it inherits whatever rate limits and privacy proxies the registry applies. On a minimal container or a phone terminal this is the service most likely to fail quietly.
The alternative approach for any single task is to call the underlying service directly. Resolving DNS over HTTPS with a plain HTTP request, running whois on the command line, or using curl directly are all one-liners with no framework in the way. The difference in approach is that SIGIT gives you uniform flags, typed validation, consistent rendering and JSON export across fifteen tasks, at the cost of a dependency stack and a Python runtime. If you only need one of those tasks, the framework is more than the job requires.
One last point is not technical. Several services probe third party systems, and the authorisation to run them against a given target does not change because a tool makes it convenient. The toolkit documents no permission model, so that judgement stays with the operator.
Editorial conclusion
Adopt SIGIT when you want one scriptable command per reconnaissance task, with typed parameters and JSON output you can pipe into other tools, and skip it when you need deeper control than a single scan per service provides, since each tool does one job with fixed parameters. Verify three things before you rely on it: the licence, which the repository metadata reports as Unlicense while pyproject.toml declares MIT, the platform count for email and username checks, since the service catalogue says 100+ while the usage example says 140+ for email_recon, and that the whois service works on your host, because it shells out to the system whois utility rather than doing the lookup itself. The last push to main was on 2026-10-04 and version 0.2.1 was tagged the same day.
Frequently asked questions
How do I install SIGIT?
Clone the repository and run uv sync, which registers the sigit executable in the environment. A global install is also possible with uv tool install . or pip install ., and Python 3.11 or higher is required.
What services does SIGIT provide?
Fifteen services across six categories: DNS, subdomain and WHOIS lookups; email reconnaissance and mail finding; IP geolocation, port scanning and reverse IP; phone number validation and technology detection; breach checking, header analysis and SSL checks; and GitHub and username reconnaissance.
How does SIGIT avoid being blocked by websites?
HTTP traffic runs through curl_cffi with browser fingerprint impersonation using JA3 and JA4, and the impersonation target is configurable through SIGIT_IMPERSONATE, with chrome124 shown as an example. Concurrency and timeouts are bounded by SIGIT_MAX_CONCURRENCY and SIGIT_TIMEOUT.
Can I export SIGIT results as JSON?
Yes. Every service accepts an output file flag, for example sigit user_recon --username targetuser -o user_profiles.json and sigit dns_recon --domain google.com -o results_dns.json. The rendering layer also supports tables, panels, lists and raw text.
How do I add a new service to SIGIT?
Create a tool directory under the matching category in sigit/services/, for example sigit/services/network/my_scanner/, and follow the remaining steps in the README's guide. The registry performs recursive package discovery, so a conforming service is picked up and given a generated subcommand.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/termuxhackers-id-sigit)Was this useful?