{"id":50296121,"url":"https://github.com/ipanalytics/sat-geoip","last_synced_at":"2026-06-02T10:00:15.386Z","repository":{"id":360188178,"uuid":"1249079693","full_name":"ipanalytics/Sat-geoip","owner":"ipanalytics","description":"sat-geoip builds a satellite-internet intelligence dataset from operator GeoIP feeds, subnet-to-PoP mappings, live BGP announcements, RIR/RPKI ownership evidence, and historical snapshots.","archived":false,"fork":false,"pushed_at":"2026-05-28T07:02:56.000Z","size":2366,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T09:08:32.270Z","etag":null,"topics":["asn","bgp","eutelsat","geoip","hughesnet","intelsat","maxmind-db","o3b","oneweb","ripestat","routing","satellite-internet","ses","starlink","viasat"],"latest_commit_sha":null,"homepage":"https://ipanalytics.github.io/Sat-geoip/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ipanalytics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-25T10:29:35.000Z","updated_at":"2026-05-28T07:02:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ipanalytics/Sat-geoip","commit_stats":null,"previous_names":["ipanalytics/sat-geoip"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/ipanalytics/Sat-geoip","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipanalytics%2FSat-geoip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipanalytics%2FSat-geoip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipanalytics%2FSat-geoip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipanalytics%2FSat-geoip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ipanalytics","download_url":"https://codeload.github.com/ipanalytics/Sat-geoip/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipanalytics%2FSat-geoip/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33816488,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asn","bgp","eutelsat","geoip","hughesnet","intelsat","maxmind-db","o3b","oneweb","ripestat","routing","satellite-internet","ses","starlink","viasat"],"created_at":"2026-05-28T09:00:18.424Z","updated_at":"2026-06-02T10:00:15.378Z","avatar_url":"https://github.com/ipanalytics.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sat-geoip\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./site/banner.png\" alt=\"sat-geoip banner\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"./LICENSE\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-Apache%202.0-blue\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/ipanalytics/Sat-geoip/actions/workflows/dataset-release.yml\"\u003e\u003cimg alt=\"CI\" src=\"https://img.shields.io/github/actions/workflow/status/ipanalytics/Sat-geoip/dataset-release.yml?branch=main\u0026label=dataset\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/ipanalytics/Sat-geoip/releases\"\u003e\u003cimg alt=\"Release\" src=\"https://img.shields.io/github/v/release/ipanalytics/Sat-geoip?label=release\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"Dataset\" src=\"https://img.shields.io/badge/dataset-GeoIP%20%2B%20PoP%20%2B%20BGP-0f766e\"\u003e\n  \u003cimg alt=\"Go\" src=\"https://img.shields.io/badge/go-1.24-00ADD8\"\u003e\n\u003c/p\u003e\n\nhttps://ipanalytics.github.io/Sat-geoip/\n\nsat-geoip builds a satellite-internet intelligence dataset from operator GeoIP feeds, subnet-to-PoP mappings, live BGP announcements, RIR/RPKI ownership evidence, and historical snapshots. It emits CSV, JSONL, and MaxMind DB artifacts that keep geolocation, PoP assignment, PTR observations, and routing state as separate evidence layers.\n\n---\n\n## Links\n\n| Resource | Location |\n|---|---|\n| Interactive dashboard | [GitHub Pages](https://ipanalytics.github.io/Sat-geoip/) |\n| Latest dataset release | [GitHub Releases](https://github.com/ipanalytics/Sat-geoip/releases) |\n| Generated artifacts | [`outputs/`](./outputs) |\n| Operator registry | [`config/operators.yaml`](./config/operators.yaml) |\n| Example evidence | [`examples/acceptance_evidence.json`](./examples/acceptance_evidence.json) |\n\n## Overview\n\nSatellite networks do not map cleanly to conventional GeoIP assumptions. A customer subnet, a declared PoP, a reverse DNS hint, and a BGP origin are different facts with different failure modes. sat-geoip preserves those facts as separate fields and records the quality signals that connect or contradict them.\n\nThe pipeline is designed for data-engineering and infrastructure workflows:\n\n- ingest operator-published geofeeds and PoP maps;\n- correlate them with live BGP origin state;\n- retain explicit semantics for every derived field;\n- generate stable machine-readable artifacts for enrichment, routing analytics, and infrastructure inventories.\n\n## Architecture\n\n```mermaid\nflowchart LR\n  A[\"Operator GeoIP feeds\"] --\u003e E[\"Evidence model\"]\n  B[\"Operator PoP feeds\"] --\u003e E\n  C[\"RIPEstat BGP state\"] --\u003e E\n  D[\"RIR / RPKI / PTR layers\"] --\u003e E\n  E --\u003e R[\"Resolver\"]\n  R --\u003e J[\"sat-geoip-prefixes.jsonl\"]\n  R --\u003e C1[\"CSV reports\"]\n  R --\u003e M[\"sat-geoip.mmdb\"]\n  R --\u003e S[\"release statistics\"]\n```\n\nThe resolver applies fixed precedence rules:\n\n| Field | Winning source | Notes |\n|---|---|---|\n| Operator | live BGP origin, then RIR org match | ASNs are treated as a discovered set |\n| GeoIP | operator geofeed | customer-subnet location semantics |\n| PoP | official PoP feed | PTR is corroboration only |\n| Routing state | BGP collectors | geofeeds do not imply live routing |\n| Ground station claim | constant `false` | never inferred from GeoIP or PoP data |\n\n## Current Dataset\n\n\u003c!-- SAT_GEOIP_STATS_START --\u003e\n| Dataset metric | Count |\n|---|---:|\n| Prefixes | 11262 |\n| Announced prefixes | 7904 |\n| GeoFeed-only prefixes | 3358 |\n| BGP-only prefixes | 6977 |\n| Prefixes with PoP assignment | 3297 |\n| Ground station claims | 0 |\n\n### Operators\n\n| Name | Count |\n|---|---:|\n| `avanti` | 23 |\n| `eutelsat_skylogic` | 277 |\n| `hughes` | 675 |\n| `inmarsat` | 55 |\n| `intelsat` | 93 |\n| `marlink` | 29 |\n| `oneweb` | 17 |\n| `ses_o3b` | 22 |\n| `speedcast` | 106 |\n| `starlink` | 5432 |\n| `thuraya` | 10 |\n| `viasat` | 4523 |\n\n### Orbit Classes\n\n| Name | Count |\n|---|---:|\n| `geo` | 698 |\n| `geo_mss` | 10 |\n| `geo_or_hybrid_satellite` | 4855 |\n| `geo_or_multi_orbit` | 93 |\n| `leo` | 5449 |\n| `meo` | 22 |\n| `mixed_satellite` | 135 |\n\u003c!-- SAT_GEOIP_STATS_END --\u003e\n\nThe checked-in `outputs/` directory is generated from live public feeds. The example evidence fixture remains in the repository to exercise acceptance cases and deterministic tests.\n\n## Operator Coverage\n\n| Operator | Orbit | Service class | Evidence layers | GeoFeed |\n|---|---|---|---|---|\n| Starlink | LEO | `satellite_internet` | GeoIP feed, PoP feed, BGP, RIR/RPKI model | active |\n| Eutelsat OneWeb | LEO | `satellite_internet` | BGP, PeeringDB/RDAP/RPKI model, facility reference metadata | not found |\n| Viasat | GEO/hybrid | `satellite_internet` | GeoIP feed, BGP, RIR/RPKI model | active |\n| Inmarsat | GEO/hybrid | `satellite_internet` | BGP, RDAP/RPKI model | not found |\n| Thuraya | GEO MSS | `mss_narrowband` | BGP, RDAP/RPKI model | not found |\n| SES Networks / O3b | MEO | `satellite_internet` | BGP, PeeringDB/RDAP/RPKI model, gateway reference metadata | not found |\n| Hughes / HughesNet | GEO | `satellite_internet` | BGP, RDAP/RPKI model | not found |\n| Intelsat | GEO/multi-orbit | `satellite_internet` | BGP, PeeringDB/RDAP/RPKI model | not found |\n| Avanti Communications | GEO | `satellite_internet` | BGP, RDAP/RPKI model | not found |\n| Eutelsat / Skylogic | GEO/hybrid | `satellite_internet` | BGP, PeeringDB/RDAP/RPKI model | not found |\n| Marlink | mixed satellite | `satellite_service_provider` | BGP, PeeringDB/RDAP/RPKI model | not found |\n| Speedcast | mixed satellite | `satellite_service_provider` | BGP, PeeringDB/RDAP/RPKI model | not found |\n\n## Features\n\n- Go resolver with typed evidence and canonical resolved-prefix records.\n- Operator registry covering Starlink, OneWeb, Viasat, Inmarsat, Thuraya, SES/O3b, Hughes/HughesNet, Intelsat, Avanti, Eutelsat/Skylogic, Marlink, and Speedcast.\n- RFC 8805 geofeed parser and Starlink PoP CSV parser.\n- RIPEstat announced-prefix parser for live BGP state.\n- CSV, JSONL, and MaxMind DB outputs.\n- Release statistics in JSON and Markdown.\n- Static GitHub Pages dashboard generated from release outputs.\n- GitHub Actions workflow for scheduled dataset builds and release publishing.\n- Tests for the acceptance cases that guard field semantics and confidence separation.\n\n## Quick Start\n\n```sh\ngit clone https://github.com/ipanalytics/Sat-geoip.git\ncd Sat-geoip\ngo test ./...\ngo run ./cmd/sat-geoip -format release -evidence examples/acceptance_evidence.json -out outputs\n```\n\nBuild from live public sources:\n\n```sh\ngo run ./cmd/sat-geoip -format live-release -out outputs\n```\n\n## Installation\n\nsat-geoip is a standard Go module.\n\n```sh\ngo install ./cmd/sat-geoip\n```\n\nFor reproducible CI builds, use Go 1.24 or newer.\n\n## Usage\n\nGenerate resolved records from an evidence file:\n\n```sh\ngo run ./cmd/sat-geoip \\\n  -format jsonl \\\n  -evidence examples/acceptance_evidence.json\n```\n\nGenerate all release artifacts:\n\n```sh\ngo run ./cmd/sat-geoip \\\n  -format release \\\n  -evidence examples/acceptance_evidence.json \\\n  -out outputs\n```\n\nGenerate all artifacts from live public feeds:\n\n```sh\ngo run ./cmd/sat-geoip \\\n  -format live-release \\\n  -out outputs\n```\n\nUpdate the README statistics block from release stats:\n\n```sh\ngo run ./cmd/sat-geoip \\\n  -format update-readme-stats \\\n  -stats outputs/stats.json \\\n  -readme README.md\n```\n\n## Artifacts\n\n| File | Description |\n|---|---|\n| `sat-geoip-prefixes.jsonl` | Canonical resolved records, one prefix per line |\n| `sat-geoip-prefixes.csv` | Flattened resolved-prefix table |\n| `sat-geoip.mmdb` | MaxMind DB for prefix lookups |\n| `satellite-asns.csv` | Operator ASN seed registry |\n| `operator-geofeeds.csv` | Known operator feed URLs and formats |\n| `operator-gateway-reference.csv` | Gateway country reference metadata; not customer GeoIP |\n| `prefix-changes.jsonl` | Per-prefix change events compared with the previous committed output |\n| `prefix-changes.csv` | Flattened change event table |\n| `history-summary.json` | Release-level history counters |\n| `starlink-geoip-vs-bgp.csv` | Starlink geofeed and BGP comparison |\n| `starlink-pop-mapping.csv` | Starlink prefix-to-PoP mapping |\n| `pops-vs-ptr-mismatch.csv` | PTR/PoP disagreement report |\n| `stats.json` | Machine-readable release statistics |\n| `RELEASE_NOTES.md` | Markdown body for GitHub Releases |\n\n## Data Format\n\nCanonical JSONL records follow the resolved-prefix schema:\n\n```json\n{\n  \"prefix\": \"14.1.64.0/24\",\n  \"operator\": \"starlink\",\n  \"operator_group\": \"spacex\",\n  \"service_type\": \"satellite_internet\",\n  \"orbit_class\": \"leo\",\n  \"origin_asn\": 45700,\n  \"origin_as_name\": \"IDNIC-STARLINK-AS-ID\",\n  \"geoip_country\": \"PH\",\n  \"geoip_city\": \"Manila\",\n  \"geoip_source\": \"starlink_feed_csv\",\n  \"geoip_semantics\": \"customer_subnet_geoip_location\",\n  \"pop_code\": \"mnlaphl1\",\n  \"pop_iata\": \"mnl\",\n  \"pop_source\": \"starlink_pops_csv\",\n  \"bgp_state\": \"announced\",\n  \"ground_station_claim\": false,\n  \"active_user_claim\": true,\n  \"quality_flags\": [\"geoip_valid\", \"bgp_announced\", \"origin_asn_expected\"],\n  \"data_confidence\": {\n    \"attribution\": 0.997,\n    \"geo\": 0.85\n  }\n}\n```\n\n`data_confidence.attribution` and `data_confidence.geo` are intentionally separate. Attribution answers whether a prefix belongs to the operator set. Geo confidence answers whether the declared location label is internally consistent.\n\n## Reference Validation Data\n\nThe pipeline includes local reference datasets under [`data/reference`](./data/reference):\n\n| Source | Use |\n|---|---|\n| GeoNames `countryInfo`, `admin1CodesASCII`, `cities1000` | country, subdivision, and city-country validation |\n| OurAirports `airports.csv` | IATA airport code to country validation |\n\nThese files are validation references, not GeoIP sources. They improve quality flags such as `geoip_invalid_country_city_pair` and support PoP/gateway sanity checks without overriding operator-published geofeed semantics.\n\n## Operational Notes\n\n- Scheduled releases run from GitHub Actions and publish a date-tagged dataset release.\n- Live builds fetch public operator feeds and RIPEstat Data API responses.\n- Release jobs update `README.md`, `outputs/`, and the GitHub Release body with dataset statistics.\n- `first_seen`, `last_seen`, `changed_at`, and `change_type` are repository snapshot history fields. They describe when sat-geoip first observed or changed a record, not when the operator originally allocated or routed the prefix.\n- Prefix change reports compare the current build against the previously committed `sat-geoip-prefixes.jsonl` artifact.\n- Raw snapshot retention is part of the long-term roadmap; current checked-in outputs represent the latest generated release artifact set.\n- The resolver keeps evidence layers separate by design. Consumers should select the field appropriate to their workflow instead of collapsing fields into a single location.\n\n## Use Cases\n\n- satellite ISP prefix enrichment in network inventory systems;\n- comparing operator-declared GeoIP data with live BGP announcements;\n- tracking Starlink PoP assignment changes;\n- generating MMDB enrichment files for edge and analytics pipelines;\n- auditing feed consistency across country, city, PoP, and origin-AS layers.\n\n## Scope\n\nsat-geoip covers satellite-internet data engineering: operator feeds, BGP state, ownership evidence, PoP mappings, release artifacts, and historical change tracking. It does not score users, reputation, abuse, anonymity, or risk.\n\n## Limitations\n\n- Live BGP collection currently uses RIPEstat REST APIs, not MRT/RIS-Live streams.\n- PTR and RPKI enrichment are represented in the model but not fully collected in the first release pipeline.\n- OneWeb/Eutelsat and most non-Starlink/Viasat operators are BGP-derived until public operator geofeeds are found.\n- SES/O3b, Hughes, Marlink, Intelsat, Avanti, Speedcast, Inmarsat, and Thuraya are BGP-derived in the first release because no public RFC 8805 geofeed is known for those operators.\n\n## Directory Structure\n\n```text\n.\n├── cmd/sat-geoip/              # CLI entry point\n├── config/                    # operator registry\n├── data/reference/            # validation-only GeoNames and OurAirports datasets\n├── examples/                  # acceptance evidence fixtures\n├── internal/collectors/       # feed and BGP collector helpers\n├── internal/export/           # CSV and JSONL writers\n├── internal/history/          # per-prefix snapshot history and change reports\n├── internal/live/             # live public-source dataset builder\n├── internal/mmdb/             # MaxMind DB writer\n├── internal/release/          # artifact and statistics generation\n├── internal/resolver/         # core evidence resolution engine\n├── internal/validators/       # RFC 8805 and PoP parsers\n├── outputs/                   # generated dataset artifacts\n└── site/                      # README assets\n```\n\n## Deployment\n\nThe repository includes a scheduled GitHub Actions workflow:\n\n```text\n.github/workflows/dataset-release.yml\n```\n\nIt runs tests, builds live release artifacts, updates README statistics, commits generated files, and publishes a GitHub Release containing the dataset files.\n\nManual release:\n\n```sh\ngh workflow run dataset-release.yml\n```\n\n## License\n\nsat-geoip is licensed under the [Apache License 2.0](./LICENSE).\n\n## Disclaimer\n\nsat-geoip publishes derived infrastructure data from public sources. Operator feeds and public BGP APIs can be incomplete, delayed, or internally inconsistent; downstream systems should preserve the source semantics included in each record.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipanalytics%2Fsat-geoip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fipanalytics%2Fsat-geoip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipanalytics%2Fsat-geoip/lists"}