Exec Summary
Intro
Workspace
Auto-Pivot
Architecture
Capabilities
Domain
Username
Graph & Cases
Two Numbers
Accuracy
Security
Engineering
Discussion
Ethics
Future
Conclusion
Sources
Executive Summary Why GeoIntel Exists The Workspace Auto-Pivot Engine Architecture Capabilities Domain Username Graph, Cases & Evidence Two Numbers Data Accuracy Security Model Testing & Delivery Discussion Ethics & Use Future Work Conclusion Sources
◈Unified OSINT · Multi-Identifier Intelligence · Build Study

HEAVEN-GeoIntel
A Unified
OSINT Intelligence Platform

Seven Identifiers · One Console · Link Analysis · Real Data or Nothing

◈ Author-built · zero API keys to start · source on GitHub
Nisarg Chasmawala (shroff)
alias // HEAVEN
Penetration Tester  |  Vulnerability Assessment  |  Cybersecurity Researcher  |  Offensive Security Engineer  |  Digital Forensics
7+Identifiers
11+Modes
30+API Ops
34+Sources
100%Coverage
Scroll to Explore

This is a build-and-evaluate study of HEAVEN-GeoIntel, a unified OSINT intelligence platform the author designed and wrote for penetration testers, security researchers, and OSINT analysts. The problem it addresses is mundane but expensive: an analyst pivots by hand across twenty to thirty tools and browser tabs to build a picture around a single identifier. GeoIntel folds that work into one console over seven identifier types, phone, email, username, IP, domain, crypto wallet, and file hash, plus an in-browser file-metadata reader, and links the results into a graph that shows how they connect. It exposes 30+ API operations across 21+ endpoints, reaches most of its intelligence through 25+ of 34+ sources that need no API key, and holds every route to a 100 percent test-coverage gate. Its governing rule, applied in every layer, is that it returns real, derivable metadata and nothing else: no placeholders, no simulation, and no identity fused to a person without proof. This paper goes past the feature list into the engineering decisions that make those guarantees hold, and argues that the value of an OSINT tool is the truth of its output, not the size of its hit count.

00 — Executive Summary

GeoIntel at a Glance

GeoIntel is a production-ready platform, not a prototype. The counts below grow with each release, so they are written as floors rather than fixed numbers.

🛰️
One console, seven identifiers
Phone, email, username, IP, domain, wallet, and hash in an 11-mode workspace with a command palette, plus an in-browser file-metadata reader, so an analyst stops juggling tabs.
🔑
Zero API keys to start
25+ of 34+ sources need no key. Offline analysis and free-source fan-out work out of the box; optional keys deepen the picture but are never required.
🔗
It links the identifiers
Every result offers the identifiers it derived as one-click pivots, and a graph draws the connections, with confirmed links kept separate from candidates.
✅
Real data or nothing
A username is FOUND only on proof; an ambiguous phone type is labelled ambiguous; a sanctions miss says "not on this list," never "clean"; unresolved fields stay blank.
🗂️
Cases and evidence
File-backed cases survive restarts, carry a graph, notes, a change inbox, and a hashed evidence locker, and export as PDF, STIX 2.1, Maltego, and more.
🔒
Hardened and tested
Keys stay server-side, every lookup is validated into fixed hosts with no SSRF, and a 100 percent coverage gate holds every route, including the proxy and auth gate.
Motivation
01 — Introduction

Why GeoIntel Exists

The pivoting problem

Open-source intelligence work is rarely blocked by a lack of data. It is slowed by the shape of the work. To build a picture around one phone number or one email address, an analyst opens a reverse-lookup site, then a breach checker, then a carrier tool, then a handful of search engines, then a username scanner, copying a value between each and holding the connections in their head. The intelligence is out there; the friction is in the pivoting, and it scales badly across an investigation.

GeoIntel starts from that observation. Rather than a new data source, it is a console that centralises the fan-out and, more importantly, keeps the links. When a lookup derives another identifier, a domain's mail host, a Gravatar-linked username, an IP behind a service, it offers that identifier as a one-click pivot and records the relationship so a graph can show it later. The analyst stops being the integration layer between a dozen tools that do not talk to each other.

What it refuses to do

The tool draws a hard line around what it returns. It gives publicly derivable metadata only. It does not and cannot provide real-time GPS, live device tracking, or SS7 interception, and its licence explicitly prohibits stalking, harassment, doxing, domestic abuse, and any non-consensual surveillance. That line is not just legal cover; it shapes the engineering. The platform is intended for use inside an explicit written penetration-test scope, or for OSINT research, journalism, and self-protection, and only in ways that comply with the laws of both the analyst's jurisdiction and the target's. Its accuracy discipline exists precisely so it cannot be turned into a tool for inventing a fact about a person.

"The measure of an OSINT tool is not how many hits it reports. It is whether every hit is true. A tool that proudly says a handle was found on forty sites, when thirty of those answer for any handle, has produced confident noise, not intelligence."

GeoIntel design rationale

Contributions

The Workspace
02 — The Console

One Workspace, Eleven Modes

GeoIntel is a single console with an 11-mode switcher. Seven modes are live lookups, one reads deep metadata from any file in the browser, and the last three are workflow tools. A command palette ties them together: type any identifier and it auto-detects the type and runs the lookup, jumps between modes, or toggles the theme.

ModeWhat it does
PhoneCarrier, type, NPA geo, two separate scores, pivots, QR, report
EmailUnified breach view, password exposure, reputation, identity, validation
Username38+ sites in parallel, plus a 242+ site deep sweep on request
IPGeo, ASN, ISP, reverse DNS, VPN/proxy/hosting flags, exposure, risk score
DomainDNS, WHOIS, SPF/DMARC, subdomains, HTTP/TLS posture, legal entity
WalletOFAC SDN screening, BTC activity and counterparties, ERC-20 holdings, ENS
HashFile-hash reputation (CIRCL / NSRL) plus an offline crypto workbench
FileDeep metadata from ~70 formats, parsed in the browser, never uploaded
BulkUp to 500 mixed identifiers as a cancellable job with per-row provenance
GraphLink-analysis graph of the session, or of any saved case
CasesPersistent cases: notes, per-case graph, hashed evidence locker, change inbox

The console is keyboard-first: number keys switch mode, a slash focuses the input, and the palette handles the rest. Every lookup produces a shareable URL, so a result in any mode can be bookmarked or handed off. A sources-and-keys panel shows which data sources are live and lets an analyst add optional API keys in the app rather than editing a file, and those keys are stored server-side and never sent back to the browser; the interface only ever sees a configured-or-not flag. The look is a hybrid cyberpunk glass design, 3D tilt cards, an animated grid, a Canvas katakana rain, in both light and dark, and it honours reduced-motion.

Core Idea
03 — Cross-Identifier Pivoting

The Auto-Pivot Engine

The heart of GeoIntel is the piece that turns a set of separate lookups into a connected investigation. After any lookup, the auto-pivot engine reads the identifiers the response already contains, a domain's MX host, a Gravatar-linked handle, an unmasked infostealer IP, and offers each as a one-click follow-up. It is a pure function over data already gathered; it never synthesises an identifier, and it deliberately drops values that are evidence rather than something you can pivot on, such as Hudson Rock's masked entries.

GeoIntel — Cross-Identifier Auto-Pivot Flow
flowchart LR T([Target\nidentifier]) --> LK{Lookup\nengine} LK --> RES[Typed\nresult] RES --> AP{Auto-Pivot\nengine} AP -->|MX host| D2[Domain] AP -->|linked handle| U2[Username] AP -->|service IP| I2[IP] D2 & U2 & I2 --> PIN{Pinned to\ncase?} PIN -->|both ends| G[(Link Graph\nderived edge)] PIN -->|no| CAND[Candidate\nnot stored] style T fill:#0b1629,stroke:#00f5d4,color:#dde8f7 style AP fill:#0f1e38,stroke:#818cf8,color:#dde8f7 style G fill:#020912,stroke:#34d399,color:#34d399 style CAND fill:#0b1629,stroke:#f472b6,color:#f472b6

The distinction that keeps this honest is between a confirmed link and a candidate. A relationship is only stored on the graph when both of its ends were actually pinned to the case, so the graph can never contain a node the case does not, and each derived edge is labelled with the source that produced it. The analyst sees the derivation, not a guess: "Gravatar, linked GitHub account" or "DNS, MX host," drawn as a dashed edge between two real nodes on top of the membership spokes. The pivot engine widens an investigation by offering real, derivable next steps, and never claims a link it cannot show the source for.

Architecture
04 — System Design

GeoIntel Architecture

GeoIntel is a Next.js 16 application on React 19 with a strict-TypeScript codebase, built so that every UI feature is also a JSON API. A lookup is an App Router route that validates its input, fans out to the relevant sources in parallel, folds the results through the auto-pivot engine, and returns a typed response. The same route registry generates an OpenAPI 3.1 specification at request time, and a test fails the build if the registry and the actual routes ever disagree, so the API documentation cannot quietly drift out of date.

GeoIntel — Layered Architecture (offline first, free sources, optional keys)
flowchart TD subgraph UI[One Console · 11 Modes] CP[Command Palette] MODES[Phone · Email · Username\nIP · Domain · Wallet · Hash] end UI --> RT[App Router Routes\n30+ ops · 21+ endpoints] RT --> VAL[Validate + Safe-Fetch\nno SSRF] VAL --> OFF[Offline Datasets\nNPA · MCC/MNC · country · OFAC] VAL --> FREE[Free Keyless Sources\n25+ of 34+] VAL --> OPT[Optional Keyed\nenrichment] OFF & FREE & OPT --> PV[Auto-Pivot Engine] PV --> STORE[(File-backed Cases\n.data · no DB)] RT --> DOCS[/OpenAPI 3.1\ngenerated/] style UI fill:#0b1629,stroke:#00f5d4,color:#dde8f7 style RT fill:#0f1e38,stroke:#818cf8,color:#dde8f7 style VAL fill:#0b1629,stroke:#f472b6,color:#dde8f7 style STORE fill:#020912,stroke:#34d399,color:#34d399 style FREE fill:#0b1629,stroke:#34d399,color:#34d399

Underneath the routes sit three layers. A server layer holds the case store, the API-key store, the audit log, the cache, the rate limiter, input validation, and a safe-fetch wrapper that is the single choke point for every outbound request. An analysis layer holds the pure functions, phone and email analysis, IP classification, hash detection, entity extraction, cross-pivots, case correlation and merging. A data layer holds the offline datasets, a country-intelligence table of 99 countries, the MCC/MNC operator map, a US and Canada NPA area-code database of 397 codes, the username-site catalogue, the disposable-domain list, and the bundled OFAC sanctions snapshot, so a large part of every lookup resolves with no network call at all.

GeoIntel — A Single Lookup, End to End
flowchart LR IN[Identifier] --> V[Validate\ninput] V --> OFF[Offline\nanalysis] OFF --> FAN{Parallel\nfan-out} FAN --> S1[Keyless\nsources] FAN --> S2[Optional\nkeyed] S1 & S2 --> MERGE[Merge +\ndedupe] MERGE --> PIV[Auto-pivot\nderive] PIV --> OUT[/Typed result\n+ pivots/] OUT --> GR[(Session\ngraph)] style IN fill:#0b1629,stroke:#00f5d4,color:#dde8f7 style FAN fill:#0f1e38,stroke:#818cf8,color:#dde8f7 style MERGE fill:#0b1629,stroke:#fbbf24,color:#dde8f7 style OUT fill:#0b1629,stroke:#34d399,color:#34d399 style GR fill:#020912,stroke:#00f5d4,color:#00f5d4

Persistence is deliberately simple. Investigation cases are written to a file store rather than a database, owner-only and git-ignored, so they survive restarts with no external dependency, and the whole platform runs with no database, no Redis, and no cloud account. A multi-stage Docker image ships with the repo, runs as a non-root user, and binds to localhost only by default, so the console is not exposed to the network unless the operator chooses to expose it.

Capabilities
05 — What It Does

Capabilities, by Identifier

Phone intelligence

Every phone lookup returns real data derived from the number structure and bundled datasets before any network call: country, calling code, validity by Google's libphonenumber, line type, all four formats, expected digit length, IANA timezone and offset, and for US and Canada the area code, state, and metro from a real NPA database of 397 codes. On top of that offline core it fans out to free sources, Hudson Rock for infostealer exposure and LeakCheck for the public breach index, both keyless, and offers 37 deduplicated OSINT pivots across five categories, each tagged by access tier, FREE, CAPTCHA, APP, LOGIN, PAID, or BLOCKED, so an analyst can filter to the free ones first. It also builds a QR code for the tel URI and an attack-vector grid across vishing, smishing, SIM-swap, spoofing, pretexting, and location.

Email intelligence

An email lookup runs offline classification instantly, disposable across 1,200+ domains, free-webmail across 370+, privacy hosts, role addresses, government, and educational, then fans out in parallel. It reports breaches as a single unified, deduplicated view that merges XposedOrNot and LeakCheck, with the headline count being the union across sources rather than any one source's share, and it enriches bare breach names offline from three vendored, keyless catalogue snapshots: a rich credential tier from Have I Been Pwned and XposedOrNot whose overlapping descriptions are unioned, plus a Wikipedia notable-breaches tier for the large government and institutional incidents the credential indexes never carry. ProxyNova COMB adds masked password-exposure evidence with a reuse verdict. With an optional Have I Been Pwned key, HIBP's own per-account breaches join the union so the count can match HIBP directly.

IP and domain intelligence

Both are free and keyless. An IP lookup returns geolocation, ASN and ISP, reverse DNS, internet exposure through Shodan InternetDB, open ports and known CVEs linked to NVD, and risk flags for VPN, proxy, hosting, and Tor folded with a GreyNoise classification into a 0-to-100 score, with a second geolocation provider that answers when the first is throttled so a one-minute limit never escalates into an hour-long ban. The domain lookup is treated in depth below, because the way it was built is a case study in reading a degraded answer as degraded rather than as a small attack surface.

Wallet intelligence: sanctions, offline and first

The first question anyone asks about a crypto address is whether it is sanctioned, so that is the first thing the tool answers, before it ever looks at a balance. A snapshot of the US Treasury's SDN list ships with the app, 1,056 addresses across 20 chains, 532 Bitcoin, 254 Tron, 120 Ethereum, 94 USDT, and the rest, read from the XML export rather than the CSV, whose truncated remarks column loses half the addresses. It is offline by design: no key, no network call at lookup time, and no rate limit between an analyst and a sanctions answer, and the screen reports the designated entity, OFAC's own entry id, and the programs the address is listed under, so a hit traces back to the list. It answers even for chains whose balance the tool cannot read: a listed Tron address returns the sanctions match plus a plain statement that the balance is not fetchable, rather than a generic failure.

⚠

Scope stated, not implied. This is the SDN list only. A negative result means "not on this list," never "clean." Other authorities publish their own lists, and an address one hop from a listed one is not itself listed. Beyond sanctions, the tool reports Bitcoin activity and distinct counterparties, ERC-20 balances for a fixed set of ten value-carrying tokens read from a keyless public node, and a forward-verified ENS name whose reverse record is confirmed forward so a self-declared name that does not point back is never printed as the owner. The token list is deliberately short because there is no keyless way to enumerate every token an address holds, and pretending otherwise would mean a paid indexer or a made-up answer.

Hash and file intelligence

A hash lookup returns file-hash reputation through CIRCL hashlookup for known-software clearance against the NSRL set, and ships an offline crypto workbench to hash, encode, and encrypt or decrypt text in the browser, across the MD5 and SHA families, HMAC, Base64, hex, URL, binary, Morse, ROT13, Atbash, Caesar, Vigenere, XOR, and AES-256-GCM with a passphrase, plus a keyless Pwned Passwords check that uses k-anonymity so only the first five characters of a password's SHA-1 hash ever leave the tab. The File mode reads deep metadata from any file entirely in the browser, the file is never uploaded: it identifies about seventy formats by content, then reads each one properly. Photos give EXIF and GPS, IPTC byline and caption, XMP identifiers and camera serials; PNGs give their text chunks, including the prompt and seed an image generator wrote; PDFs give the author block, save history, embedded fonts, and active content; Office files give author, company, manager, and editing time from both the modern XML and the legacy OLE2 formats; archives give their member list and risky paths; executables give their build timestamp, toolchain, and symbol paths. Every file also gets SHA-256 and SHA-1, an entropy figure, and an extension-versus-content check.

Case Study · Domain
06 — Engineering Case Study

Domain Intelligence: Reading a Thin Answer Honestly

The domain lookup is the clearest example of the tool's core discipline, because getting it right meant treating a confident-looking answer as a bug. Coverage used to be one question with one answer. The certificate-transparency source, Certspotter's free issuances API, returns roughly the hundred most recent certificates, and a second source, crt.sh, was only consulted when Certspotter came back with fewer than five hosts. On wordpress.org, Certspotter's window held 9 hosts, so the threshold was never crossed, while crt.sh held 25. The tool reported 9 as though that were the answer.

The fix was to stop trusting a single source's window. Now both certificate-transparency sources always run in parallel, and two more join them: reverse IP contributes the names sharing the apex address, and passive DNS contributes every name beneath the apex it has ever recorded. On wordpress.org, 194 of 200 passive-DNS rows were for a subdomain rather than the apex. The panel prints a coverage strip, each source, whether it answered, and how many hosts it contributed, so a thin result reads as a thin source rather than as a small attack surface. Measured end to end, wordpress.org went from 9 hosts to 494 distinct.

◈

A degraded source is parked, not parsed. The reverse-IP provider returns its errors as plain text in the body, so "API count exceeded" would parse as a hostname if read naively. Every line has to survive hostname validation, and a quota notice parks the source for an hour instead of being read as data. The first 40 discovered names are then resolved, so a name from certificate transparency that no longer points anywhere is visibly dead rather than silently listed, and a third-party domain that merely shares the server is reported separately as co-hosting, because that is a different finding from a subdomain of the name you asked about.

Exposure on the domain's own addresses

The tool already knew how to ask what is exposed on a host; it just never asked it about the host it had resolved a moment earlier, so a domain lookup could not tell you that its own web server has an open Redis port. The apex addresses, capped at three so a round-robin address set cannot turn one lookup into a dozen calls, now go through the same keyless Shodan InternetDB and GreyNoise path the IP mode uses. On muenchen.de that returns ports 80 and 443 and four CVEs on the apex address.

Who legally owns it

GDPR redacted the registrant out of most generic-TLD WHOIS records. What survived is the organisation on an OV or EV certificate, which a certificate authority actually verified, and that is a name the Global Legal Entity Identifier Foundation's register can be queried with, keylessly. So the LEI lookup runs on the WHOIS registrant when there is one and on the certificate organisation when there is not, and the answer says which it used. As a worked example, paypal.com has no registrant in RDAP and an OV certificate reading "PayPal, Inc.", which resolves to a specific LEI. The register does word matching, so that name alone returns tens of thousands of hits; only an exact normalised name match is reported as the entity, and the rest are offered as candidates rather than asserted.

Internationalised names, served as the analyst sees them

An internationalised domain such as muenchen.de written in its native script used to be rejected as invalid while its punycode spelling sailed through, which is backwards for OSINT, since homoglyph abuse is a large share of real phishing and the analyst pasting the name as it appears in the mail is the one to serve first. Every domain-shaped input is now normalised once to its ASCII form using the platform's own UTS-46 implementation rather than a hand-rolled table, and displayed in both spellings. The reverse direction matters for reading: a punycode label tells you nothing and a Cyrillic look-alike of a familiar brand tells you everything, so ASCII labels are decoded for display, and a label that will not decode is shown exactly as it arrived rather than guessed at. The look-alike generator gained the matching half, producing Cyrillic, Greek, and Armenian homoglyph variants, each carrying both the punycode name to resolve and the Unicode name a victim sees.

Case Study · Identity
07 — Engineering Case Study

Username Intelligence: Proof, Not a Shared Handle

Username OSINT is where most tools quietly lie, and where GeoIntel spends the most effort not to. A handle is checked across 38+ sites in parallel, with a 242+ site deep sweep available on request. Of the core set, 23 are auto-verified server-side, so there are no browser cross-origin limits, and marked FOUND or UNVERIFIED. The other 15 are JavaScript apps or bot-walls that answer for every handle, or anti-bot challenges that block a keyless server fetch, so a server probe genuinely cannot tell whether the account exists, and the tool never guesses: it flags them for manual verification and hands you a one-click link to confirm yourself.

Which sites can be trusted was decided empirically

How many handles you test a site with changes the answer, and the catalogue reflects that rather than a hopeful guess. Testing one real handle against one fake one made several sites look auto-verifiable; re-running across eight known-real and six known-absent handles showed one of them returns a success for absent handles too, while two others report real accounts as missing. Only the sites that survived that wider test were promoted to auto-verified. Even a promoted site is probed only for handles it can actually hold: one major platform serves a success page for any string that is not a valid handle, so a dotted or hyphenated name is reported not found there rather than claimed.

Alongside the existence sweep, nine platforms are read through their own keyless public API, which upgrades "the account exists" to "here is who it is": GitHub, GitLab, Codeberg, Hacker News, Reddit, Bluesky, Mastodon, Chess.com, and Lichess return a real name, join date, location, follower counts, and bio. Two of them hand you a cross-platform edge for free, one reporting a streamer's linked Twitch URL and another a self-declared website. Each was promoted only after a clean split across four known-real and four known-absent handles, and three candidate sources were tested and rejected for returning a success on handles that do not exist.

Identity is resolved to proven, or a candidate

The hardest problem in username OSINT is knowing whether the same handle on two sites is the same person, and GeoIntel answers it with evidence rather than assumption. Beyond a self-declared link between accounts, it establishes a match by comparing the two profile photographs, and it does so server-side, which is what makes it work at all: a browser cannot read the pixels of an image from another origin, so a client-side comparison could never have produced a real match. Each avatar is fetched through the same SSRF guard as every other outbound request, decoded without a native dependency, reduced to a nine-by-eight grey grid, and hashed by a row-wise gradient into a perceptual hash. Two avatars are compared by Hamming distance over that hash, and known placeholder art, the default Gravatar, an identicon, a lettered initial, is recognised and never used as a link, because two identical default avatars prove nothing.

✓

The output is a confidence and the proofs it rests on. On a well-known developer handle, the tool fuses a GitHub and a Mastodon account on a full avatar match and resolves the identity at a high confidence; on another handle it finds no proof, labels the result a candidate at a capped low confidence, and lists two same-named accounts separately as unlinked candidates rather than absorbing them. Where two proven-linked accounts disagree on a name or a location, the contradiction is printed as a contradiction instead of being averaged away. The 242+ deep-sweep sites are offered rather than folded into every lookup, because hundreds of probes is tens of seconds and hundreds of sockets, and folding it in would make the fast answer slow.

Investigations
08 — Graph, Cases & Evidence

Link Analysis, Persistent Cases, and a Hashed Evidence Locker

The link graph

Every successful lookup adds a colour-coded node to an interactive graph connected to a central target, across all seven identifier kinds, turning a session of scattered lookups into one visual map exportable as a PNG. Pinning a result to a case also stores the relationships the auto-pivot engine derived, drawn as dashed edges between real nodes on top of the membership spokes, so the picture shows the derivation rather than just the roster, and only links whose both ends were pinned are stored.

Cases that survive, and a change inbox

Investigation cases are named, hold any identifiers an analyst adds, and carry their own link graph and free-form notes, backed by a file store so they survive restarts and sessions with no database. Pinning a lookup records a snapshot of the scalars worth watching for that mode, breach count, infostealer hits, open ports, subdomain total, registrar, DMARC policy, and pinning the same identifier again later diffs the new snapshot against the stored one and reports exactly what changed, computed server-side against what is on disk so it works across sessions and machines. A first snapshot is reported as a baseline, never as "no change," and a change inbox collects every movement across every case, newest first, with an optional webhook. An optional case lock seals the case store behind a signed token cookie while leaving the lookup console open.

The evidence locker

For work that may have to stand up later, the evidence locker preserves the response as the API actually returned it, hashes it with SHA-256 into a per-case manifest, and lets an analyst verify every artifact months afterward. A case exports as a paged PDF dossier with a cover sheet and a signature block, and also as JSON that is re-importable and integrity-hashed and warns on tampering, as Markdown, CSV, a Maltego paste table, and a STIX 2.1 bundle, so the output drops into whatever the next stage of the investigation uses.

Scoring
09 — Two Numbers, Not One

Why One Score Could Not Answer Two Questions

A single "threat score" is a common feature and, in this tool's own telling, a mistake it corrected. One score conflated two different findings. A number that appears in four breaches and a number used by a scam call centre both scored high, and the label said the same thing about both. The White House switchboard, a public number that sits in public breach indexes, read as a threat, which is plainly wrong.

So there are now two figures, and each says what it is. Abuse risk answers whether the identifier is being used against people, and moves on reputation verdicts from sources that actually make them: blacklisted, malicious, spam, known-fraud, disposable. Exposure answers how much of the identifier is already public, and moves on named breaches, credential records recovered, and infostealer captures. Exposure is evidence volume, not danger, and its bands say so, NONE OBSERVED, LIMITED, SIGNIFICANT, EXTENSIVE, rather than borrowing the language of risk.

◈

The worked example is the point. The White House switchboard now reads abuse 0 CLEAN with exposure 46 SIGNIFICANT, which is the truthful pair of statements: it is not being used against anyone, and it is very public. Both figures are computed locally, and each lists the signals that produced it, so an analyst can see why a number scored the way it did rather than trusting an opaque total.

Accuracy
10 — Data Accuracy

Real Data or Nothing

The accuracy discipline is the part of GeoIntel that most separates it from tools that optimise for an impressive hit count. The rule is simple and applied everywhere: return what can be shown, and be honest about the rest.

◈

Even the project's own poster is held to this rule. Every number on it is read out of the thing it describes at build time, the source manifest, the mode registry, the endpoint registry, so a claim like "25 of 34 keyless sources" cannot become false by adding a source, because a test fails the build if the artwork is older than the registries it quotes.

Security
11 — Security Model

Hardened by Default

Because GeoIntel handles sensitive lookups and optional third-party keys, its security model is designed to keep secrets server-side, refuse attacker-chosen destinations, and stay same-origin by default.

ControlWhat it does
API-key isolationEvery external fetch runs in a server route, so keys never reach the browser bundle; the UI only ever sees a configured-or-not flag.
No SSRFEvery lookup validates its input and only URL-encodes it into fixed upstream hosts, so a caller can never choose the destination.
Content-Security-Policydefault-src self, connect-src self, object-src none, frame-ancestors none, with a narrowed image allow-list.
Security headersX-Frame-Options DENY, nosniff, Referrer-Policy, a Permissions-Policy that blocks geolocation, camera, mic, payment, and USB, plus cross-origin isolation headers.
No trackingMetadata from structure and public databases only; no device tracking, analytics, or telemetry.
Rate limiting60 requests per minute per client plus a server-wide ceiling, fixed-window, every limit environment-tunable.
Optional case lockA single shared secret seals the case store behind an HMAC-signed token cookie, with constant-time comparison and instant invalidation on rotation.
Audit trailEvery lookup records type, hashed target, time, and status to an owner-only log.

The rate limiter is a small case study in the same honesty the rest of the tool shows. Next.js removed the socket address from a route handler, so the limiter identifies a client by the real IP behind a trusted proxy when an operator opts in, otherwise by a first-party opaque cookie that gives each browser its own bucket, and otherwise by one shared bucket for non-browser clients. The cookie carries no identity or history and exists only so that opening the console on a phone does not consume a laptop's allowance, while the server-wide ceiling stops a script that discards the cookie from exhausting a free upstream tier.

Engineering
12 — Testing & Delivery

A 100 Percent Coverage Gate and Reproducible Delivery

GeoIntel holds the files that ship to 100 percent coverage, statements, branches, functions, and lines, enforced by thresholds in the test config. The gate covers all of the library, the covered components, every API route, and the proxy, that is, every outbound fetch in the application plus the auth and CSRF gate. New gated code must ship with tests or an explicit, named ignore for a branch that is genuinely unreachable, or the build fails, so coverage cannot quietly erode.

Every push and every pull request runs lint, type-checking, the test suite with the coverage gate, and a build through GitHub Actions, plus a Playwright smoke suite, and a push to the main branch also publishes a multi-architecture container image. A dataset-overlay mechanism lets an analyst correct or extend the bundled data, an area code after a split, a new burner-mail provider, a username site, by dropping a JSON file, with a malformed overlay ignored rather than fatal, so the bundled data stays in force and the problem is reported instead of breaking a lookup. A username-site entry with no absence marker is rejected outright, because a site that cannot signal a missing account would claim every handle as found.

◈

The OpenAPI specification is generated from the route registry at request time, and a test walks the actual route files and fails the build if they and the registry disagree. Adding a route without documenting it is a red build, which is what keeps the "import it into Postman" promise from ever silently becoming untrue.

Discussion
13 — Discussion

Where GeoIntel Sits in the OSINT Landscape

OSINT tooling tends to fall into two camps. Aggregators pull many sources together but inherit their noise, reporting a handle as found on dozens of sites when most of those answer for any input. Specialist tools are accurate but narrow, forcing the analyst back into the tab-juggling GeoIntel set out to remove. GeoIntel's contribution is to be an aggregator that keeps a specialist's discipline about truth, and the engineering case studies above are the evidence: the domain lookup that treats a thin answer as a bug, the username catalogue decided by wider testing rather than a single probe, the identity fusion proven by pixels, the sanctions list read from the format that does not lose half its rows.

Three design choices carry the argument. The auto-pivot engine widens an investigation without inventing a single identifier, and separates confirmed links from candidates. The accuracy rules refuse to claim what cannot be shown, from an ambiguous phone type to an unverifiable username to an ISP-level IP location to a sanctions absence. And the keyless-first strategy, with 25+ of 34+ sources needing no key and a large offline core, keeps the tool useful in the field without a wallet full of API subscriptions. None of these is a headline feature; together they are the reason the output can go in a report.

Honest limits

GeoIntel is bounded by what open sources actually expose, and it is careful to say so. It returns metadata, not surveillance, and cannot locate a person in real time. Free source tiers impose rate limits, which is why bulk mode is offline for phones and why the tool tracks each provider's budget and parks a source that reports itself out of quota. WHOIS depth depends on a TLD's RDAP support, and a keyless wallet lookup reads a fixed token list because there is no keyless way to enumerate every token an address holds. Naming these plainly is part of the same discipline as the rest of the tool.

Ethics
14 — Ethics & Acceptable Use

Responsible Use by Design

A tool that gathers intelligence about people carries obvious dual-use weight, and GeoIntel treats that as an engineering constraint, not a footnote. It returns publicly derivable metadata only, and it cannot provide real-time GPS, live device tracking, or SS7 interception, capabilities that are the difference between OSINT and surveillance. Its licence prohibits stalking, harassment, doxing, domestic abuse, and any non-consensual surveillance outright, and places the responsibility for misuse squarely on the user.

Intended use is inside an explicit, written penetration-test scope of work, or for OSINT research, journalism, and protecting oneself, one's family, or one's organisation, and only in ways that comply with the laws of both the analyst's jurisdiction and the target's. The accuracy discipline reinforces the ethics: because the tool refuses to fabricate a fact or fuse an identity without proof, and refuses to read a sanctions absence as innocence, it is structurally harder to misuse it to build a false or invasive picture of a person. Doing OSINT responsibly means being right and staying in scope, and the platform is built to make both the default.

Future Work
15 — Future Work

Where GeoIntel Goes Next

Near term

Medium term

Longer term

Synthesis
16 — Conclusion

Conclusion

GeoIntel is an argument, made in software, that the value of an OSINT tool lies in the truth of its output, not the size of its hit count. It removes the friction that slows an investigation, seven identifier types in one console, 30+ operations across 21+ endpoints, a username checked across 38+ sites, and it keeps the links between what it finds so an analyst works with a connected picture rather than a pile of tabs. But its defining choices are the disciplined ones, and the engineering case studies are where they show: a domain lookup that grew wordpress.org from nine hosts to nearly five hundred by refusing to trust one source's window, a username catalogue whose every auto-verified site earned its place under wider testing, an identity fused only when the pixels of two avatars actually match, a sanctions list read from the XML that keeps all its rows.

Those choices are what make the output usable. A graph that never contains a node the case cannot show, a username result with zero false positives on a nonexistent handle, an IP location that admits it is ISP-level, a sanctions answer that says "not on this list" rather than "clean," these are the properties that let the work go into a report and stand up in front of someone who will check it. The security model reinforces the same posture: keys stay server-side, no lookup can be pointed at an attacker's host, and a 100 percent coverage gate holds every route to test.

The tool is bounded by what open sources expose, and it says so plainly, metadata not surveillance, a fixed token list rather than a fabricated one, a single sanctions list named as such, WHOIS depth that depends on the registry. That honesty is not a limitation bolted on at the end; it is the same rule that runs through every layer, and it is visible in the two-number rewrite of the scoring, the parked source that will not be read as data, the contradiction that is printed rather than averaged. GeoIntel is built on the belief that doing OSINT well means being right and staying in scope, and it is engineered to make both of those the default rather than the exception.

17 — Sources

Data Sources

GeoIntel reaches its intelligence through documented public sources. The keyless sources below are consulted with no API key; the optional ones deepen a lookup when a key is supplied. All are the genuine services the platform integrates.

  1. libphonenumber-js · Google's libphonenumber compiled to JavaScript, for offline phone parsing and validation.
  2. Hudson Rock Cavalier · infostealer-malware exposure for phone, email, and username. Free, no key.
  3. XposedOrNot · breach database (1000+ databases), also a vendored offline catalog tier. Free, no key.
  4. LeakCheck (public index) · named breaches and exposed field types. Free, no key.
  5. Have I Been Pwned · per-account breaches unioned into the breach view, and a vendored offline catalog tier. Optional paid key.
  6. ProxyNova COMB · masked password-exposure evidence with a reuse verdict.
  7. Gravatar · avatar and profile resolution for email and username.
  8. ip-api.com and ipwho.is · IP geolocation with automatic failover. Free.
  9. Shodan InternetDB · open ports and known CVEs for an IP or a domain's own addresses. Free, no key.
  10. GreyNoise · internet-scanner classification, folded into IP risk. Free tier.
  11. Cloudflare DNS-over-HTTPS · DNS record resolution for domain intelligence.
  12. RDAP · registration data (WHOIS) via the Registration Data Access Protocol. Keyless.
  13. Certspotter and crt.sh · certificate-transparency subdomain enumeration, both always consulted.
  14. Mnemonic passive DNS and HackerTarget reverse IP · historical and co-hosting host discovery. Keyless.
  15. GLEIF · the Global Legal Entity Identifier Foundation register, for registrant legal entity. Keyless.
  16. CIRCL hashlookup · known-software (NSRL) file-hash clearance and verdict.
  17. Pwned Passwords · keyless k-anonymity password-exposure check.
  18. Keyless identity APIs · GitHub, GitLab, Codeberg, Hacker News, Reddit, Bluesky, Mastodon, Chess.com, and Lichess, read for profile detail.
  19. US Treasury OFAC · the SDN sanctions list, shipped as a bundled offline snapshot of 1,056 addresses across 20 chains.
  20. Optional enrichment · IPQualityScore, NumVerify, AbstractAPI, Twilio Lookup, Hunter.io, EmailRep.io, FullContact, and BreachDirectory (RapidAPI), each used only when a key is configured.