Repository navigation
feat(health): watch the public ingest path from the Pi tick, without an Access token - #139
Conversation
…an Access token The scheduled probe only asked the dashboard /healthz over the LAN, so everything Cloudflare adds was unwatched: a `docker compose up -d` without the deploy environment blanks CLOUDFLARE_TUNNEL_TOKEN and drops public ingest while the LAN probe stays green, and every agent then exports spans into a hole silently. probe-edge-ingest.sh asks https://otlp.aignite.pl/v1/traces and expects exactly HTTP 401. The ingest host is not behind Access, so the request reaches cotel's own auth middleware, and only a working chain can answer 401: DNS, the tunnel, the process, and the /v1/traces route. The bearer is a deliberately invalid cotel_ token rather than absent, so the expectation holds whichever way allow_anonymous is set. No credential is needed, which is what the runbook got wrong: it claimed a meaningful edge check had to wait for an Access service token to be allowed on cotel.aignite.pl. The pager learns PC_ALERT_SUBJECT and PC_ALERT_LEAD, defaulting to the strings it already sent. Without them a second watcher mints an alert whose title and wake reason claim production /healthz is red, which points the reader at the wrong half of the system; the ingest alert instead says the application is alive and names the tunnel and DNS as what to look at. Co-Authored-By: Wayland <wayland@agents.flopbut.local> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (6)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe pull request adds a probe for public OTLP ingest, enables configurable alert wording, and updates the health-probe documentation to describe scheduled LAN and edge checks. ChangesHealth probe and alerting
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Merge Risk: ⚪ Minimal · up to This change adds a public-ingest health check and lets alerts name the service being watched. Existing alert wording stays the same by default. No established defect blocks merging. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The new check uses no real credential by default and cannot write spans. Risk is limited to monitoring assurance: its accepted response does not uniquely identify the intended application, and the production watcher’s deployment and recovery behavior remain unverified. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 4 files. (2 skipped: 2 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What this fixes
The scheduled probe only asked the dashboard
/healthzon robmini over the LAN, so everything Cloudflare adds was unwatched. That is not theoretical:docker compose up -dwithout the deploy environment blanksCLOUDFLARE_TUNNEL_TOKENand drops public ingest while the LAN/healthzstays green. Every agent then exports spans into a hole and keeps working silently — the exact silence the probe was built to end.The runbook said a meaningful check from outside the LAN had to wait for an Access service token to be allowed on
cotel.aignite.pl. It does not. Measured:The ingest host is not behind Access, and that 401 proves the whole chain: DNS, the tunnel, the process, and
/v1/tracesbeing routed.What changed
scripts/probe-edge-ingest.sh(new) — askshttps://otlp.aignite.pl/v1/tracesand expects exactly 401, not 200 and not "any answer" (a Cloudflare interstitial would otherwise pass as health). It sends a deliberately invalidcotel_bearer rather than no bearer, so the expectation holds whichever wayallow_anonymousis set; with anonymous ingest allowed a tokenless request would reach the handler and answer 405.GET, so a bypassed auth check could not write anything. Exit codes:0handler 401,1unreachable,2answered but not the handler's 401,4Access now fronts the ingest host.scripts/page-cotel-health.sh— learnsPC_ALERT_SUBJECTandPC_ALERT_LEAD, both defaulting to the strings it already sent. The dedup marker is machine-facing; without its own subject a second watcher mints an alert whose title and wake reason claim production/healthzis red, sending the reader to the wrong half of the system.scripts/probe-edge-ingest_test.sh(new) + 4 cases in the pager test, wired into thetestjob and the push path filter.docs/operations/health-probe.md— the vantage-point table now carries both scheduled halves, the "needs an Access token to be worth having" claim is corrected, and the new half, its exit codes, the apart-classification rule and its drill recipe are documented.Not in this repo (host side, sanctioned under this probe):
~/ops/cotel-healthz.shruns both halves per tick with separate streak files (state,state-edge), separate dedup markers ([cotel-health-probe],[cotel-ingest-edge]), its own--half local|edgeselector, and the alert strings above. No GitHub Actions schedule is revived — GitHub dropped eight of nine ticks, systemd does not.Two deliberate asymmetries. While the LAN half is red the edge half does not page: a dead process makes the public path unreachable as a consequence, and a second alert would send its reader hunting Cloudflare for a dead container. The edge streak keeps counting through the suppression, so it pages on the next tick if the process returns and the public path does not. And a probe script that is not at the materialization ref is reported as "that half is not deployed" rather than failing the unit — the LAN half must not go dark because the other half has not landed, and the new half starts running by itself on the first tick after this merges.
How it was verified
All on the Pi, against
origin/flo-1005-edge-ingest-probeas the materialization ref, so the realgit showpath was exercised:probe-healthz: OK — HTTP 200 ingest age 43sandprobe-edge-ingest: OK — HTTP 401 from the ingest handler,--probe-onlyexit 0.probe-edge-ingest: FAILED — public ingest unreachable (connection refused), exit 1.not paging: the LAN /healthz half is red too, and its alert covers thisand created nothing; the streak still advanced.cotel public ingest at … is red [cotel-ingest-edge-drill], whose body leads with "The application is alive; its public ingest path is not" and points at the tunnel and DNS. Then the green half routed its close. Drill streaks were left at their true value (0).🤖 Generated with Claude Code
Summary by CodeRabbit