Skip to content

feat(maintenance): add authenticated close actions and logs#5525

Closed
magrathean-uk wants to merge 7 commits into
teslamate-org:mainfrom
magrathean-uk:feature/operations-center
Closed

feat(maintenance): add authenticated close actions and logs#5525
magrathean-uk wants to merge 7 commits into
teslamate-org:mainfrom
magrathean-uk:feature/operations-center

Conversation

@magrathean-uk

@magrathean-uk magrathean-uk commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds one authenticated Maintenance page for two opt-in operator tasks:

  • close eligible, long-running open drives and charging sessions without deleting records
  • inspect a bounded rotating file-log tail for support

The page also shows validated image build identity so a support log can be tied back to the exact source, ref and revision.

This intentionally does not add a second health endpoint, a runtime collector, a duplicate data-health inbox or a top-level navbar item. The page is linked from Settings, and open-session queries run only when maintenance actions are explicitly enabled.

Issue coverage

Why these parts are together

The remaining pieces share one small operator workflow and one security boundary. Close actions and log access both need an explicitly enabled, authenticated Maintenance page; build identity makes the log output actionable during support. Keeping them together avoids separate routes, auth configuration and repeated UI/documentation, while the commits remain split by concern if maintainers want any part separated.

Safety and privacy

  • Both capabilities default to disabled.
  • Enabling either requires a non-empty Basic Auth username and password at startup.
  • Maintenance responses use Cache-Control: no-store.
  • Candidate queries are bounded to the oldest 200 sessions and run only when actions are enabled.
  • A close action locks and rechecks the exact record, requires a known inactive vehicle state, and uses existing TeslaMate completion logic.
  • The action never deletes a record. Drives with insufficient position data remain unchanged.
  • The active log is limited to 5 MB with three compressed rotations; the UI reads at most 256 KB or 500 lines.
  • Known credentials, token collections, backseat tokens and VINs are redacted before persistence and again before display, including escaped structured log values.

Verification

  • MIX_ENV=test mix ci: 411 tests passed
  • mix dialyzer: 0 errors
  • Docusaurus production build passed
  • Production Docker image built and ran as nonroot:nonroot on PostgreSQL 18
  • Browser checked at 1440x900 and 390x844
  • /health_check: 200
  • /maintenance without credentials: 401 with Basic Auth challenge and no-store
  • /maintenance with credentials: 200 with no-store
  • Production log-tail check confirmed VIN and token redaction
  • Production close-action check failed closed when vehicle activity was unavailable and left the disposable database row unchanged

All database and browser verification used disposable local containers.

Copilot AI review requested due to automatic review settings July 18, 2026 15:33
@netlify

netlify Bot commented Jul 18, 2026

Copy link
Copy Markdown

Deploy Preview for teslamate ready!

Name Link
🔨 Latest commit 0697ae2
🔍 Latest deploy log https://app.netlify.com/projects/teslamate/deploys/6a5baa2601bb56000865f0d4
😎 Deploy Preview https://deploy-preview-5525--teslamate.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@magrathean-uk

Copy link
Copy Markdown
Contributor Author

Hi @JakobLichterfeld, when you have time, could you take a look at the scope and safety model here? It covers the close-action part you outlined in #4850, and includes runtime health, build info and bounded logs because they share the same operations and authentication path. I would really value reviewing it as one workflow first, since the support flow is incomplete if only one part lands. If you would prefer separate PRs after that, the commits are already split by concern. I could not assign labels from the fork, but area:teslamate, enhancement and possibly docker look like the closest matches.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new “operations/maintenance” surface that consolidates runtime diagnostics (build provenance + runtime health), optional bounded file-log access, and optional guarded maintenance actions for safely closing long-running open sessions. It also adds a versioned /api/health endpoint for aggregate runtime health reporting.

Changes:

  • Add a new Maintenance LiveView (operations center) with build info, runtime health, data-health findings, optional log tail, and optional close actions.
  • Introduce TeslaMate.RuntimeHealth and wire it into vehicles/stream/MQTT to expose aggregate health via GET /api/health.
  • Add build metadata injection (Docker + GitHub Actions) and optional rotating redacted file logging with a bounded tail reader.

Reviewed changes

Copilot reviewed 65 out of 65 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
website/sidebars.js Adds docs entries for runtime health and operations page.
website/docs/maintenance/operations.md Documents the operations/maintenance UI, auth boundary, logs, and close actions.
website/docs/configuration/runtime-health.md Documents the /api/health endpoint contract and caching/HTTP semantics.
website/docs/configuration/environment_variables.md Documents new env vars for file logging and maintenance actions/auth.
test/teslamate/runtime_health_test.exs Adds unit tests for runtime health collection, redaction, and aggregation.
test/teslamate/mqtt/pubsub/vehicle_subscriber_test.exs Extends subscriber tests for reconnect snapshot republish behavior.
test/teslamate/mqtt/handler_test.exs Tests MQTT handler reporting into runtime health without leaking details.
test/teslamate/maintenance_test.exs Tests safe close logic for eligible drives/charging sessions.
test/teslamate/log_redactor_test.exs Tests log redaction of common secret shapes.
test/teslamate/file_log_test.exs Tests rotating file log installation + bounded, redacted tail reads.
test/teslamate/data_health_test.exs Tests data-health report for long-running open sessions and truncation.
test/teslamate/build_info_test.exs Tests build metadata validation/normalization/log-line formatting.
test/teslamate_web/plugs/operations_auth_test.exs Tests Basic Auth boundary for sensitive operations + fail-closed config.
test/teslamate_web/live/maintenance_live_test.exs End-to-end LiveView tests for diagnostics, logs, and close actions.
test/teslamate_web/controllers/health_controller_test.exs Tests /api/health aggregate response + legacy /health_check.
test/tesla_api/stream_test.exs Tests stream liveness events emitted separately from data receiver.
test/support/mocks/vehicles.ex Extends VehiclesMock with summary/2 + mutable summary state.
test/support/mocks/api.ex Adds arity-4 stream mock support (opts) for liveness receiver.
priv/gettext/tr/LC_MESSAGES/default.po Updates gettext references/strings for Maintenance/Operations UI.
priv/gettext/nl/LC_MESSAGES/default.po Updates gettext references/strings for Maintenance/Operations UI.
priv/gettext/nb/LC_MESSAGES/default.po Updates gettext references/strings for Maintenance/Operations UI.
priv/gettext/ja/LC_MESSAGES/default.po Updates gettext references/strings for Maintenance/Operations UI.
priv/gettext/fi/LC_MESSAGES/default.po Updates gettext references/strings for Maintenance/Operations UI.
priv/gettext/en/LC_MESSAGES/default.po Updates gettext references/strings for Maintenance/Operations UI.
priv/gettext/da/LC_MESSAGES/default.po Updates gettext references/strings for Maintenance/Operations UI.
priv/gettext/ca/LC_MESSAGES/default.po Updates gettext references/strings for Maintenance/Operations UI.
priv/gettext/default.pot Adds new msgids for Maintenance/Operations UI.
lib/teslamate/vehicles/vehicle.ex Records summary/API/stream health into RuntimeHealth; adds stream liveness receiver; records termination.
lib/teslamate/mqtt/pubsub/vehicle_subscriber.ex Republishes retained snapshot after broker reconnect; reports publish health to RuntimeHealth.
lib/teslamate/mqtt/handler.ex Records MQTT connection state transitions into RuntimeHealth.
lib/teslamate/mqtt.ex Passes runtime health dependency into the MQTT handler init state.
lib/teslamate/maintenance.ex Implements safe, opt-in close actions for eligible long-running sessions.
lib/teslamate/log.ex Adds delete_invalid option to avoid deleting drives when close is requested.
lib/teslamate/log_redactor.ex Implements defense-in-depth redaction for common secret shapes.
lib/teslamate/import/fake_api.ex Adds arity-4 stream/4 to match updated API streaming signature.
lib/teslamate/file_log.ex Implements rotating file logger install + bounded tail reader with redaction.
lib/teslamate/data_health.ex Implements read-only long-running open session report with truncation.
lib/teslamate/build_info.ex Implements validated build provenance/identity extraction and logging.
lib/teslamate/application.ex Installs file logging; logs build metadata; starts RuntimeHealth.
lib/teslamate/api.ex Adds streaming overloads to pass liveness receiver through to TeslaApi.Stream.
lib/teslamate_web/templates/layout/root.html.heex Adds navbar entry for the maintenance/operations page.
lib/teslamate_web/router.ex Adds OperationsAuth pipeline and routes /maintenance and /api/health.
lib/teslamate_web/plugs/operations_auth.ex Implements optional Basic Auth boundary with fail-closed config.
lib/teslamate_web/live/maintenance_live/index.ex Implements the Maintenance LiveView UI behavior (refresh, logs, close confirmation).
lib/teslamate_web/controllers/health_controller.ex Implements versioned aggregate runtime health endpoint with 503 behavior.
lib/tesla_api/stream.ex Adds liveness receiver callbacks and emits liveness events on connect/disconnect/terminate.
Dockerfile Injects build metadata env vars; creates log directory for file logging.
config/runtime.exs Adds build-info config + env-driven operations auth, file logging, and maintenance action toggles.
assets/css/app.scss Adds styles for operations layout and log tail view.
.github/workflows/ghcr_build.yml Passes build ref/revision/source into the image build action.
.github/workflows/buildx.yml Passes build ref/revision/source into the image build action.
.github/actions/build/action.yml Adds build args for build provenance + sets TESLAMATE_BUILD_DATE at build time.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread website/docs/maintenance/operations.md Outdated
Comment thread website/docs/maintenance/operations.md
Comment thread lib/teslamate_web/templates/layout/root.html.heex Outdated
Comment thread lib/teslamate_web/router.ex
Comment thread test/teslamate/log_redactor_test.exs Outdated
@magrathean-uk

Copy link
Copy Markdown
Contributor Author

Quick correction before you spend time reviewing this: I have now read your closing notes on #5517 and #5518, and those concerns apply to parts of this branch too. I do not want to ask you to review a direction you have already rejected. I am removing the duplicate data-health surface, the hot-path runtime collector, and the second health endpoint. I will update the branch and description so the remaining scope is only the requested maintenance actions, bounded log access, build identity, and their shared auth boundary.

@JakobLichterfeld JakobLichterfeld added enhancement New feature or request note:discussion Details or approval are up for discussion docker Pull requests that update Docker code area:teslamate Related to TeslaMate core labels Jul 18, 2026
@magrathean-uk
magrathean-uk force-pushed the feature/operations-center branch from 1bf05d0 to bcd4f27 Compare July 18, 2026 16:25
@magrathean-uk magrathean-uk changed the title feat(maintenance): add an operations center feat(maintenance): add authenticated close actions and logs Jul 18, 2026
@magrathean-uk

Copy link
Copy Markdown
Contributor Author

Hi @JakobLichterfeld, the narrowed version is pushed now. I removed everything that overlapped with the concerns you raised on #5517 and #5518: there is no duplicate data-health inbox, no hot-path collector, no new /api/health endpoint and no navbar slot. Open-session queries now run only when maintenance actions are explicitly enabled.

What remains covers the close-drive/charge part of #4850, the bounded authenticated log-tail part of #4891, and build identity from #3682. I think these are worth reviewing together because they use the same small Maintenance page and Basic Auth boundary, and the build identity is what makes the support logs traceable. Keeping that shared path avoids three separate routes, auth setups and repeated UI/docs work. I have also called out clearly that the logging part is env-controlled and does not replace the UI-toggle direction in #4898.

The commits are still separated by concern if you prefer to split anything after reviewing the safety model. The updated PR description has the exact boundaries and verification, including 411 tests, Dialyzer, a production Docker build, browser checks, auth headers, fail-closed action proof, and VIN/token redaction.

Remove the duplicate data-health and runtime-health concepts from the maintenance workflow. Open-session queries now run only when close actions are explicitly enabled, and the page is linked from Settings instead of taking a navbar slot.

Keep the shared Basic Auth boundary for bounded file logs and close actions. Extend log redaction to cover VINs, token collections, backseat tokens, and escaped structured values before persistence and display.
@magrathean-uk
magrathean-uk force-pushed the feature/operations-center branch from bcd4f27 to 0697ae2 Compare July 18, 2026 16:30
@JakobLichterfeld
JakobLichterfeld marked this pull request as draft July 20, 2026 08:17
@JakobLichterfeld JakobLichterfeld added closed:wontfix This will not be worked on and removed enhancement New feature or request note:discussion Details or approval are up for discussion docker Pull requests that update Docker code area:teslamate Related to TeslaMate core labels Jul 20, 2026
@JakobLichterfeld

Copy link
Copy Markdown
Member

Hi Bolyki, thank you for the work that went into this — and for proactively narrowing the scope after my notes on #5518 and #5520. The craftsmanship is genuinely good: the fail-closed safety model, the lock-and-recheck transaction, and the test coverage are all well done.

That said, I won't review this as a single unit, and I want to be transparent about why.

1. This bundles too much. Build identity (#3682) has nothing to do with maintenance actions or log access — a shared auth path is not enough reason to couple three features. Even with clean commits, a 49-file PR spanning CI, Dockerfile, a new auth plug, a new LiveView, a file logger and a redaction engine is very hard to review and even harder to maintain.

As a side note on #3682: our images already carry build identity twice — the OCI labels from docker/metadata-action (org.opencontainers.image.revision etc.), and since #5380 signed SLSA provenance that cryptographically ties every published digest to repo, ref and commit (gh attestation verify oci://teslamate/teslamate:latest --repo teslamate-org/teslamate). Injecting a third, self-reported copy via build-args and ENV goes in the opposite direction. If the goal is showing identity in the UI, that needs to start from what the image already carries — I'll leave notes in the issue.

2. Direction before implementation. As I said in #5452: “I'd prefer that we first establish the need for a feature and then discuss the best implementation, rather than iterating on the implementation before we've agreed that the feature itself solves a recurring problem.” For #4891 the need is established — I opened that issue and outlined the requirements there. But this implementation makes decisions that were not part of that outline (mandatory Basic Auth, no UI toggle for file logging), and those are not up for negotiation in a PR thread. Please wait for direction in the issue before implementing; arriving with finished implementations puts me in the position of either accepting decisions I wasn't part of, or rejecting finished work — neither is good for you or for me.

3. The mandatory Basic Auth coupling is a blocker. Many users already secure TeslaMate properly at the deployment level — reverse proxy with Authelia or OIDC, mTLS, VPN — which is the documented model for TeslaMate. Refusing to start unless a second, TeslaMate-specific Basic Auth credential pair is configured punishes exactly the users who have set up better authentication: for them this is not a safety feature but friction and a second credential store to manage. And since the rest of the UI (settings, geofences, token entry) remains unprotected, the boundary doesn't provide a real security gain either. Deployment-level protection has to remain a first-class option. I won't debate the security architecture further in this PR — the expected model will be spelled out in the issues.

How to proceed:

One more general note: you've been contributing at a very high pace over the last weeks, and some of it has been genuinely valuable (#5512, #5513, #5514, #5475). But TeslaMate is maintained by volunteers, and review capacity is our scarcest resource. Several small, issue-aligned PRs — coordinated with the work that already exists — will always move faster here than large pre-built solutions. Thanks for understanding.

🤖 Review drafted with Claude Code (Fable 5 high) — sponsored by Claude for Open Source

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

Labels

closed:wontfix This will not be worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend version with more build info

3 participants