{
  "markdown": "# Perimeter Watch Scanner\n\nPassive external-perimeter checks for the domains you own or manage. This is the\nscanner engine behind [Perimeter Watch](https://entradox.github.io/perimeter-watch-site/) —\nopen-sourced so you can verify exactly what it does and run it yourself.\n\n**The hosted version is here: https://entradox.github.io/perimeter-watch-site/**\n($9/mo for 3 domains, $19/mo for 10 — weekly briefs with evidence, zero maintenance).\nSelf-hosting this repo gets you the scanner only: you build the cron, the diffing,\nthe delivery, and the retention archive yourself.\n\n## What it checks (all passive, public data only)\n\n1. **TLS certificate expiry** — read from public Certificate Transparency logs (crt.sh);\n   direct-connect fallback; alert window <14 days\n2. **Domain registration expiry** — whois with RDAP fallback (rdap.org); alert window <21 days\n3. **Dangling DNS / subdomain takeover** — 50 common subdomains checked via DNS;\n   CNAME targets fingerprint-matched against the can-i-take-over-xyz list (Heroku, S3,\n   Azure, GitHub Pages, Netlify, Shopify, etc.). A fingerprint CNAME whose target no\n   longer resolves = takeable = RED\n4. **Lookalike domains** — hyphen/plural/suffix variants queried in CT logs (info-only;\n   content-verification is planned as Phase 2)\n\n**What it never does:** port scans, crawling, active testing, credential access,\ntakedowns, or fixes. If it can't reach a source, it says `COVERAGE_GAP` in the output —\nit never guesses.\n\n## Quick start\n\n```bash\n# requirements: python 3.10+, dig (bind-utils/dnsutils), whois (optional — RDAP fallback exists)\npython3 perimeter_scan.py --domain example.com --state state.json --brief --evidence-dir ./evidence\n```\n\nOutput: full JSON (stdout + state file), a rendered one-page brief, and an append-only\nevidence line in `evidence/<domain>.jsonl`.\n\nSample run (real output):\n\n```\n# Perimeter Watch Brief — example-site.com\n**Rating: GREEN** | Scan window: 2026-09-03T15:54 → 15:54\n## COVERAGE\n- tls:               OK — cert expires in 93 days\n- domain_lifecycle:  OK — 294 days remaining\n- dangling_dns:      OK — 50 subdomains checked, zero takeable records\n- lookalikes:        OK — 4 variants queried, 0 registered\n```\n\n## Weekly cron\n\n```bash\n# crontab -e — Mondays 03:00, every domain in domains_authorized.txt\n0 3 * * 1 cd /path/to/repo && for d in $(cat domains_authorized.txt); do python3 perimeter_scan.py --domain \"$d\" --state \"state_${d}.json\" --evidence-dir evidence >> briefs/weekly_log.md 2>&1; done\n```\n\n## Rules baked into the code\n\n- **Authority before scan.** Only scan domains you own or are authorized to manage.\n- **Passive only.** Public records: CT logs, whois/RDAP, DNS resolution. No probing, ever.\n- **Honest failure.** Unreachable sources produce `COVERAGE_GAP`, never a fake GREEN.\n- **No takedowns, no fixes.** Detection and evidence only.\n\n## License\n\nMIT. Attribution appreciated, not required.\n\n## Don't want to run cron yourself?\n\nThe hosted service does all of this weekly, delivers the brief with evidence to your\ninbox, and supports agency-resell terms: **https://entradox.github.io/perimeter-watch-site/**\n\nContact: entradox@icloud.com",
  "bytes": 3154,
  "sha": "7fcf7f5ca7037ab4582dd2c501015a8f111f61794a2ea901635f29e26139f314",
  "repo_slug": "entradox/perimeter-watch-scanner",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_entradox_perimeter_watch_scann_2e33c56c/readme"
}