#224
feat(recon): add Subdomains by Jsmon as a passive subdomain source
Summary
Integrates Subdomains by Jsmon — a passive subdomain intelligence API with 5.4B+ subdomains — as a new source in the domain-discovery fan-out, alongside crt.sh, HackerTarget, Subfinder, Amass and Knockpy.
query_jsmon()indomain_recon.pymirrors thequery_hackertargetpattern: per-source circuit breaker,KeyPoolrotation, scope filter, max-results cap, dict-style{subdomain: {"jsmon"}}return for graph source attribution- Full settings cascade: Prisma (
jsmonEnabled,jsmonMaxResults,jsmonApiKey) → PythonDEFAULT_SETTINGS→ fetch mapping →registry.yaml→registry.json→ frontend toggle inSubdomainDiscoverySection - API key via
UserSettings.jsmonApiKey(global per-user, not per-project), with rotation support, import/export, masking, andNOT_PROBEDentry (no usage endpoint) internal-networkpreset disables jsmon (no public OSINT for RFC1918 targets)- Graph schema updated:
"jsmon"in Subdomain.sourcevalues - Preset schema: Zod +
RECON_PARAMETER_CATALOGentries for AI presets - 12 unit tests (
test_jsmon_source.py): 200/401/429/404/network-error, scope filter, max cap, disabled/no-key skip — all offline via mockedrequests.Session
Skills / contracts followed
recon-tool-integration(enrichment_isolatedcontract, graph completeness, preset catalog)project-settings-cascade(Prisma + Python + registry + frontend)graph-db-writes(source value addition toschema_sections.md)
How to get a free API key
- Visit https://subdomains.jsmon.sh
- Register — the free tier gives 3 queries/day and up to 100 results per query
- Paste the key in Settings → API Keys → Jsmon Subdomains API Key
Defaults
- Enabled by default (
jsmonEnabled: true), but no-ops without an API key — zero impact on existing scans jsmonMaxResults: 5000 (stealth ceiling: 100)
Subsystems touched
| Subsystem | Files |
|---|---|
| Source module | recon/main_recon_modules/domain_recon.py |
| Settings | recon/project_settings.py, recon_settings/registry.yaml, recon_settings/registry.json |
| Prisma | webapp/prisma/schema.prisma |
| Frontend | SubdomainDiscoverySection.tsx, inputLogicTooltips.tsx |
| Preset schema | recon-preset-schema.ts |
| Hardcoded presets | internal-network.ts |
| API keys | apiKeysTemplate.ts, rotationTools.ts, apiUsage/registry.ts |
| User settings route | webapp/src/app/api/users/[id]/settings/route.ts |
| Graph schema | graph_db/schema_sections.md |
| Build artifact | webapp/src/lib/reconSettings/registry.json |
| Tests | recon/tests/test_jsmon_source.py |
| Test counts | apiKeysTemplate.test.ts |
Steps for maintainer / CI
I did not run Docker, Prisma, typecheck or the test harness (scope-limited to file edits).
-
python3 recon_settings/build.py—registry.jsonwas hand-edited (PyYAML unavailable); re-running build.py will produce the canonical output and update theroe_parse_prompt.pySHA-256 digest -
docker compose exec webapp npx prisma db push— apply the two new Project columns + one UserSettings column -
docker compose exec webapp npx tsc --noEmit— typecheck -
./redamon.sh test unit— full unit gate
🤖 Generated with Claude Code