1654 Commits
Author SHA1 Message Date
Juan Denis a61ae889fd Merge pull request #91 from jhd3197/dev
Sign extension releases and take WordPress out of the core tree
v1.7.82
2026-08-05 23:20:45 -04:00
github-actions[bot] 7e20371f5c chore: bump version to 1.7.82 [skip ci] 2026-08-06 02:54:34 +00:00
Juan DenisandClaude Opus 5 8e55f2355e fix(install): unbreak curl | bash — guard BASH_SOURCE under set -u
Piped execution leaves BASH_SOURCE unset, so the sourceability guard's bare
${BASH_SOURCE[0]} was an unbound variable under `set -u` and aborted the
install before main() ever ran:

    bash: line 2107: BASH_SOURCE[0]: unbound variable

This broke the one-liner README/DEPLOYMENT document, on every distro — not
just the Debian 13 it was reported on (reproduced on debian:13 bash 5.2.37,
ubuntu:22.04 bash 5.1.16, almalinux:9 bash 5.1.8). CI never saw it because
every job runs `bash install.sh` from a checkout, where BASH_SOURCE IS set.

Use the same non-empty-first guard scripts/install.sh already carries, and
add the proving test the panel installer was missing (T41) — the agent
installer has had its twin since the same fix landed there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 22:42:52 -04:00
Juan Denis e556baf238 test: ratchet 3117 -> 3138 (audit remediation proving tests) 2026-08-05 13:36:33 -04:00
Juan Denis 065b6ed61b docs: consent-gate matrix + seam lifecycle in EXTENSIONS.md 2026-08-05 13:36:33 -04:00
Juan Denis 7c6b0f3958 security: hook seam lifecycle + registrant binding
Audit remediation (extension seams):
- disable/uninstall tear down the extension's backup kinds, event
  types, and template providers (unregister_capabilities by slug);
  enable re-registers (idempotent)
- wordpress_bridge fails closed unless the extension row is ACTIVE;
  orphaned-site db snapshot route returns clean 503
- provider registrations bound to their registrant: cross-slug
  replace/hijack rejected for backup kinds, event types, template
  providers
2026-08-05 13:36:33 -04:00
Juan Denis 670e9d8af7 security: signature lifecycle, update-path consent gates, download hardening
Audit remediation (install/signing surface):
- sig verdict reset on every install path (no stale verified badge)
- registry update route mirrors install consent gates (unreviewed 404,
  unsigned-first-party/untrusted 409 until acknowledged, bad sig 400);
  update offers carry installed_source_type; frontend risk dialog gains
  update branch
- first_party entries without verified pinned-key signature require
  acknowledge (community reviewed exempt, review-stamp-bound)
- downloads: https-only with per-hop redirect revalidation, private/
  link-local IP rejection, 100MB zip + 64KB sig caps, github token
  https-only
- extraction: declared+actual 250MB decompression cap with cleanup
- install/update audit logs record the signature verdict
2026-08-05 13:36:20 -04:00
Juan Denis d2d2d861cd test: ratchet 3213 -> 3117 (WP extension-owned suites moved out)
Collected 3142; floor keeps the usual ~25 headroom for
environment-dependent collection.
2026-08-05 02:38:54 -04:00
Juan Denis b159c7a5bd docs: WP extraction complete — core data seam, Tier C status 2026-08-05 02:38:41 -04:00
Juan Denis ba3bc685fe test: split WP suites — extension-owned move to serverkit-wordpress
10 extension-owned suites (surface, extraction, import-zip, php errors/
limits, pipelines alias, plugin library, promote, reports, ssh import)
move to the extension repo via the SERVERKIT_WORDPRESS_DIR loader.
Panel-core suites (bridge, hooks-absent, seeding, authz sweeps) updated
for WP-absent behavior; conftest seeds the manifest onto test plugin rows.
2026-08-05 02:38:41 -04:00
Juan Denis e6008afb38 refactor(wordpress): remove in-tree extension (extracted)
The full WordPress suite now lives at github.com/jhd3197/serverkit-wordpress
as a standalone runtime-ESM extension (backend blueprints/services, game
dashboard UI, tests, CI). Installed from the registry or offered during
onboarding from the bundled snapshot. WP data models stay core per D1
(documented core-data-seam).
2026-08-05 02:38:24 -04:00
Juan Denis e1a05384be refactor(wordpress): drop WP literals from sidebar presets + builtin manifest 2026-08-05 02:38:14 -04:00
Juan Denis b3eca19f66 chore(registry): bundled index lists serverkit-wordpress
Offline-first installs see the WP entry; sha256 refreshes from the
published asset at panel release time.
2026-08-05 02:38:13 -04:00
Juan Denis 798467baba feat(sdk): bump to 1.2.0 + PluginSlot/ErrorBoundary exports
Runtime-ESM extensions (starting with serverkit-wordpress) need slot
mounting and error containment from the host; additive, versioned in
lockstep frontend/backend.
2026-08-05 02:38:13 -04:00
Juan Denis 72eaba34f2 refactor(wordpress): decouple core from the in-tree extension
Bridge, blueprint registration, app/attach flows and builtin job
handlers no longer assume the WP builtin is present; WP install paths
gitignored like other extracted extensions. WP absent = feature absent
gracefully (plan 52 phase 5, D4).
2026-08-05 02:37:48 -04:00
Juan Denis 0f8d179692 test: ratchet 3197 -> 3213 (wp hook inversion matrix) 2026-08-05 01:18:42 -04:00
Juan Denis 964f8eee7d docs: hook registration seams + core data seam in EXTENSIONS.md 2026-08-05 01:18:33 -04:00
Juan Denis d61985e73b test: WP hook inversion matrix (present x absent)
16 tests covering boot registration, idempotency, backup provider
resolve/validate/missing-state, event catalog present/absent, template
provider dispatch, monitor binding gate, health-sweep no-op, analytics
ext-to-ext guards. Existing suites minimally updated for the provider
interfaces (171 WP/monitor + 316 backup/events/templates green).
2026-08-05 01:18:32 -04:00
Juan Denis 060e600ffa feat(monitors): gate wordpress_site_id binding on WP presence
Create/update validation fails loudly naming the missing extension
instead of orphaning monitors; health sweep no-ops with zero WP sites
(plan 52 phase 3 task 17). StatusComponent.wordpress_site_id stays core
per D1.
2026-08-05 01:18:23 -04:00
Juan Denis e0888ecbba feat(templates): provider hook for extension template kinds
The wordpress template kind + wordpress-external-db preflight move behind
a template-provider hook the extension supplies; the backend filters the
catalog so the WP card simply does not appear when WP is absent — no
frontend change needed (plan 52 phase 3 task 16).
2026-08-05 01:18:23 -04:00
Juan Denis b153f68c12 feat(events): registered event-type catalog seam
Extensions register event types at load; wordpress.* types now come from
the WP extension instead of a hardcoded core catalog (plan 52 phase 3
task 15). emit_wp stays core as a dumb emitter helper.
2026-08-05 01:18:22 -04:00
Juan Denis 8d106aa5a0 feat(backups): dynamic target-provider registry
VALID_TARGET_TYPES is now provider-driven; the wordpress_site branch
moves behind a provider the WP extension registers. ProtectionPanel /
RestoreDrawer read available types from the API; policies whose provider
is absent surface a clear missing-provider state instead of crashing
(plan 52 phase 3 task 13).
2026-08-05 01:18:11 -04:00
Juan Denis 57d82c8c83 feat(extensions): boot-time hook registration seam
Extensions can register providers into core engines at load (backup
targets, event types, template kinds) via a core_hooks module; idempotent,
process-lifetime like blueprint registration. WP extension supplies its
entries through builtin-extensions/serverkit-wordpress/backend/core_hooks.py
(plan 52 phase 3, D4).
2026-08-05 01:18:02 -04:00
Juan Denis ef88b765d7 docs: extraction audit reflects phase-4 frontend relocation 2026-08-05 00:48:21 -04:00
Juan Denis 6d53935130 refactor(wordpress): drop residual core nav/title wiring
App.jsx /wordpress* title fallbacks removed (manifest page_titles cover
the routes); sidebar preset hiddenItems no longer hardcode the wordpress
slug — nav sources from extension contributions.
2026-08-05 00:48:20 -04:00
Juan Denis 5d8160dc73 refactor(wordpress): relocate frontend into the extension
5 WordPress* pages + components/wordpress (40 files) + 3 _wordpress*.scss
partials move from core into builtin-extensions/serverkit-wordpress/
frontend/ (synced to frontend/src/plugins via the baked-glob pattern).
200 imports rewritten to serverkit-sdk; remaining @/ imports only for
genuinely host-internal modules. main.scss drops the WP partials — the
extension bundle imports its own styles. npm build + lint green.
2026-08-05 00:48:12 -04:00
Juan Denis c17975ea7a feat(sdk): export layout/feedback/form primitives for extension UIs
TabGroupLayout, Modal, ConfirmDialog, Spinner/LoadingState, EmptyState,
Skeleton(SkeletonBoundary), and the ui/* form kit (Button, Input, Select,
Switch, ...) as generic re-exports so an extension page can mirror core
page chrome without deep imports. Proven out by the WordPress frontend
relocation (plan 52 phase 4).
2026-08-05 00:48:01 -04:00
Juan Denis 07fcc82778 feat(marketplace): games category with gamepad icon
Unknown categories already derived/filtered gracefully; this adds
games to the canonical order and gives it a lucide Gamepad2 icon
ahead of serverkit-minecraft landing in the registry.
2026-08-05 00:25:39 -04:00
Juan Denis 73de373b80 test: move minecraft suites to the extension repo, adjust ratchet
The four minecraft test files now live in serverkit-minecraft/tests/
(panel-hosted via SERVERKIT_MINECRAFT_DIR loader). Ratchet floor
3280 -> 3197 (-83 minecraft tests; collected 3222, floor intact).
2026-08-05 00:09:19 -04:00
Juan Denis e280a446c1 refactor(extensions): extract serverkit-minecraft to its own repo
The Minecraft game-server extension now lives at
github.com/jhd3197/serverkit-minecraft as a standalone runtime-ESM
extension (analytics/gpu repo pattern). It is installed from the
registry like any first-party extension, no longer bundled in-tree.
2026-08-05 00:09:11 -04:00
Juan Denis a4329124dd chore(extensions): author signing tool + signing spec docs
scripts/sign-extension.mjs signs a bundle with an ed25519 author key;
EXTENSIONS.md documents the format, key model, and verdict behaviors.
Generated private keys live in gitignored scripts/keys/.
2026-08-04 23:34:34 -04:00
Juan Denis 0299d334af feat(extensions): install consent UX with signature badges
Consent card shows permissions, version gate, and signature state
(Signed/Unsigned/Unknown signer/Invalid) with honest copy; 'Install
anyway' destructive path for acknowledged risk; invalid = disabled.
2026-08-04 23:34:26 -04:00
Juan Denis 31697cda9e feat(extensions): enforce signature policy in install flow
Invalid signature hard-blocks (400); untrusted key requires explicit
acknowledge (409 backstop); registry index carries signature/publisher
fields; install pinned to previewed sha256 with re-verified signature.
2026-08-04 23:34:15 -04:00
Juan Denis af64f3628d feat(extensions): ed25519 signing service + publisher key registry
Signature verification over extension bundles with pinned publisher
public keys; verdicts: verified/unsigned/unknown_signer/invalid.
24 tests: round-trip, tamper, malformed, untrusted key, forge attempts.
2026-08-04 23:34:02 -04:00
Juan Denis 347a7f319c Merge pull request #89 from jhd3197/dev
Close IDOR and authorization gaps across the backend API
v1.7.81
2026-08-04 10:16:16 -04:00
github-actions[bot] 20c25938c8 chore: bump version to 1.7.81 [skip ci] 2026-08-04 13:11:21 +00:00
Juan Denis 00c66556b0 Bump cryptography to 50.0.0
Update the backend dependency pin from `cryptography==48.0.1` to `cryptography==50.0.0` in `requirements.txt` to keep encryption tooling current.
2026-08-04 09:10:56 -04:00
github-actions[bot] 459d46d6f6 chore: bump version to 1.7.80 [skip ci] 2026-08-04 13:01:12 +00:00
Juan Denis 939af8bc76 Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-08-04 09:00:24 -04:00
Juan Denis d961bd23f0 fix(api): close IDOR/authz gaps across deployment jobs, vaults, queues, docker, databases
Proactive hardening from an internal audit of the same broken-authorization
class as GHSA-6w78-q5vm-rfmh (authentication checked, app/workspace-level
authorization skipped):

- deployment_jobs: job detail/logs/retry resolve the job and gate on
  can_access_app / can_operate_app (app-less jobs: requester or admin);
  global job listing is admin-only
- secrets_webhooks: every vault/secret/webhook-endpoint/delivery by-id
  route resolves to its workspace and 404-seals non-members; secret
  reveal and signing-secret regeneration require workspace owner/admin;
  dead local admin_required placeholder removed
- shared_resources: variable-group CRUD and attach/detach gate on the
  resolved scope (workspace role / can_edit_app / can_operate_app),
  closing deploy-time env injection into foreign apps
- queue_bus: message receive/complete/fail/list on system-owned groups
  are admin-only; user-owned groups restricted to their owner
- docker: raw container inspect (exposes env vars) and container logs
  are admin-only, matching Decision 7; per-app logs stay app-gated
- databases: raw SQL query endpoints, host-level metadata reads, and
  process lists are admin-only; per-app managed database flows unchanged

Adds 4 persona-matrix regression suites (74 tests) and bumps the
test-count ratchet.
2026-08-04 08:53:27 -04:00
Juan DenisandTyler Boykin 783e195304 fix(git): enforce app-level authorization on deployment read endpoints
GHSA-6w78-q5vm-rfmh: four git deployment/webhook read endpoints checked
authentication but skipped app-level authorization, letting any active
user (even a foreign viewer) read cross-tenant deployment history and
logs that can contain secrets from pre/post-deploy scripts.

- git.deployments/<id>: resolve deployment -> app, 404/403 via
  app_access_tier before returning any log bytes
- git.deployments/webhook/<id>: gate on _webhook_visible_to (app-linked
  webhooks follow app visibility; unlinked stay panel-wide, plan 29 #11)
- deploy.history & deploy.webhook-logs: app_id queries require
  app_access_tier; global (no app_id) queries are panel-admin only

Adds backend/tests/test_git_deployment_authz.py (9 persona-matrix
regression tests) and bumps the test-count ratchet.

Co-authored-by: Tyler Boykin <25166954+CaptBoykin@users.noreply.github.com>
2026-08-03 23:44:56 -04:00
Juan Denis 0110149703 Merge pull request #88 from jhd3197/dev
Add demo video badge to README variants
v1.7.79
2026-08-03 00:19:17 -04:00
github-actions[bot] 09eed1c5e7 chore: bump version to 1.7.79 [skip ci] 2026-08-03 04:17:36 +00:00
Juan Denis 9b531e14b3 Add demo video badge to README variants
Adds a new YouTube “Watch the Demo” badge/link near the top badges in the main README and the Spanish, Portuguese, and Simplified Chinese README translations so users can quickly find the product walkthrough.
2026-08-03 00:17:29 -04:00
Juan Denis 0877d38353 Merge pull request #87 from jhd3197/dev
Install profiles, honest capacity advice, and two security fixes
v1.7.78
2026-08-02 19:42:03 -04:00
github-actions[bot] ee18e2e884 chore: bump version to 1.7.78 [skip ci] 2026-08-02 22:58:13 +00:00
Juan Denis b6e3fea493 Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-08-02 18:58:12 -04:00
Juan Denis 048a560f8c fix(security): correct PROTECTED_ROOTS path math; tighten root matching
Copilot review on the GHSA-rm3m-9mvw-68fh patch caught two issues:

- _BACKEND_DIR/_INSTALL_DIR were one level too shallow (backend/app and
  backend/ instead of backend/ and the install root), which left
  <install>/.env and frontend/dist reachable on the deployed layout —
  the exact PoC path from the advisory. _BACKEND_DIR stays in
  PROTECTED_ROOTS so flat layouts (code at /app) are covered too.
- The ALLOWED_ROOTS check used a bare startswith, so e.g. /optfoo
  matched the /opt root. Both checks now require an exact match or a
  path-boundary prefix.

New tests pin the level math (the existing cases computed the expected
layout independently and passed on Windows for the wrong reason) and
simulate the deployed layout with the install dir inside an allowed root.
2026-08-02 18:56:33 -04:00
github-actions[bot] b8a031e733 chore: bump version to 1.7.77 [skip ci] 2026-08-02 22:36:24 +00:00
Juan Denis 0b0bfcce70 feat(security): daily GHSA feed check with admin notifications
New builtin job security-feed (daily) pulls the normalized advisory feed
from serverkit.ai/api/security-feed.json (a cached proxy of the repo's
published GitHub Security Advisories) and:

- notifies admins (security.alert, critical) when the running panel
  version falls inside an advisory's affected range, once per advisory;
- fires a one-time post-fix reminder after an upgrade crosses a fix
  boundary when the advisory declares a "## Post-upgrade actions" section
  (e.g. rotate JWT_SECRET_KEY after GHSA-rm3m-9mvw-68fh).

Dedupe keys, the last-good feed copy, and the previously-seen version live
in SystemSettings, so restarts never re-notify and outbound failures serve
the cached feed. Opt out via the security_feed.enabled setting. Privacy
page on serverkit.ai updated to disclose the daily call.
2026-08-02 18:35:25 -04:00