Echolot delegates identity to whatever IdP the operator already runs and stores no passwords - no hashing, no reset flow, no lockout policy, and no credential database to lose. For a tool people self-host next to other services, that is the difference between one more service and one more thing that can leak someone's password. Verification is stdlib-only, matching the server's no-dependency rule. Longer than jwt.Parse, and auditable in one sitting. The part that matters is the algorithm allow-list: taking `alg` from the token is the classic forgery, so it is fixed in code. Tests cover the real attacks against a genuine signer - a self-contained IdP with real keys, because a mock that returns success proves nothing about a verifier: alg=none, HS256/RS256 confusion, a payload swapped under a valid signature, a token addressed to another client, a token from another issuer, expired and future-dated tokens, and discovery that renames the issuer (which would otherwise have us fetch a stranger's keys believing they were the provider's). With no admin group configured nobody is an admin. An operator who has not said who may administer the server has not thereby said "anyone who can log in". Device and account stay separate concepts: enrollment admits a device (operator's token), signing in attributes it to a person (POST /v1/account/link, device credential plus ID token - both required, neither substitutes). uploads=account now means what it says instead of refusing everyone, and signing in does not override uploads=off. The profile advertises the sign-in configuration so the app can offer the button only when there is something behind it, and drive PKCE without anyone typing an issuer URL. A discovery failure is reported rather than hidden, so "configured but the provider is not answering" is distinguishable from "not configured". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Echolot
Free software for detecting and debugging local network issues from an Android phone — built for people who actually know what a neighbor table is.
Most "wifi analyzer" apps show you signal bars. Echolot aims at the layer where home and office networks actually break: duplicate DHCP servers, broken IPv6 RAs, MTU black holes, NAT64 weirdness, multicast that dies at the AP, DNS that answers differently than it should. It records what it observed, separates observation from interpretation, and exports the whole run so you can argue with it later.
Status: pre-release. The capability prober runs on real hardware; the production app and the probe server are not built yet.
Repository layout
docs/ design docs — the contract for everything below
echolot-prober/ capability prober: validates the no-root feasibility matrix on real devices
The Go probe server and the production app land here as siblings.
Design docs
The three specs are draft-complete and reviewed; treat them as the contract.
| Doc | What it defines |
|---|---|
| docs/feature-catalog-and-feasibility.md | Full feature list + the no-root feasibility matrix |
| docs/measurement-schema.md | Archived/exportable measurement JSON (observation vs finding, two-clock rule, anonymization) |
| docs/probe-protocol.md | Client↔server wire protocol (pinned TLS control plane, binary UDP data plane, STUN, canary DNS) |
| docs/build-status.md | Running log of decisions and next steps |
Privilege tiers
Every result records which tier produced it:
app— no root, no special setup. The bulk of the functionality.shizuku— ADB-shell privileges via wireless pairing, no root. Shipped in v1.root— future optional module.
Licensing
| Part | License | Why |
|---|---|---|
| All code (app, prober, server) | GPL-3.0-or-later | The value here is the platform-API research; copyleft keeps derivative apps free |
docs/ (the specs) |
CC-BY-4.0 | A wire protocol and a measurement format should be implementable by anyone, without license anxiety |
Full texts: LICENSE (GPLv3) and docs/LICENSE (CC BY 4.0).
Sources carry SPDX-License-Identifier headers.
If you want to build a compatible server or client, the protocol and schema docs are deliberately permissive — go ahead.
Building
See echolot-prober/README.md. Short version, from echolot-prober/:
echo "sdk.dir=/path/to/Android/sdk" > local.properties
./gradlew :app:assembleDebug