Commit Graph

27 Commits

Author SHA1 Message Date
admin a1d045079f @
hub v0.54.0: change operator login password from the Configuration UI

Adds a "Login password" card on /configuration. The password was previously
settable only via the hub-config ConfigMap (auth.password_hash) + redeploy.

- store: hub_settings key operator_password_hash + Get/SetOperatorPasswordHash
- server: passwordHash field -> configPasswordHash (seed); new
  effectivePasswordHash() (DB override wins, else seed) is now the single
  source for the CSRF gate, RequireAuth, and handleLogin
- POST /configuration/password (handleChangePassword): requires current
  password, 8-72 byte new + confirm, bcrypt cost 10, persists DB override;
  existing sessions kept valid; ConfigMap stays the break-glass reset path
- UI: current/new/confirm form + inline mismatch pre-check + 6 flashes
- tests + red-proofs: override precedence, happy-path via handleLogin,
  wrong-current rejection, mismatch/too-short/no-op, template render
- docs: CHANGELOG, README (auth+config), REUSE, REPORT

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd
@
2026-07-13 22:46:49 +02:00
admin 95d71fef2e hub v0.47.0: CHANGELOG + README tab/host-lifecycle/offsite docs + REUSE map + manifest bump to 0.47.0
CONTEXT.md: v0.47.0 arc entry (resolves the 146d165 swept-WIP flag) + the
multi-endpoint-allocation deferral + pre-GitOps stale-template note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vvz1NCu22p8dGkRCpeX9re
2026-07-11 21:39:44 +02:00
admin 09bd7191e0 docs: SLICE 4 — hub README, REPORT, CONTEXT (offsite arc build-complete)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-10 00:25:57 +02:00
admin cb26dc7e83 docs: SLICE 3 — hub README, REPORT, CONTEXT
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 23:26:16 +02:00
admin e0d1733b85 docs: offsite hardening bundle — hub README, REPORT, CONTEXT
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 22:48:41 +02:00
admin 44ec06b50f hub v0.37.0: offsite provisioning SLICE 1 — Cloud-API client + provisioning core
Hetzner storage-box provisioning against api.hetzner.com/v1 (NOT .cloud).
internal/hetznerapi (typed client + CloudAPI interface + Fake + WaitAction);
internal/offsite (Provisioner.ProvisionOffsite — idempotent by label, shared
sub-account/dedicated box, transient password, non-secret Descriptor,
fail-closed); one_time_secrets store (single-use Save/Consume); POST
/offsite/consume-password/{id} (customer-key auth, once); config-form Offsite
section → applyOffsite (502+no-save on error) → descriptor in ConfigJSON →
version bump. Token/passwords never logged/committed/in ConfigJSON. Tested vs a
faked Cloud API + fail-closed red-proof. NOT yet live-provisioned (needs the
dedicated-project scoped token; current token can delete ep0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 18:38:24 +02:00
admin f4d88c1ff4 docs: felhom.eu REPORT (HostLeafChecker) + hub README + self-health arc complete (spike doc)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pg8ANF97SEeKYSN5Jxw3qJ
2026-06-29 23:32:12 +02:00
admin 8098237ce1 hub v0.14.0: passphrase-authed host enrollment (Day-0 option C)
New POST /api/v1/host-enroll (handleHostEnroll): X-Retrieval-Password authed,
body {customer_id} -> {host_id, api_key}. Mint-once-reuse (201 first, 200
reuse) so re-running the host-bootstrap never orphans a running agent's key;
auth checked before any mint. Backed by new Store.GetHostByCustomer
(ORDER BY updated_at DESC LIMIT 1, idx_hosts_customer).

GET /config/{id} and global-key POST /admin/hosts left untouched. Exact-match
route (path == "/host-enroll") to avoid the /hosts/ prefix collision.

Tests: host_enroll_test.go (mint/reuse/401-no-mint/404/400) + GetHostByCustomer
store test; companion red-proof verified always-mint fails the reuse assertion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TtXesNa2LGbMmE4DNL6SE7
2026-06-26 15:35:24 +02:00
admin 5f5e3c54a1 hub v0.13.0: DR recipe — assemble + store + view the secret-free reconstruction recipe
DR recipe slice (hub half), grounded in SPIKE-dr-recipe-2026-06-16. The hub
receives two additive dr_recipe halves on the existing report paths (agent
storage/guest/PBS on host-report; controller customer/apps on the controller
report), stores them PLAINTEXT in a DEDICATED dr_recipe table keyed by customer
(each half preserves the other), and AssembleDRRecipe stitches them into one
operator-readable recipe (ignore-unknown + version-skew tolerant).

View: a DR-recipe panel on the customer page + GET /customers/{id}/dr-recipe.json
download (operator-auth, no secrets to redact). Plaintext-at-rest is correct —
the recipe is the clean inverse of the retired infra-backup.

Tests: store round-trip (each half preserves the other), assemble-matches-golden,
ignore-unknown + version skew, partial halves, no-secrets sweep. Manifest tag
bumped to v0.13.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 18:49:45 +02:00
admin 0635640848 hub v0.12.0: retire Infra Backup, purge its plaintext secrets, fix backup-deadline email
Phase-1 of SPIKE-infra-backup-2026-06-15. The infra-backup mechanism was dead
since slice 8C yet stored plaintext customer secrets at rest (app-secret key,
restic password, Cloudflare tokens) — a zero-knowledge violation — and its
absence made the daily expected_backup_missed email fire for healthy customers.

- Repoint monitor.CheckBackupDeadlines backup half to the agent host-report's
  PBS snapshots (+vzdump): alarm only on no-backup / >26h stale / verify failed.
  Keep the db_dump half. No host-report → no backup alarm (liveness owns that).
  New store.GetLatestHostReportJSON. Tests incl. a companion that fails pre-fix.
- Remove the infra-backup endpoints, store methods/types, and operator panel;
  /recovery now returns config_yaml only.
- migrate(): DROP infra_backup_versions/infra_backups + VACUUM (+wal_checkpoint)
  to physically reclaim the plaintext pages, gated on table existence.

Flagged out-of-scope: exposed creds need operator rotation; legacy reports table
holds historical plaintext restic_password rows (separate leak, not purged here).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 11:08:06 +02:00
admin d65dba63bf docs: update hub README for v0.6.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 09:23:18 +01:00
admin 906c143aea docs: update CF token permissions for geo-restriction
Config form now shows Zone WAF:Edit requirement alongside DNS:Edit.
Hub README updated with permission note.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:58:25 +01:00
admin 1e354cbd41 feat(hub): Configuration page, asset seedOrUpdate, English UI
- Add Configuration page with "Refresh Assets" button
- Replace seedIfEmpty with seedOrUpdate (SHA-256 compare on startup)
- Translate all Hungarian text on Apps pages to English
- Add Configuration tab to all template navigation
- Expand isAssetFile to match favicon patterns
- Add felhom-logo.svg to website assets for the pipeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 09:34:43 +01:00
admin a757bee07a feat(hub): app telemetry analytics dashboard (v0.4.0)
- store/telemetry.go: new app_telemetry + app_log_issues tables with
  SaveAppTelemetry, GetFleetAppSummary (with P95), GetAppTelemetryHistory,
  GetAppCustomerBreakdown, GetCustomerAppSummary, GetAppIssues, prune methods
- api/handler.go: parse and save optional app_telemetry from report body,
  backward-compatible with old controllers
- cmd/hub/main.go: prune app_telemetry (90d) and stale issues (30d)
- web/apps.go: handleApps + handleAppDetail + chart data aggregation helpers
- web/server.go: routes for /apps, /apps/{name}, /static/chart.min.js;
  added memoryColor/accuracyClass/gt template functions
- web/embed.go: embed static/chart.min.js
- web/configs.go: add app telemetry section to handleCustomerUnified
- templates/apps.html: fleet-wide app list with summary cards and sortable table
- templates/app_detail.html: per-app page with Chart.js memory trend,
  customer breakdown, and known issues table
- templates/customer_unified.html: new Alkalmazás telemetria card
- templates/style.css: badge, summary-card, chart, period-selector,
  accuracy-dot, mem-color, data-table styles
- All templates: added Alkalmazások nav link

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 10:46:50 +01:00
admin 3bc31fca2d updated version in readme 2026-02-21 17:16:25 +01:00
admin 67f53a4ccd hub v0.3.8 — CSRF protection + secure session model
- server.go: replace literal hub_session=authenticated with random 64-char hex
  session tokens stored server-side (hubSession map + sync.RWMutex); per-session
  CSRF tokens; CleanupSessions goroutine; SameSite=Lax+Secure cookie; CSRF
  validation in ServeHTTP; csrfToken/csrfField helpers
- configs.go: add html/template import; pass CSRFField/CSRFToken to all template
  renders; renderConfigForm gains r *http.Request parameter
- config_form.html: {{.CSRFField}} in form
- customer_unified.html: meta csrf-token + csrfHeaders() JS; {{.CSRFField}} in
  all 5 POST forms; csrfHeaders() on 3 fetch calls
- main.go: start CleanupSessions goroutine

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 16:39:14 +01:00
admin da991fad57 updated readme 2026-02-21 15:45:44 +01:00
admin 4ec1b7d712 hub v0.3.5: Recovery endpoint + customer_blocked in report response
- New GET /api/v1/recovery/{customer_id}: returns generated controller.yaml
  and infra backup in a single response for disaster recovery.
  Auth via X-Retrieval-Password header.
- Report response now includes customer_blocked: true when customer
  status is "blocked" — controllers use this to detect standing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:38:57 +01:00
admin 9048e1adad hub v0.3.4: Rename version labels for clarity
"Current version" → "Controller version", "Latest version" → "Registry latest"
to avoid confusion when running version is ahead of registry cache.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:29:04 +01:00
admin 6dd72f1408 hub v0.3.3: Fix version double-v prefix, skip deprecated ping_uuids in diff
- Remove extra "v" prefix from ControllerVersion display (was "vv0.21.1")
- Add monitoring.ping_uuids.* to volatile keys — skipped in config diff
- Update manifest to v0.3.3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:57:01 +01:00
admin 6bcbaa1574 hub v0.3.2: Show Hub version in page footers
Add hubVersion template function via closure in web.New(). Version is
passed from main.go (set via ldflags at build time) and displayed in
the footer of all 6 page templates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:39:52 +01:00
admin 11428659d1 hub v0.3.1: Config diff display + pull config
Replace broken SHA256 hash comparison with value-based YAML comparison.
Add "Show Diff" button showing per-key differences in a color-coded table.
Add "Pull Config" to import controller's current config into the Hub.
New endpoints: GET /customers/{id}/config-diff, POST /customers/{id}/pull-config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:26:53 +01:00
admin 3217cb4751 feat: Hub monitoring takeover — event system, dead man's switch, notifications (v0.3.0)
Replace external Healthchecks.io with Hub-native monitoring. New events
table + /api/v1/event endpoint for structured events from controllers.
Staleness checker (60s) detects unresponsive nodes. Backup deadline
checker (daily 05:00) catches missed backups. Notification dispatcher
sends operator (English) + customer (Hungarian) emails via Resend with
per-event cooldowns. Event timeline on customer page, dashboard badges.
Config form deprecates Monitoring UUIDs section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:53:24 +01:00
admin b4cb92e09f docs: update hub CHANGELOG and README for v0.2.2
Add config hash comparison feature to changelog. Bump version references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 16:18:28 +01:00
admin a7a5304093 docs: update Hub README.md with v0.2.1 features
Document unified customer page, blocked status, pending dashboard,
config push, auto-create config, and customer state matrix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 16:07:13 +01:00
admin 4c8bf63ce3 feat: customer config management — CRUD, API retrieval, per-customer auth (v0.2.0)
New "Configurations" section lets operators pre-configure customer settings
in the Hub, then docker-setup.sh can download a ready-made controller.yaml
using just a customer ID and retrieval password.

- Store: customer_configs table with CRUD + per-customer API key lookup
- API: GET /api/v1/config/{id} with X-Retrieval-Password auth
- Auth: per-customer API keys alongside existing global key (backward compatible)
- Web UI: /configs list, create, edit, delete, YAML preview, copy-to-clipboard
- YAML gen: deep-merge controller.yaml.example template with customer overrides
- Template fetcher: background goroutine refreshing template from Gitea repo
- Navigation: Dashboard / Configurations tabs on all pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:36:32 +01:00
admin 41e313bf36 hub v0.1.7: Infrastructure backup endpoints for disaster recovery
Add infra-backup push/pull API for controller DR:
- POST /api/v1/infra-backup — controller pushes infrastructure snapshot
- GET /api/v1/infra-backup/{customer_id} — fresh controller pulls backup
- infra_backups SQLite table with per-customer snapshots
- Customer detail page shows infra backup status card
- README.md with full API docs and DR flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:17:12 +01:00