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.
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.
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 rationaleContributions
- A single console over seven identifier types with a cross-identifier auto-pivot engine that never synthesises an identifier and separates confirmed links from candidates.
- An accuracy discipline enforced in code: username identity fused only on proof, sanctions results scoped honestly, ambiguous data labelled as such, and unresolved fields left blank rather than filled with a plausible default.
- A keyless-first source strategy, 25+ of 34+ sources need no key, with large offline datasets and graceful degradation that keeps a lookup useful when a source is down or throttled.
- A hardened, fully tested implementation: keys isolated server-side, no-SSRF input validation into fixed hosts, and a 100 percent coverage gate over every route including the outbound proxy.
- A body of engineering decisions, documented here, where the correct-but-harder choice was taken over the impressive-looking one, from reading a sanctions list out of XML to proving a cross-platform identity by pixels rather than by a shared handle.
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.
| Mode | What it does |
|---|---|
| Phone | Carrier, type, NPA geo, two separate scores, pivots, QR, report |
| Unified breach view, password exposure, reputation, identity, validation | |
| Username | 38+ sites in parallel, plus a 242+ site deep sweep on request |
| IP | Geo, ASN, ISP, reverse DNS, VPN/proxy/hosting flags, exposure, risk score |
| Domain | DNS, WHOIS, SPF/DMARC, subdomains, HTTP/TLS posture, legal entity |
| Wallet | OFAC SDN screening, BTC activity and counterparties, ERC-20 holdings, ENS |
| Hash | File-hash reputation (CIRCL / NSRL) plus an offline crypto workbench |
| File | Deep metadata from ~70 formats, parsed in the browser, never uploaded |
| Bulk | Up to 500 mixed identifiers as a cancellable job with per-row provenance |
| Graph | Link-analysis graph of the session, or of any saved case |
| Cases | Persistent 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.
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.
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.
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.
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.
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, 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.
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.
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.
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.
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.
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.
- Phone is always accurate because it is offline. Country, validity, line type, timezone, and formats come from libphonenumber and bundled data with no API in the loop. An ambiguous fixed-line-or-mobile type is shown as ambiguous, never claimed as one or the other, and an area code is extracted only for US and Canada, where a real NPA database exists, because guessing a variable-length code elsewhere would fabricate data.
- A username is FOUND only on proof. The sites that answer for every handle are never auto-claimed; they are flagged for manual verification. A nonexistent handle yields zero false positives, which is regression-tested, and identity is fused across platforms only on a self-link or a server-side perceptual avatar match, everything else stays a labelled candidate.
- IP location is ISP-level, and says so. Hosting, VPN, and proxy addresses mask the real user, so the tool surfaces those flags rather than pretending the location is the person, and a provider that publishes no proxy or hosting flags returns a null rather than a fabricated false.
- Domain data is reported as upstream returns it. DNS, WHOIS, and subdomain data is exactly what the resolvers give back; an empty section means not resolved, never fabricated, and WHOIS depth depends on the TLD's RDAP support.
- A sanctions miss is scoped, not cleared. A negative screen says "not on this list," never "clean," and the tool names which list it checked so the absence can be read correctly.
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.
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.
| Control | What it does |
|---|---|
| API-key isolation | Every 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 SSRF | Every lookup validates its input and only URL-encodes it into fixed upstream hosts, so a caller can never choose the destination. |
| Content-Security-Policy | default-src self, connect-src self, object-src none, frame-ancestors none, with a narrowed image allow-list. |
| Security headers | X-Frame-Options DENY, nosniff, Referrer-Policy, a Permissions-Policy that blocks geolocation, camera, mic, payment, and USB, plus cross-origin isolation headers. |
| No tracking | Metadata from structure and public databases only; no device tracking, analytics, or telemetry. |
| Rate limiting | 60 requests per minute per client plus a server-wide ceiling, fixed-window, every limit environment-tunable. |
| Optional case lock | A single shared secret seals the case store behind an HMAC-signed token cookie, with constant-time comparison and instant invalidation on rotation. |
| Audit trail | Every 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.
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.
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.
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.
Where GeoIntel Goes Next
Near term
- Grow the keyless source set and the offline datasets as new free intelligence sources appear, keeping the zero-key experience as capable as possible.
- Extend the deep-sweep username coverage and the number of platforms read through a keyless public API, so more accounts resolve to a real identity rather than a bare existence check.
- Widen the change-tracking inbox and webhook so continuous monitoring of an identifier becomes a first-class workflow, not just a manual re-run.
Medium term
- Deepen wallet intelligence beyond the fixed token list where a keyless path allows it, and broaden sanctions coverage past the single SDN list, without ever substituting a made-up answer for a real one.
- Broaden perceptual matching and self-link detection to raise the confidence of cross-platform identity fusion while keeping the same conservative standard of proof.
- Expand the export formats and the case dossier so the output slots into more downstream intelligence and reporting pipelines.
Longer term
- Formalise the accuracy discipline into a documented confidence model, so every asserted link and score carries a stated, testable basis.
- Explore tighter integration with the wider HEAVEN toolset so an OSINT case can feed directly into an authorised assessment.
- Keep the guiding rule fixed as the tool grows: real, derivable data or nothing, and never a fact about a person the tool cannot show the source for.
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.
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.
- libphonenumber-js · Google's libphonenumber compiled to JavaScript, for offline phone parsing and validation.
- Hudson Rock Cavalier · infostealer-malware exposure for phone, email, and username. Free, no key.
- XposedOrNot · breach database (1000+ databases), also a vendored offline catalog tier. Free, no key.
- LeakCheck (public index) · named breaches and exposed field types. Free, no key.
- Have I Been Pwned · per-account breaches unioned into the breach view, and a vendored offline catalog tier. Optional paid key.
- ProxyNova COMB · masked password-exposure evidence with a reuse verdict.
- Gravatar · avatar and profile resolution for email and username.
- ip-api.com and ipwho.is · IP geolocation with automatic failover. Free.
- Shodan InternetDB · open ports and known CVEs for an IP or a domain's own addresses. Free, no key.
- GreyNoise · internet-scanner classification, folded into IP risk. Free tier.
- Cloudflare DNS-over-HTTPS · DNS record resolution for domain intelligence.
- RDAP · registration data (WHOIS) via the Registration Data Access Protocol. Keyless.
- Certspotter and crt.sh · certificate-transparency subdomain enumeration, both always consulted.
- Mnemonic passive DNS and HackerTarget reverse IP · historical and co-hosting host discovery. Keyless.
- GLEIF · the Global Legal Entity Identifier Foundation register, for registrant legal entity. Keyless.
- CIRCL hashlookup · known-software (NSRL) file-hash clearance and verdict.
- Pwned Passwords · keyless k-anonymity password-exposure check.
- Keyless identity APIs · GitHub, GitLab, Codeberg, Hacker News, Reddit, Bluesky, Mastodon, Chess.com, and Lichess, read for profile detail.
- US Treasury OFAC · the SDN sanctions list, shipped as a bundled offline snapshot of 1,056 addresses across 20 chains.
- Optional enrichment · IPQualityScore, NumVerify, AbstractAPI, Twilio Lookup, Hunter.io, EmailRep.io, FullContact, and BreachDirectory (RapidAPI), each used only when a key is configured.