Commit Graph
35 Commits
Author SHA1 Message Date
Juan DenisandClaude Fable 5 11066bb130 fix(agent-install): paged version discovery, checksum verify, busybox support (A1-A3)
- version discovery pages agent-v tags (?per_page=100, 3 pages) so
  panel releases can no longer push agent tags off page 1; panel
  injects its resolved agent version into the served script and its
  own releases fetch is paginated too (A1)
- downloaded agent binary is sha256-verified against the release's
  checksums.txt: halt on mismatch, warn-and-continue when absent (A2)
- value-taking options error loudly when the value is missing; busybox
  adduser fallback; no GNU-only grep -oP; pipe-safe source guard (A3)
- test-routing.sh fixed (PASS++ suicide under set -e, guarded probes,
  curl 000000 false-pass) rather than deleted - still live tooling
- new scripts/test/test_agent_install.sh (18 passed); backend server
  tests 110 passed

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 18:00:24 -04:00
Juan DenisandClaude Opus 4.8 f47d0e1428 feat: Phase 1 foundation — status aggregator, API scopes, onboarding, template magic vars
Four foundational enhancements toward the deploy-code developer experience:

- Container status aggregator (C7): new ContainerStatusService applies a
  deterministic priority hierarchy (degraded > restarting > running:unhealthy >
  starting > running:healthy > exited > unknown) over an app's containers,
  cached with a short TTL. Exposed at /api/v1/status and pushed over a new
  container_status Socket.IO channel; Applications page now renders an
  aggregated ContainerStatusPill with sub-status tooltip.

- API token scopes + sensitive data masking (C10): require_scope() decorator
  enforces fine-grained scopes for API-key requests (pass-through for JWT),
  a canonical SCOPES catalog at /api/v1/api-keys/scopes, and a reusable
  sensitive_data_filter (mask_sensitive) honoring secrets:read. Frontend gains
  a grouped ApiKeyScopesModal picker and per-key scope pills.

- Server onboarding state machine (C8): new onboarding lifecycle
  (pending -> validating -> installing_prerequisites -> installing_docker ->
  pairing_agent -> ready/failed) with ServerOnboardingService, a
  server_onboarding_logs table, servers.onboarding_* columns, REST endpoints,
  and an OnboardingWizard surfaced on the server detail overview.

- Declarative template catalog (C5): documented catalog schema and
  magic-variable resolution (SERVICE_PASSWORD_/USER_/FQDN_/URL_/BASE64_*)
  layered onto the existing YAML template loader without changing behavior for
  templates that don't use them; GET /api/v1/templates/catalog/schema.

Migration 029 adds the onboarding table + columns. 60 new tests pass; frontend
builds clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 18:23:47 -04:00
Juan Denis cbf64dfbaa feat(workspaces): enforce server quotas and add nav permissions UI
- Enforce max_servers quota on server creation and workspace moves
- Add my_role/my_effective_role to single workspace GET response
- Add Navigation Permissions editor to Workspace Settings
- Store full active workspace object for nav/brand settings
2026-06-21 18:44:08 -04:00
Juan DenisandClaude Opus 4.8 fa73b217ef feat(workspace): scope domains/databases + reconcile workspace roles (#33)
Finish #33's two named workspace-scoping slices, backend-only (no schema
migration, no frontend changes):

- Domains: get_domains scopes through the parent Application via scope_query
  (own + granted, workspace-narrowed); also surfaces granted apps' domains,
  closing a gap vs the per-domain routes. Admin-no-context path unchanged.
- Databases: the app-linked /docker/databases enumeration scopes via
  scope_query; host-level MySQL/PG/SQLite stay global system resources
  (documented inline).
- Role reconciliation: WorkspaceService.effective_role + can_write_in_workspace
  intersect global User.role with per-workspace WorkspaceMember.role,
  narrow-only (a workspace role can only reduce capability; system admin never
  capped). Enforced at apps/servers create + reassign seams (viewer -> 403,
  only when a workspace context is active). Reconciled role surfaced on
  GET /workspaces (my_role/my_effective_role).

6 new tests; full backend suite 193 passed / 12 skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 21:00:57 -04:00
Juan DenisandClaude Fable 5 6eb4471829 fix(servers): require developer role for agent self-update (audit H3)
POST /<id>/agent/update was @jwt_required() only, so a read-only viewer could
trigger agent binary replacement + service restart across the whole fleet —
inconsistent with every other state-changing server route, which is
@developer_required. Add @developer_required and a test proving a viewer gets
403 while a developer clears the gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 17:33:29 -04:00
Juan DenisandClaude Opus 4.8 e89415f3e0 feat(workspaces): reassign apps/servers between workspaces (#33)
Completes the organizing loop — existing resources were stuck wherever the
backfill put them (Default); now they can be moved into client workspaces.

- PUT /apps/<id>/workspace (owner-or-admin on the app) and
  PUT /servers/<id>/workspace (developer+), both requiring the TARGET be a
  workspace the caller can access (member or admin). A null target moves the
  resource back to Default.
- UI: an 'Apps' management modal on each Workspaces card (mirrors the Members
  modal) with move-in / move-out. It fetches with allWorkspaces (an empty
  X-Workspace-Id header) so it can see apps in other workspaces to move them in,
  sidestepping the ambient scope.
- Fixed a real bug caught by tests: the app ownership check compared app.user_id
  to the stringified get_jwt_identity() (int != str -> spurious 403); now uses
  user.id.

Verified: 2 new endpoint tests (ownership + target-membership + null->Default +
role gates), full suite 122 passed, frontend lint-clean + production build.
Servers reassignment is API-only for now; the modal is apps-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 09:32:30 -04:00
Juan DenisandClaude Opus 4.8 45aeb507e4 refactor(workspaces): lenient workspace resolution for safe header-driven context (#33)
A stale or forbidden X-Workspace-Id (deleted workspace, removed member) now degrades to no-scope instead of 403/404, so an ambient workspace-context header can never break the apps/servers lists. Safe by construction: falling back to no-scope only ever shows the user their own resources and stamps the default workspace on create — it never grants access to, or creates in, a foreign workspace. Also drops the error-tuple from the four call sites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 08:49:44 -04:00
Juan DenisandClaude Opus 4.8 299a004cdf feat(workspaces): workspace_id scoping foundation + safe backfill (#33)
The cross-cutting backbone the rest of the #33 agency-scale milestone needs,
landed as a contained, narrow-only foundation rather than a 36-route rewrite.

- Nullable workspace_id FK on applications + servers (Alembic 015 off 014) with
  an idempotent raw-SQL backfill: create a Default workspace, attach every
  workspace-less row, and make every existing user a member so nobody loses
  visibility once scoping is activated. Also creates the workspace_id indexes
  that upgraded installs would otherwise lack.
- Centralized scope helper in WorkspaceService: ensure_default_workspace,
  resolve_workspace_id (validates a requested workspace; membership-checked with
  admin bypass; rejects deactivated accounts on the workspace path), and
  scope_query.
- Opt-in + narrow-only: a request filters by workspace only when it carries an
  X-Workspace-Id header / ?workspace_id=. scope_query INTERSECTS the workspace
  filter with the existing per-user ownership filter, so it can only narrow
  visibility, never broaden it — with no context the behavior is byte-identical
  to before (admin->all, owner->own, servers global). This closes the footgun
  where the backfill would otherwise let a non-admin enumerate all resources via
  the Default workspace.
- Wired into apps.py + servers.py (list + create): replaces the duplicated
  ownership branch and stamps new resources with the active-or-default workspace.

Deferred to follow-on slices: broad route adoption, per-site ACL, the
workspace<->User role reconciliation, server-side branding, and a frontend
workspace selector.

Verified: 10 new pytest tests (scope-narrowing, a can't-broaden-access
regression, deactivated-user gate, raw-SQL backfill against real SQLite +
idempotency), full suite 120 passed, a real end-to-end alembic upgrade to 015 on
a fresh DB (columns + indexes), and a 2-lens adversarial review (3 findings, all
fixed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 03:36:24 -04:00
Juan Denis a79bbc27f7 Add connstring, file handlers, and security tests
Introduce connstring package and tests to decode panel "connection strings" and add UI/CLI hooks to accept them. Move file access handlers into a dedicated file_handlers.go with strict allowlist checks that resolve symlinks and validate parent dirs to prevent escapes; add unit tests covering symlink and allowlist behaviour. Add credential-rotation HMAC verification, command blocking and configurable exec timeout resolution, gate system:exec registration by feature flag, and fix Docker logs reading to use io.ReadAll with a size cap. Misc: buffer restart channel to avoid IPC hangs, improve UDP discovery error handling, expose IPC token via a local endpoint and add IPCTokenPath, and wire the pairer to handle connection-string pairing and persist credentials. Overall changes focus on security hardening, UX for single-string pairing, and reliability fixes.
2026-05-02 00:51:47 -04:00
Juan DenisandClaude Opus 4.7 5541504ef8 Fix the systemic silent failures: empty log, dead WS, locked-out agents
Four real root causes that produced the symptoms we've been chasing:

1. agent.log was 0 bytes because io.MultiWriter aborts the entire
   write chain on the first writer error. On Windows services where
   os.Stdout writes can transiently fail, the lumberjack file writer
   never got the slog records — events.json (direct os.File) worked
   fine while agent.log silently stayed empty for the entire process
   lifetime. Replace io.MultiWriter with resilientWriter that
   independently writes to each underlying writer and swallows
   per-writer errors. Also surface logger init failures (MkdirAll,
   OpenFile) instead of silently falling back to stdout-only, and
   emit an explicit "logger initialized" startup line so an empty
   file is now an obvious bug rather than ambiguous.

2. WS connections appeared to "drop every 2-3 minutes" but actually
   the read loop had no ReadDeadline at all — ReadMessage() blocked
   forever on a network-killed connection until the OS-level TCP
   timeout fired, which is exactly what produced the
   ws_connected → ws_disconnected pattern in events.json. Add
   readWait = pingInterval*2.5 + 5s, reset it on every successful
   read AND in SetPongHandler. Now CF/ngrok killing the conn at the
   network layer (without sending a WS close frame) is detected
   within seconds, the read errors out cleanly, the Manager's flap
   detector counts it, and we fall back to polling far faster.

3. Newly-registered servers defaulted to permissions=[] which made
   every action 403. The user hit "Permission denied" on
   docker:image:list, system:info, agent:recapabilities, and probably
   half the rest. Default to ['*'] when no profile or list is
   specified — single-tenant deployments shouldn't need to manually
   open a profile editor before anything works.

4. Migration 006 retroactively fixes already-stuck servers: any row
   with permissions=[] gets ['*']. Non-empty admin-defined ACLs are
   left alone. Solves "I registered before this fix and now I can't
   do anything" without bulldozing legitimate configurations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 07:06:58 -04:00
Juan DenisandClaude Opus 4.7 e99e65cff6 Auto-correct stale 'online' status when no in-memory agent
When the panel restarts or the agent process crashes without a clean
disconnect, Server.status stays 'online' in the DB even though
agent_registry has no in-memory record. The UI then shows a
contradiction: "online" pill in the header, "Agent not connected"
on the Docker tab.

Reconcile in get_server: if there's no in-memory agent and the row
says online, flip to offline and persist. The capabilities cache +
last_seen still surface so the user sees the last known state, but
the UI now correctly reflects that the agent isn't reachable right
now.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 06:52:15 -04:00
Juan DenisandClaude Opus 4.7 7d55a9c05d Add panel-driven cloudflared login flow
Users had to SSH in to run `cloudflared tunnel login` before any of
the Tunnels tab worked. Wire up the OAuth flow so the panel can
trigger it and surface the auth URL for the user to open from their
own browser.

Agent:
- New cloudflared.LoginEvent + Manager.Login() that spawns the
  process, regex-matches the dash.cloudflare.com/argotunnel URL on
  stdout/stderr, and watches cert.pem in parallel as a reliable
  completion signal. 15-minute hard ceiling.
- New cloudflared:login action returns {job_id, channel} immediately;
  the goroutine emits start → status (with auth_url) → done events
  on the job channel.
- Non-linux stub returns "unsupported".
- jobs.HasTerminated() helper so handler shutdown paths can avoid
  double-emitting the terminator.

Panel:
- POST /servers/<id>/cloudflared/login + RemoteCloudflaredService.login
- ApiService.startRemoteCloudflaredLogin

Frontend:
- CloudflaredTab gains a "Login to Cloudflare" CTA when not authed.
  Click → starts the agent flow, joins the job's Socket.IO room,
  listens for the auth_url event, and renders an Open-in-Browser
  button. Once the agent emits done, refreshes capabilities + status
  + tunnel list automatically — the rest of the tab unlocks itself.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 05:52:11 -04:00
Juan DenisandClaude Opus 4.7 32bf2b8081 Cache agent capabilities to DB and surface them in System Status card
The agent reports a rich capability payload (sudo mode, runtime
managers, detected runtimes, allowed paths, systemd JSON support)
that the panel was discarding once the WebSocket disconnected. The
Overview tab also gave no visibility into what the agent had
discovered, which left users guessing why a feature tab was missing
or a Docker call returned empty.

Backend:
- Server model gains seven nullable columns: cached_capabilities,
  cached_runtimes, cached_runtime_managers, cached_allowed_paths,
  cached_sudo, cached_systemd_json, capabilities_at. Migration 005
  is idempotent (checks existing columns before adding) so it's safe
  on already-bootstrapped databases.
- agent_registry.update_capabilities() now persists a snapshot to the
  Server row whenever the agent reports state. Wrapped in try/except
  so a DB hiccup doesn't drop the in-memory update.
- /servers/<id> falls back to the cached snapshot when the agent is
  offline and exposes capabilities_stale + capabilities_at so the UI
  can badge stale data.

Frontend:
- New SystemStatusCard renders sudo mode, package manager, runtime
  managers, detected runtime versions, capability map (as colored
  chips), and file-access roots. "Stale" badge + relative timestamp
  + Refresh button (calls agent:recapabilities).
- DockerTab now distinguishes "agent online but no docker daemon"
  from "no containers found", with concrete remediation hints. Load
  errors surface as a banner instead of being swallowed to console.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 05:16:42 -04:00
Juan DenisandClaude Opus 4.7 a534fbf002 Add Packages/Services tabs, JobProgressModal, pyenv runtime mgmt and template library
Phase 3 (frontend), Phase 4 (template library), Phase 5 (pyenv runtimes).

Frontend:
- New Packages tab on ServerDetail: search, install/remove, upgrade-all,
  update-cache, quick-install presets (nginx, redis, mariadb, postgres,
  docker, fail2ban, certbot, htop). Capability-gated on packages.
- New Services tab: list systemd units with state filter, start/stop/
  restart/logs per row, daemon-reload at top. Capability-gated on systemd.
- JobProgressModal subscribes to a server-stream Socket.IO room and
  renders live install/build progress until the agent emits phase=done.
- ApiService: 13 packages/services methods + 9 runtime methods +
  refresh-capabilities helper.
- LESS partials for both new tabs imported in main.scss.

Template library: 9 new one-click stacks added to ServerTemplate
TEMPLATE_LIBRARY: lemp, lamp, docker-host, node-host, python-host, redis,
postgres, cloudflared, fail2ban. Reuses existing packages/services/
firewall_rules JSON columns; the workflow engine's agent_command +
capability_gate nodes drive execution against the new agent surface.

Phase 5 — pyenv / pyenv-win runtime management:
- Agent: 9 new runtimes:* actions (list, pyenv:bootstrap, python:installed,
  python:available, python:install, python:uninstall, python:set_global,
  python:set_local, python:current). Bootstrap and install stream via
  the job-channel pattern. pyenvLock mutex serializes mutations.
  Capability probe surfaces RuntimeManagers["python"] = pyenv | pyenv-win.
- Panel: remote_runtimes_service.py + 9 routes under /servers/<id>/runtimes.
- Frontend: ApiService methods to drive the new endpoints.
  (Dedicated RuntimesTab component left as a follow-up; the API
   surface is the foundation.)

Build, vet, and tests pass across all three layers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 04:42:30 -04:00
Juan DenisandClaude Opus 4.7 e71099a4e9 Add remote packages, services, sudo, job streaming and capability re-probe
Foundation for the remote server setup experience: agent gains
auto-sudo, package and systemd handler additions, missing docker
verbs, and a job-channel registry for streaming long-running
operations. Panel exposes the new agent surface as /servers/<id>/
packages, /services, and /refresh-capabilities routes.

Agent:
- New protocol actions: agent:recapabilities, packages:update_cache/
  install_async/upgrade/search/info, systemd:daemon_reload/list_units/
  logs/logs_follow, docker:container:create/exec, docker:image:build,
  docker:volume:create, docker:network:create.
- Auto-sudo helper (sudo -n) probed at boot, surfaced as a capability;
  apt invocations get DEBIAN_FRONTEND=noninteractive + dpkg force-confold.
- jobs registry with ring-buffer replay so panels that subscribe to a
  job:<id> channel mid-flight still see prior progress events.
- Capability re-probe is mutex-guarded and additive (transient probe
  failures don't drop features the panel already saw).
- Existing systemd handlers now sudo and use 2-min timeouts for cold
  service starts (postgresql etc.).

Panel:
- remote_packages_service.py and remote_systemd_service.py mirror the
  cron service shape (thin send_command dispatcher).
- 13 new routes on servers.py covering packages CRUD + search/info,
  systemd unit control + logs + daemon-reload, and capability refresh.
- Long-running install/upgrade return {job_id, channel} for the
  frontend to subscribe to via Socket.IO.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 04:33:08 -04:00
Juan Denis 1f61513c26 Add agent Phase4 primitives, remote files & UI
Add Phase 4 agent primitives (package management, systemd control, bounded exec) and advertise file-access roots so the panel can target agents safely. Introduces agent/internal/agent/workflow_handlers.go with handlers for packages, systemd and system:exec, registers those actions, and extends capabilities.Probe and capability messages to include runtimes and allowed_paths.

Backend: add RemoteFileService and new /servers/<id>/files/* endpoints, store advertised allowed_paths in agent_registry and expose a getter, normalize agent system metrics shape in remote_docker_service, and wire capabilities/allowed_paths into the servers list. Extend workflow_engine with agent_command, capability_gate and runtime_gate nodes and basic runtime-version comparison.

Frontend: add TargetPicker component and update FileManager to support remote targets (browse/read/write via agent), guard unsupported remote ops, and normalize agent file responses for the UI. Overall this enables remote file browsing and Phase 4 workflows against connected agents.
2026-05-01 03:37:33 -04:00
Juan Denis 8ddd60f83d Add Cloudflared tunnel management
Introduce Cloudflare Tunnel management end-to-end.

Highlights:
- Add agent/internal/cloudflared package (Manager interface, Linux impl, non-Linux stub) to shell out to cloudflared and detect auth via cert.pem.
- Wire cloudflared Manager into the agent and register cloudflared:* handlers for status/list/create/route/delete.
- Extend protocol.Capabilities and agent payloads with runtimes detection and a cloudflared capability; implement runtime version probes.
- Add backend API endpoints and RemoteCloudflaredService that forward cloudflared actions to agents; update agent registry to store runtimes.
- Frontend: new CloudflaredTab UI, API client methods for remote cloudflared operations, styles, and UX tweaks (plus minor component/class refinements in LogViewer, ProcessTable, FileManager, StyleGuide, terminal styles).

Purpose: allow the panel to manage Cloudflare named tunnels by delegating commands to the agent's cloudflared CLI, while surfacing binary/auth state (install vs authenticated) and detected language runtimes.
2026-05-01 02:26:15 -04:00
Juan Denis dca5c3af67 Add remote cron management (agent, API, UI)
Introduce remote cron management across agent, backend and frontend.

- Agent: add a cron.Manager to agent, register handlers (cron:status,list,add,remove,toggle) and implement thin JSON handlers. Add agent/pkg/protocol message constants.
- Cron package: new platform-agnostic interface with Linux implementation (crontab-driven) and non-Linux stub. Includes content-based stable IDs, validation, list/add/remove/toggle and human-friendly schedule descriptions.
- Backend: expose /servers/<id>/cron/* endpoints and add RemoteCronService to proxy requests to agents via agent_registry, mapping agent responses to HTTP codes.
- Frontend: enhance Tabs component with overflow "More" popover; add API calls for remote cron ops; wire a Cron tab in ServerDetail (guarded by server.capabilities.cron) with UI for listing, adding, toggling and removing jobs; add Cron UI in Git page by switching to the new Tabs component.

Notes: cron functionality is Linux-only; non-Linux agents return an explicit unsupported status. Validation prevents unsafe shell operators and requires absolute command paths.
2026-05-01 01:54:17 -04:00
Juan Denis a93697c7f6 Add agent capability probing and reporting
Probe and report agent feature capabilities (cron, docker, systemd, nginx, etc.) so the panel can gate target pickers without extra round-trips.

Key changes:
- Add agent/internal/capabilities: probes host for features and platform/distro, returns protocol.CapabilitiesMessage cached at agent startup.
- Agent: store probed capabilities, send them on every transport reconnect (sendCapabilities) and include them when using poll transport.
- Protocol: introduce TypeCapabilities and CapabilitiesMessage (map[string]bool + platform/distro fields).
- Poll transport: accept CapabilitiesMessage in Send(), serialize to raw payload and queue for next /poll; support one-shot capabilities in poll body.
- Backend: handle capabilities from socket (on_capabilities) and poll endpoint; persist capabilities in in-memory ConnectedAgent (agent_registry) with helpers get_capabilities/has_capability; include capabilities/platform info in servers API.
- New fleet API (GET /api/v1/fleet/targets): list runnable targets (local + connected agents) and optionally filter agents by a requested feature using the advertised capability map.

Rationale: make agent feature availability explicit and discoverable to the panel so UI pickers can show only applicable agents without asking agents on every UI interaction.
2026-05-01 00:37:48 -04:00
Juan Denis 96a6f31d75 Add poll transport; Windows UI & service fixes
Introduce a fallback polling transport and manager: add internal/transport (Manager + poll client) so the agent can fall back from WebSocket to REST long-poll when tunnels mangle WS frames. Wire the Manager into the Agent and expose transport mode in IPC status.

Windows/service fixes: add service-scoped mutex to prevent concurrent service starts, probe IPC port on start to fail fast if occupied, and mirror main.Version into agent package at init. Fix spawned wizard visibility by setting HideWindow=false and add focus helpers that force foreground on Windows.

UI/asset changes: enable DevTools by default (env to disable), inject a small JS shim to forward console errors/navigation readiness to Go logs, hide WebView host until bundle ready (with timeout), and wrap static assets with no-store headers to avoid stale cached bundles. Add local /local/status endpoint so the UI can detect registration when IPC is unreachable.

Pairing/service handling: ensure service stop/start errors are surfaced, wait for service to reach RUNNING after pairing and surface helpful error messages if it doesn't. Implement platform-specific waitForServiceRunning and service control stubs.

Auth/backend alignment: expand API key prefix from 8 to 12 chars to match backend panel expectations and avoid authentication mismatches.

Misc: add focus_windows.go (Windows-only), various small refactors and logging improvements to make blank-page and pairing failures debuggable.
2026-04-30 22:31:04 -04:00
Juan Denis cc1151d0ce Add deployment jobs and remote deployment runner
Introduce a deployment jobs system to support cross-server template installations and remote execution. Adds DeploymentJob and DeploymentJobLog models, DeploymentJobService for job lifecycle, and DeploymentPlanRunner to execute plans locally or via agents. TemplateService gains build_install_plan and related helpers to produce executable plans; Template installs can run async (202) or synchronously. Backend API/CLI updated: new deployment-jobs endpoints, apps API uses RemoteDockerService for remote compose actions, and CLI commands (deploy-template, deployment-status, list-servers) were added. Agent and config changes: file access validation with allowed_paths, file write create_dirs option, default allowed paths, and install script/systemd read-write paths updated to permit /var/lib/serverkit and /var/serverkit. Migration file for deployment_jobs schema included.
2026-04-29 00:39:16 -04:00
Juan Denis 313f1a8f6b Remote Docker remove, normalize API & permissions
Add end-to-end support for removing remote Docker networks and volumes and normalize remote API responses. Server: new Flask endpoints to DELETE remote networks/volumes and helpers to compute external base/ws URLs and v1 API paths. Agent: register new handler docker:network:remove and Client.RemoveNetwork implementation. Backend service: RemoteDockerService.remove_network uses agent registry for remote servers and falls back to local DockerService. Models: expand Server permission logic to map agent actions to profile/legacy scopes (DOCKER_READ_ACTIONS, scope expansion and wildcard matching) and add unit tests covering permission mappings. Frontend: handle agent-backed response shapes (unwrapRemoteData, normalizeListResponse), call new removeRemoteNetwork/removeRemoteVolume API methods, update download/install URLs to /api/v1, and tweak several UI texts. Install scripts: change config/log directories, pass --config when registering/starting agent, and update systemd/service/unit and Windows service install paths. README: small wording updates about fleet/remote deployment and monitoring.
2026-04-29 00:11:46 -04:00
Juan Denis f6f08ae9d1 Fleet monitor + security and agent hardening
Adds cross-server Fleet Monitor endpoints and models, plus broad security and robustness improvements across agent, backend, and tooling.

Key changes:
- New fleet monitor API (endpoints for heatmap, comparison, alerts, thresholds, anomalies, forecast, search, exports, and Prometheus) and service skeleton.
- New DB models for ServerAlertThreshold and MetricAlert to support metric alerts.
- Agent discovery/registration hardening: HMAC-signed discovery requests, signature/timestamp validation, minimal discovery responses, HMAC-based unregister headers, and enforced command timeout cap in agent command handling.
- WebSocket and agent client TLS handling gated by SERVERKIT_INSECURE_TLS env var; added auth rate limiting on agent gateway.
- Docker-compose: parameterize agent image via AGENT_VERSION and avoid running as root by adding docker group access.
- Backend security & policy: tightened CSP script/style sources, request size limit, 2FA pending-token rejection on non-2FA endpoints, registration flow/guards, admin-only SSO admin routes via middleware, rate limits on sensitive endpoints, and logging for auth/2FA events.
- Database service hardening: identifier validation, avoid passing passwords on CLI (use env vars), safer subprocess usage, and docker exec handling improvements.
- CronService: command validation to prevent shell injection and run commands without shell=True; build_service and other subprocess usages updated similarly.
- Misc: .env.example notes clarified for encryption key generation, invitation token generation improved, agent registry timestamp window reduced, various logging and input validations added, frontend FleetMonitor page and styles stubbed in, and Vite/config/style updates.

Overall this commit implements fleet monitoring scaffolding and a set of security, validation, and operational improvements to make agent discovery, registration, command execution, and backend services safer and more robust.
2026-03-23 01:58:28 -04:00
Juan Denis d9dfc4d611 Add agent fleet management, discovery & updates
Introduce full agent fleet management and discovery features across backend, agent, and frontend. Backend: add AgentVersion and AgentRollout models, extend Server/ServerGroup/ServerCommand/AgentSession with fleet, queue and latency fields; implement AgentFleetService (bulk upgrades, staged rollouts, queued commands, retries, diagnostics) and DiscoveryService (UDP broadcast scan); add new servers API endpoints for fleet operations. Agent: add UDP discovery responder, agent:update handler to trigger updater, and wire updater.UpdateTo to install specific versions; extend protocol messages with discovery and agent:update types. Registry: deliver queued commands on agent connect and track heartbeat latency. Frontend: add AgentFleet page and route, plus API client updates. Also add SECURITY_AUDIT.md to .gitignore. These changes enable discovery, staged rollouts, offline command queuing with retries, and fleet health/diagnostics.
2026-03-23 01:46:41 -04:00
Juan Denis f0eb8b8cd9 Update GitHub repo references and install params
Replace hardcoded repository URL from serverkit/serverkit to jhd3197/ServerKit across agent Dockerfile, README, packaging scripts (deb/rpm) and install scripts so downloads and metadata point to the correct repo. Backend install endpoints now replace the repo placeholder with the GITHUB_REPO constant, and the frontend Windows install command was adjusted to use the -Server parameter instead of -ServerUrl. These changes ensure install scripts, packages, and generated docs reference the intended repository and that generated installer commands match the agent's expected flags.
2026-03-01 13:39:03 -05:00
Juan Denis d2e5fdd6d6 Update default GitHub repo for agent releases
Changed the default value of SERVERKIT_GITHUB_REPO from 'serverkit/serverkit' to 'jhd3197/ServerKit' to point to the new repository for agent release checks.
2026-01-25 14:28:08 -05:00
Juan Denis 4cdcff598d Remove compare_server_metrics endpoint
Deleted the /metrics/compare API endpoint and its handler from servers.py. This endpoint allowed comparison of metrics across multiple servers but is no longer needed.
2026-01-22 19:55:22 -05:00
Juan Denis bca7e29b57 Implement security features: key rotation, IP allowlist, anomaly detection
Adds API key rotation, IP allowlisting, anomaly detection, and replay protection to the ServerKit agent system. Backend changes include new endpoints, models, and services for security alerts, nonce tracking, and anomaly detection, as well as updates to the server model and agent authentication logic. The agent now supports credential rotation and replay protection via nonces. Frontend updates add UI and API methods for managing allowed IPs, viewing security alerts, and rotating API keys. Documentation and environment setup instructions are included.
2026-01-22 18:11:22 -05:00
Juan Denis fd90e2eead Add full-stack remote terminal/PTY support
Implements remote terminal functionality across agent, backend, and frontend. Adds PTY session management in the agent using creack/pty, new protocol actions, and terminal manager. Backend exposes terminal session APIs and session tracking via TerminalService. Frontend introduces a RemoteTerminal component using xterm.js and related APIs for interactive remote shell access.
2026-01-22 16:44:06 -05:00
Juan Denis 78fee0ada0 Add server historical metrics API and service
Implements backend API endpoints and a new ServerMetricsService for historical metrics, retention policies, aggregation, and multi-server comparison. Updates frontend ApiService with methods for metrics history, aggregation, comparison, retention stats, and cleanup. Updates integration plan to mark monitoring & metrics as complete.
2026-01-22 08:51:31 -05:00
Juan Denis 4a34349ed4 Add remote Docker Compose management support
Implements full remote Docker Compose project management, including listing, starting, stopping, restarting, pulling images, and viewing logs for compose projects. Updates the agent, backend API, service layer, frontend UI, and API client to support these operations for both local and remote servers.
2026-01-22 08:31:27 -05:00
Juan Denis 35deeb8882 Add remote Docker container logs streaming support
Implements backend and frontend support for streaming Docker container logs from remote servers. Adds new API endpoints, agent handler, and UI controls for selecting log line count. Updates documentation to reflect the completed feature.
2026-01-21 23:23:29 -05:00
Juan Denis 4e9767a6ca Add agent auto-update mechanism and backend endpoints
Implemented agent auto-update functionality, including periodic update checks, manual update command, and configuration options. Added backend API endpoints for agent version checking, update triggering, and download redirection. Updated documentation to reflect completion of the auto-update system.
2026-01-21 23:07:20 -05:00
Juan Denis 528c86d640 Add agent install scripts and release automation
Introduced Linux (install.sh) and Windows (install.ps1) installation scripts for ServerKit agent, and exposed new backend endpoints to serve these scripts and installation instructions. Added a GitHub Actions workflow (agent-release.yml) for automated agent builds and releases. Updated ROADMAP.md and SERVERS_INTEGRATION_PLAN.md to reflect progress on installation and distribution features.
2026-01-21 22:57:40 -05:00
Juan Denis 009fb12435 Add multi-server management and agent gateway
Introduces backend models, API endpoints, and services for remote server and agent management, including WebSocket agent gateway, server CRUD, metrics, command history, and remote Docker operations. Updates frontend to support server listing, detail pages, and related UI components and styles.
2026-01-21 22:47:42 -05:00