Skip to content

Add local GeoLite provider and checked-IP Geo inputs for Axum - #453

Draft
ChristianPavilonis wants to merge 3 commits into
feature/pluggable-geo-providersfrom
feature/axum-local-geoip
Draft

ChristianPavilonis wants to merge 3 commits into
feature/pluggable-geo-providersfrom
feature/axum-local-geoip

Conversation

@ChristianPavilonis

@ChristianPavilonis ChristianPavilonis commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add an optional, local GeoLite City/Country provider for ordinary Axum deployments, independent of CloudFront and paid services.
  • Reuse the existing Geo selection/outcome architecture with private checked-reader-IP provenance, read-only startup snapshots and restart-based replacement.
  • Blocked draft, not completed Axum: follow up with an explicit local GeoIP provider #438 acceptance. The pinned reader accepts some malformed unused metadata. The defect is reproduced and retained as an explicitly ignored regression. Do not merge as a fully validated provider.

Stacked on #439. Base is feature/pluggable-geo-providers, not main.

Changes

Crate / File Change
edgezero-core/src/geo.rs Typed assertion/reader inputs, address-redacted Debug, checked-IP provenance, no-match/missing-reader outcomes, reserved maxmind ID. Coordinated breaking pre-release API migration.
edgezero-adapter-axum/src/geo* Default-off geo-maxmind, pinned maxminddb 0.32.0, finite preparation bounds, upstream verification plus strict reachable-data structural traversal, geographic projection, immutable reader and supplied-IP composition.
Axum service/options/runner Capture IP from runner-owned checked ingress before public extensions; resolve once after admission; pure capability inspection; safe snapshot logging after logging initializes.
Geo tests and synthetic fixtures 26 reproducible original Apache-2.0 MMDB fixtures; IPv4/IPv6, proxy expectations, corruption/limits, real startup, refusal/abort/drain counts, read-only file access, replacement/deletion and restart proof.
Guide/changelog/workflows/scripts Free-data licensing and update duties, direct/proxy examples, migration guidance, four isolated feature lanes, dependency isolation and fixture reproduction checks.
docs/superpowers/ Reviewed spec, full implementation plan, decisions, verification record and remaining acceptance work.

No downloader, remote IP lookup, provider fallback, hot reload, store binding, consent interpretation or permission-policy change is introduced. The running application needs no MaxMind credentials. Defaults are 128 MiB of input and 32 million validation network visits, not an I/O deadline or RSS quota. Preparation remains synchronous before runtime signal registration and embedding-stop polling, as specified.

Closes

Tracks #438. Intentionally does not claim closure while the acceptance blockers below remain.

Test plan

Tested Rust/runtime implementation commit: 9dd7b83b, Rust/Cargo 1.95.0 on Linux. Follow-up commits update the plan and fix comma-free CI cache IDs, without changing runtime inputs. Full commands, feature sets, timings and local evidence references are in the plan.

The first combined-feature GitHub job failed before compilation because Actions cache keys reject commas. Commit 633f0552 replaces raw feature strings with safe matrix cache IDs. An old-versus-new regression check, actionlint and scoped Prettier pass locally; GitHub checks for the follow-up remain pending.

  • cargo test --locked --workspace --all-targets: 2,121 passed, 6 existing ignored.
  • Native --all-targets --all-features: 447 passed, 1 known failing metadata acceptance regression explicitly ignored.
  • Isolated axum, CloudFront-only, MaxMind-only and combined lanes: full library tests, real Geo hosting, seven doc tests per lane, all-target Clippy. Reader lanes retain the same known ignored regression.
  • cargo clippy --locked --workspace --all-targets --all-features -- -D warnings.
  • cargo fmt --all -- --check, whitespace, fixture reproduction and actionlint. Actionlint ran without ShellCheck.
  • Workspace platform-feature compilation plus minimal/bindings-only native checks.
  • Fastly/Cloudflare/Spin WASM builds and 88 runtime dispatch contract tests: 24 under Viceroy 0.21.0, 29 under wasm-bindgen-test-runner 0.2.128, 35 under Wasmtime 48.0.2.
  • Geo and native-store isolated dependency scripts; workspace rustdoc with warnings denied.
  • examples/app-demo: 54 tests passed. Both excluded-workspace lockfiles remain unchanged and pass offline/locked checks.
  • Docs lint, formatting and site build.
  • Real-runner reproduction of the metadata blocker. A supported fixture with malformed unused metadata currently reaches readiness.
  • Production-size licensed GeoLite preparation time/RSS and compatibility measurement.
  • Actual read-only mount and unprivileged permission-denied runtime proof. Existing tests use read-only file/directory modes and check source independence/no sidecars.

One earlier MaxMind-only hosting run hit the existing ephemeral reservation-to-child-bind race. The identical suite passed on rerun, then all four isolated lanes and final native integration passed. No production retry or arbitrary port policy was added.

Acceptance blockers and limitations

  1. Malformed unused metadata is accepted. Reader::verify() accepts nested non-string keys and pointer chains in unknown metadata; its public API exposes no raw metadata decoder. Our strict structural pass closes the reachable-data-record cases, not metadata. geo_maxmind_rejects_unused_metadata_nonstring_keys -- --ignored fails as expected. Fix the reader boundary and add real-runner rejection before removing the ignore, or obtain explicit approval to change the contract. This is not consent-policy acceptance.
  2. Acquisition is currently Unix-only. Non-Unix selection returns UnavailableMaxMind during pure capability validation. Equivalent safe acquisition elsewhere is not implemented; the narrower scope requires acceptance or implementation work.
  3. Production data was not obtained or benchmarked. Tiny synthetic tests and published vendor size ranges do not prove production capacity or state-level accuracy.
  4. Consent/jurisdiction policy, cache configuration, Trusted Server translation and real downstream policy-path proof remain separate application work.

Checklist

  • Changes follow repository conventions; independent source review completed and concrete findings recorded.
  • No new Tokio dependency or native reader/filesystem dependency in portable core/platform graphs.
  • Route params use brace syntax; application HTTP types use core exports.
  • No Geo store registry or legacy store-handle wiring added.
  • New behavior has unit and real-hosting tests; remaining failing acceptance case is explicit.
  • No production database, download credentials or secrets committed.
  • All approved Axum: follow up with an explicit local GeoIP provider #438 acceptance criteria satisfied. This PR must remain draft.

ChristianPavilonis added a commit that referenced this pull request Nov 4, 2026
Preserve RC startup, JSON limits, admitted-error finalization and dependency pins while integrating checked-reader GeoIP composition. Adapt SHA encoding and Rust 1.98.1 bounds; retain the documented metadata acceptance blocker.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant